From 7aa494fa939bd975e260fc501c9e402be5b2f436 Mon Sep 17 00:00:00 2001 From: Vitali Malinouski Date: Thu, 24 Apr 2014 09:15:27 -0700 Subject: [PATCH] Converted from TABs -> 4 Spaces --- .gitignore | 6 +- Gruntfile.js | 438 +- build.xml | 478 +- demos/code-mirror.js | 18 +- demos/data/content2.html | 16 +- demos/data/form.html | 68 +- demos/data/list.json | 24 +- demos/data/list2.json | 80 +- demos/data/popup1.html | 40 +- demos/data/popup2.html | 20 +- demos/data/popup3.html | 108 +- demos/examples/combo-1.html | 164 +- demos/examples/combo-2.html | 176 +- demos/examples/combo-3.html | 210 +- demos/examples/combo-4.html | 86 +- demos/examples/combo-5.html | 80 +- demos/examples/combo-6.html | 100 +- demos/examples/combo-7.html | 214 +- demos/examples/combo-8.html | 164 +- demos/examples/combo-9.html | 56 +- demos/examples/editor-1.html | 32 +- demos/examples/editor-2.html | 30 +- demos/examples/editor-3.html | 78 +- demos/examples/editor-4.html | 42 +- demos/examples/forms-1.html | 84 +- demos/examples/forms-2.html | 114 +- demos/examples/forms-3.html | 202 +- demos/examples/forms-4.html | 176 +- demos/examples/forms-5.html | 182 +- demos/examples/forms-6.html | 120 +- demos/examples/forms-7.html | 78 +- demos/examples/forms-8.html | 144 +- demos/examples/forms-9.html | 88 +- demos/examples/grid-1.html | 58 +- demos/examples/grid-10.html | 72 +- demos/examples/grid-11.html | 88 +- demos/examples/grid-12.html | 62 +- demos/examples/grid-13.html | 104 +- demos/examples/grid-14.html | 108 +- demos/examples/grid-15.html | 96 +- demos/examples/grid-16.html | 98 +- demos/examples/grid-17.html | 126 +- demos/examples/grid-18.html | 100 +- demos/examples/grid-19.html | 120 +- demos/examples/grid-2.html | 112 +- demos/examples/grid-20.html | 54 +- demos/examples/grid-21.html | 190 +- demos/examples/grid-22.html | 76 +- demos/examples/grid-23.html | 80 +- demos/examples/grid-24.html | 86 +- demos/examples/grid-25.html | 86 +- demos/examples/grid-3.html | 108 +- demos/examples/grid-4.html | 102 +- demos/examples/grid-5.html | 60 +- demos/examples/grid-6.html | 66 +- demos/examples/grid-7.html | 98 +- demos/examples/grid-8.html | 54 +- demos/examples/grid-9.html | 128 +- demos/examples/layout-1.html | 36 +- demos/examples/layout-10.html | 44 +- demos/examples/layout-2.html | 38 +- demos/examples/layout-3.html | 40 +- demos/examples/layout-4.html | 36 +- demos/examples/layout-5.html | 32 +- demos/examples/layout-6.html | 52 +- demos/examples/layout-7.html | 66 +- demos/examples/layout-8.html | 72 +- demos/examples/layout-9.html | 88 +- demos/examples/listview-1.html | 42 +- demos/examples/listview-2.html | 42 +- demos/examples/listview-3.html | 42 +- demos/examples/listview-4.html | 62 +- demos/examples/listview-5.html | 54 +- demos/examples/popup-1.html | 24 +- demos/examples/popup-2.html | 54 +- demos/examples/popup-3.html | 32 +- demos/examples/popup-4.html | 84 +- demos/examples/popup-5.html | 14 +- demos/examples/popup-6.html | 14 +- demos/examples/popup-7.html | 42 +- demos/examples/popup-8.html | 12 +- demos/examples/sidebar-1.html | 58 +- demos/examples/sidebar-2.html | 66 +- demos/examples/sidebar-3.html | 42 +- demos/examples/sidebar-4.html | 40 +- demos/examples/sidebar-5.html | 40 +- demos/examples/sidebar-6.html | 42 +- demos/examples/sidebar-7.html | 56 +- demos/examples/sidebar-8.html | 62 +- demos/examples/tabs-1.html | 38 +- demos/examples/tabs-2.html | 32 +- demos/examples/tabs-3.html | 40 +- demos/examples/tabs-4.html | 62 +- demos/examples/tabs-5.html | 32 +- demos/examples/tabs-6.html | 34 +- demos/examples/toolbar-1.html | 42 +- demos/examples/toolbar-2.html | 96 +- demos/examples/toolbar-3.html | 68 +- demos/examples/toolbar-4.html | 40 +- demos/examples/toolbar-5.html | 40 +- demos/examples/utils-1.html | 44 +- demos/examples/utils-2.html | 16 +- demos/examples/utils-3.html | 94 +- demos/examples/utils-4.html | 20 +- demos/index.css | 126 +- demos/index.html | 20 +- demos/index.js | 638 +- dist/kickstart.js | 634 +- dist/w2ui-dark.css | 12 +- dist/w2ui-fields.css | 12 +- dist/w2ui-fields.js | 7380 ++--- dist/w2ui-fields.min.js | 6 +- dist/w2ui.css | 12 +- dist/w2ui.js | 27470 ++++++++-------- dist/w2ui.min.js | 20 +- docs/code-mirror.js | 18 +- docs/details/common.box.html | 22 +- docs/details/common.destroy.html | 14 +- docs/details/common.handlers.html | 18 +- docs/details/common.name.html | 24 +- docs/details/common.off.html | 56 +- docs/details/common.on.html | 86 +- docs/details/common.onDestroy.html | 20 +- docs/details/common.onRefresh.html | 20 +- docs/details/common.onRender.html | 20 +- docs/details/common.onResize.html | 20 +- docs/details/common.refresh.html | 28 +- docs/details/common.render.html | 38 +- docs/details/common.resize.html | 14 +- docs/details/common.style.html | 14 +- docs/details/common.trigger.html | 14 +- docs/details/w2form.action.html | 44 +- docs/details/w2form.actions.html | 46 +- docs/details/w2form.clear.html | 46 +- docs/details/w2form.error.html | 28 +- docs/details/w2form.fields.html | 80 +- docs/details/w2form.focus.html | 60 +- docs/details/w2form.formHTML.html | 80 +- docs/details/w2form.formURL.html | 44 +- docs/details/w2form.generateHTML.html | 44 +- docs/details/w2form.get.html | 42 +- docs/details/w2form.goto.html | 98 +- docs/details/w2form.header.html | 36 +- docs/details/w2form.isGenerated.html | 30 +- docs/details/w2form.last.html | 4 +- docs/details/w2form.lock.html | 46 +- docs/details/w2form.msgNotJSON.html | 36 +- docs/details/w2form.msgRefresh.html | 36 +- docs/details/w2form.msgSaving.html | 36 +- docs/details/w2form.onAction.html | 30 +- docs/details/w2form.onChange.html | 30 +- docs/details/w2form.onError.html | 30 +- docs/details/w2form.onLoad.html | 30 +- docs/details/w2form.onRequest.html | 30 +- docs/details/w2form.onSave.html | 30 +- docs/details/w2form.onSubmit.html | 30 +- docs/details/w2form.onToolbar.html | 30 +- docs/details/w2form.onValidate.html | 30 +- docs/details/w2form.original.html | 2 +- docs/details/w2form.page.html | 86 +- docs/details/w2form.postData.html | 44 +- docs/details/w2form.recid.html | 46 +- docs/details/w2form.record.html | 42 +- docs/details/w2form.reload.html | 42 +- docs/details/w2form.request.html | 48 +- docs/details/w2form.save.html | 66 +- docs/details/w2form.set.html | 42 +- docs/details/w2form.submit.html | 22 +- docs/details/w2form.tabs.html | 100 +- docs/details/w2form.toolbar.html | 58 +- docs/details/w2form.unlock.html | 26 +- docs/details/w2form.url.html | 122 +- docs/details/w2form.validate.html | 40 +- docs/details/w2grid.add.html | 44 +- docs/details/w2grid.addColumn.html | 44 +- docs/details/w2grid.addRange.html | 66 +- docs/details/w2grid.addSearch.html | 50 +- docs/details/w2grid.autoLoad.html | 22 +- docs/details/w2grid.buffered.html | 8 +- docs/details/w2grid.buttons.html | 120 +- docs/details/w2grid.clear.html | 48 +- docs/details/w2grid.click.html | 56 +- docs/details/w2grid.collapse.html | 56 +- docs/details/w2grid.columnClick.html | 56 +- docs/details/w2grid.columnGroups.html | 40 +- docs/details/w2grid.columnOnOff.html | 80 +- docs/details/w2grid.columns.html | 116 +- docs/details/w2grid.copy.html | 36 +- docs/details/w2grid.dblClick.html | 56 +- docs/details/w2grid.delete.html | 48 +- docs/details/w2grid.editField.html | 72 +- docs/details/w2grid.error.html | 48 +- docs/details/w2grid.expand.html | 56 +- docs/details/w2grid.find.html | 56 +- docs/details/w2grid.fixedBody.html | 22 +- docs/details/w2grid.get.html | 56 +- docs/details/w2grid.getCellHTML.html | 64 +- docs/details/w2grid.getChanges.html | 36 +- docs/details/w2grid.getColumn.html | 56 +- docs/details/w2grid.getColumnsHTML.html | 36 +- docs/details/w2grid.getFooterHTML.html | 36 +- docs/details/w2grid.getRangeData.html | 64 +- docs/details/w2grid.getRecordHTML.html | 64 +- docs/details/w2grid.getRecordsHTML.html | 36 +- docs/details/w2grid.getSearch.html | 66 +- docs/details/w2grid.getSearchData.html | 58 +- docs/details/w2grid.getSearchesHTML.html | 46 +- docs/details/w2grid.getSelection.html | 36 +- docs/details/w2grid.getSummaryHTML.html | 36 +- docs/details/w2grid.header.html | 28 +- docs/details/w2grid.hideColumn.html | 38 +- docs/details/w2grid.hideSearch.html | 48 +- docs/details/w2grid.initColumnOnOff.html | 20 +- docs/details/w2grid.initResize.html | 2 +- docs/details/w2grid.initSearches.html | 2 +- docs/details/w2grid.initToolbar.html | 2 +- docs/details/w2grid.keyboard.html | 36 +- docs/details/w2grid.keydown.html | 38 +- docs/details/w2grid.last.html | 36 +- docs/details/w2grid.limit.html | 22 +- docs/details/w2grid.load.html | 40 +- docs/details/w2grid.localSearch.html | 48 +- docs/details/w2grid.localSort.html | 48 +- docs/details/w2grid.lock.html | 54 +- docs/details/w2grid.markSearchResults.html | 22 +- docs/details/w2grid.mergeChanges.html | 34 +- docs/details/w2grid.msgDelete.html | 22 +- docs/details/w2grid.msgNotJSON.html | 22 +- docs/details/w2grid.msgRefresh.html | 22 +- docs/details/w2grid.multiSearch.html | 24 +- docs/details/w2grid.multiSelect.html | 24 +- docs/details/w2grid.multiSort.html | 24 +- docs/details/w2grid.offset.html | 2 +- docs/details/w2grid.onAdd.html | 50 +- docs/details/w2grid.onChange.html | 42 +- docs/details/w2grid.onClick.html | 52 +- docs/details/w2grid.onCollapse.html | 48 +- docs/details/w2grid.onColumnClick.html | 42 +- docs/details/w2grid.onColumnOnOff.html | 42 +- docs/details/w2grid.onColumnResize.html | 42 +- docs/details/w2grid.onCopy.html | 44 +- docs/details/w2grid.onDblClick.html | 42 +- docs/details/w2grid.onDelete.html | 48 +- docs/details/w2grid.onDeleted.html | 28 +- docs/details/w2grid.onEdit.html | 50 +- docs/details/w2grid.onEditField.html | 42 +- docs/details/w2grid.onError.html | 42 +- docs/details/w2grid.onExpand.html | 48 +- docs/details/w2grid.onKeydown.html | 42 +- docs/details/w2grid.onLoad.html | 28 +- docs/details/w2grid.onPaste.html | 46 +- docs/details/w2grid.onReload.html | 32 +- docs/details/w2grid.onRequest.html | 32 +- docs/details/w2grid.onSave.html | 28 +- docs/details/w2grid.onSaved.html | 28 +- docs/details/w2grid.onSearch.html | 48 +- docs/details/w2grid.onSelect.html | 42 +- docs/details/w2grid.onSelectionExtend.html | 44 +- docs/details/w2grid.onSort.html | 42 +- docs/details/w2grid.onToolbar.html | 54 +- docs/details/w2grid.onUnselect.html | 42 +- docs/details/w2grid.parseField.html | 44 +- docs/details/w2grid.paste.html | 48 +- docs/details/w2grid.postData.html | 28 +- docs/details/w2grid.ranges.html | 10 +- docs/details/w2grid.recordHeight.html | 36 +- docs/details/w2grid.records.html | 56 +- docs/details/w2grid.refreshRanges.html | 34 +- docs/details/w2grid.reload.html | 34 +- docs/details/w2grid.remove.html | 48 +- docs/details/w2grid.removeColumn.html | 48 +- docs/details/w2grid.removeRange.html | 46 +- docs/details/w2grid.removeSearch.html | 48 +- docs/details/w2grid.request.html | 78 +- docs/details/w2grid.requestComplete.html | 30 +- docs/details/w2grid.reset.html | 62 +- docs/details/w2grid.resizeBoxes.html | 2 +- docs/details/w2grid.resizeRecords.html | 2 +- docs/details/w2grid.save.html | 36 +- docs/details/w2grid.scroll.html | 2 +- docs/details/w2grid.scrollIntoView.html | 50 +- docs/details/w2grid.search.html | 82 +- docs/details/w2grid.searchClose.html | 36 +- docs/details/w2grid.searchData.html | 42 +- docs/details/w2grid.searchOpen.html | 36 +- docs/details/w2grid.searchReset.html | 48 +- docs/details/w2grid.searchShowFields.html | 36 +- docs/details/w2grid.searches.html | 62 +- docs/details/w2grid.select.html | 48 +- docs/details/w2grid.selectAll.html | 36 +- docs/details/w2grid.selectNone.html | 36 +- docs/details/w2grid.selectType.html | 40 +- docs/details/w2grid.set.html | 64 +- docs/details/w2grid.show.html | 48 +- docs/details/w2grid.showColumn.html | 38 +- docs/details/w2grid.showSearch.html | 48 +- docs/details/w2grid.skip.html | 32 +- docs/details/w2grid.sort.html | 68 +- docs/details/w2grid.sortData.html | 42 +- docs/details/w2grid.status.html | 38 +- docs/details/w2grid.summary.html | 80 +- docs/details/w2grid.toggle.html | 56 +- docs/details/w2grid.toggleColumn.html | 48 +- docs/details/w2grid.toggleSearch.html | 58 +- docs/details/w2grid.toolbar.html | 62 +- docs/details/w2grid.toolbarAdd.html | 36 +- docs/details/w2grid.toolbarDelete.html | 48 +- docs/details/w2grid.total.html | 2 +- docs/details/w2grid.unlock.html | 36 +- docs/details/w2grid.unselect.html | 48 +- docs/details/w2grid.url.html | 50 +- docs/details/w2layout.content.html | 78 +- docs/details/w2layout.el.html | 26 +- docs/details/w2layout.get.html | 64 +- docs/details/w2layout.hide.html | 48 +- docs/details/w2layout.hideTabs.html | 64 +- docs/details/w2layout.hideToolbar.html | 62 +- docs/details/w2layout.html.html | 30 +- docs/details/w2layout.load.html | 84 +- docs/details/w2layout.lock.html | 34 +- docs/details/w2layout.onHide.html | 20 +- docs/details/w2layout.onResizing.html | 20 +- docs/details/w2layout.onShow.html | 20 +- docs/details/w2layout.padding.html | 14 +- docs/details/w2layout.panels.html | 90 +- docs/details/w2layout.resizer.html | 14 +- docs/details/w2layout.set.html | 72 +- docs/details/w2layout.show.html | 48 +- docs/details/w2layout.showTabs.html | 64 +- docs/details/w2layout.showToolbar.html | 62 +- docs/details/w2layout.sizeTo.html | 48 +- docs/details/w2layout.toggle.html | 34 +- docs/details/w2layout.toggleTabs.html | 64 +- docs/details/w2layout.toggleToolbar.html | 62 +- docs/details/w2layout.unlock.html | 26 +- docs/details/w2listview.add.html | 34 +- docs/details/w2listview.click.html | 34 +- docs/details/w2listview.contextMenu.html | 34 +- docs/details/w2listview.curFocused.html | 14 +- docs/details/w2listview.dblClick.html | 34 +- docs/details/w2listview.extraCols.html | 36 +- docs/details/w2listview.get.html | 34 +- docs/details/w2listview.getFocused.html | 26 +- docs/details/w2listview.insert.html | 42 +- docs/details/w2listview.items.html | 32 +- docs/details/w2listview.keyboard.html | 24 +- docs/details/w2listview.keydown.html | 32 +- docs/details/w2listview.menu.html | 38 +- docs/details/w2listview.menuClick.html | 52 +- docs/details/w2listview.multiselect.html | 16 +- docs/details/w2listview.onClick.html | 22 +- docs/details/w2listview.onContextMenu.html | 22 +- docs/details/w2listview.onDblClick.html | 22 +- docs/details/w2listview.onKeydown.html | 22 +- docs/details/w2listview.onMenuClick.html | 22 +- docs/details/w2listview.remove.html | 26 +- docs/details/w2listview.scrollIntoView.html | 26 +- docs/details/w2listview.selStart.html | 14 +- docs/details/w2listview.select.html | 34 +- docs/details/w2listview.set.html | 34 +- docs/details/w2listview.unselect.html | 26 +- docs/details/w2listview.userSelect.html | 40 +- docs/details/w2listview.viewType.html | 26 +- docs/details/w2popup.clear.html | 2 +- docs/details/w2popup.close.html | 2 +- docs/details/w2popup.defaults.html | 32 +- docs/details/w2popup.get.html | 2 +- docs/details/w2popup.keydown.html | 14 +- docs/details/w2popup.load.html | 32 +- docs/details/w2popup.lock.html | 22 +- docs/details/w2popup.lockScreen.html | 30 +- docs/details/w2popup.max.html | 2 +- docs/details/w2popup.message.html | 12 +- docs/details/w2popup.min.html | 2 +- docs/details/w2popup.onClose.html | 14 +- docs/details/w2popup.onKeydown.html | 14 +- docs/details/w2popup.onMax.html | 14 +- docs/details/w2popup.onMin.html | 14 +- docs/details/w2popup.onOpen.html | 14 +- docs/details/w2popup.open.html | 78 +- docs/details/w2popup.reset.html | 2 +- docs/details/w2popup.resize.html | 30 +- docs/details/w2popup.set.html | 2 +- docs/details/w2popup.toggle.html | 2 +- docs/details/w2popup.unlock.html | 2 +- docs/details/w2popup.unlockScreen.html | 2 +- docs/details/w2sidebar.add.html | 44 +- docs/details/w2sidebar.bottomHTML.html | 16 +- docs/details/w2sidebar.click.html | 42 +- docs/details/w2sidebar.collapse.html | 34 +- docs/details/w2sidebar.collapseAll.html | 34 +- docs/details/w2sidebar.contextMenu.html | 42 +- docs/details/w2sidebar.dblClick.html | 42 +- docs/details/w2sidebar.disable.html | 28 +- docs/details/w2sidebar.enable.html | 28 +- docs/details/w2sidebar.expand.html | 34 +- docs/details/w2sidebar.expandAll.html | 34 +- docs/details/w2sidebar.expandParents.html | 34 +- docs/details/w2sidebar.get.html | 44 +- docs/details/w2sidebar.hide.html | 28 +- docs/details/w2sidebar.icon.html | 16 +- docs/details/w2sidebar.img.html | 38 +- docs/details/w2sidebar.insert.html | 52 +- docs/details/w2sidebar.keyboard.html | 30 +- docs/details/w2sidebar.keydown.html | 34 +- docs/details/w2sidebar.lock.html | 36 +- docs/details/w2sidebar.menu.html | 44 +- docs/details/w2sidebar.menuClick.html | 60 +- docs/details/w2sidebar.nodes.html | 60 +- docs/details/w2sidebar.onClick.html | 22 +- docs/details/w2sidebar.onCollapse.html | 22 +- docs/details/w2sidebar.onContextMenu.html | 22 +- docs/details/w2sidebar.onDblClick.html | 22 +- docs/details/w2sidebar.onExpand.html | 22 +- docs/details/w2sidebar.onKeydown.html | 22 +- docs/details/w2sidebar.onMenuClick.html | 22 +- docs/details/w2sidebar.parent.html | 2 +- docs/details/w2sidebar.remove.html | 26 +- docs/details/w2sidebar.scrollIntoView.html | 26 +- docs/details/w2sidebar.select.html | 28 +- docs/details/w2sidebar.selected.html | 16 +- docs/details/w2sidebar.set.html | 44 +- docs/details/w2sidebar.show.html | 28 +- docs/details/w2sidebar.sidebar.html | 2 +- docs/details/w2sidebar.toggle.html | 34 +- docs/details/w2sidebar.topHTML.html | 16 +- docs/details/w2sidebar.unlock.html | 18 +- docs/details/w2sidebar.unselect.html | 28 +- docs/details/w2tabs.active.html | 18 +- docs/details/w2tabs.add.html | 38 +- docs/details/w2tabs.animateClose.html | 40 +- docs/details/w2tabs.animateInsert.html | 40 +- docs/details/w2tabs.click.html | 38 +- docs/details/w2tabs.disable.html | 30 +- docs/details/w2tabs.enable.html | 30 +- docs/details/w2tabs.get.html | 38 +- docs/details/w2tabs.hide.html | 30 +- docs/details/w2tabs.insert.html | 46 +- docs/details/w2tabs.onClick.html | 26 +- docs/details/w2tabs.onClose.html | 26 +- docs/details/w2tabs.remove.html | 30 +- docs/details/w2tabs.right.html | 18 +- docs/details/w2tabs.select.html | 30 +- docs/details/w2tabs.set.html | 38 +- docs/details/w2tabs.show.html | 30 +- docs/details/w2tabs.tabs.html | 34 +- docs/details/w2toolbar.add.html | 34 +- docs/details/w2toolbar.check.html | 26 +- docs/details/w2toolbar.click.html | 34 +- docs/details/w2toolbar.disable.html | 26 +- docs/details/w2toolbar.enable.html | 26 +- docs/details/w2toolbar.get.html | 36 +- docs/details/w2toolbar.getItemHTML.html | 28 +- docs/details/w2toolbar.hide.html | 26 +- docs/details/w2toolbar.insert.html | 42 +- docs/details/w2toolbar.items.html | 116 +- docs/details/w2toolbar.menuClick.html | 44 +- docs/details/w2toolbar.onClick.html | 22 +- docs/details/w2toolbar.remove.html | 26 +- docs/details/w2toolbar.right.html | 16 +- docs/details/w2toolbar.set.html | 34 +- docs/details/w2toolbar.show.html | 26 +- docs/details/w2toolbar.uncheck.html | 26 +- docs/details/w2utils.age.html | 14 +- docs/details/w2utils.base64decode.html | 14 +- docs/details/w2utils.base64encode.html | 14 +- docs/details/w2utils.date.html | 14 +- docs/details/w2utils.encodeTags.html | 14 +- docs/details/w2utils.escapeId.html | 14 +- docs/details/w2utils.event.html | 2 +- docs/details/w2utils.formatDate.html | 22 +- docs/details/w2utils.formatDateTime.html | 22 +- docs/details/w2utils.formatNumber.html | 14 +- docs/details/w2utils.formatTime.html | 22 +- docs/details/w2utils.getSize.html | 38 +- docs/details/w2utils.isAlphaNumeric.html | 14 +- docs/details/w2utils.isDate.html | 22 +- docs/details/w2utils.isEmail.html | 14 +- docs/details/w2utils.isFloat.html | 14 +- docs/details/w2utils.isHex.html | 14 +- docs/details/w2utils.isInt.html | 14 +- docs/details/w2utils.isMoney.html | 14 +- docs/details/w2utils.isTime.html | 14 +- docs/details/w2utils.keyboard.html | 2 +- docs/details/w2utils.lang.html | 14 +- docs/details/w2utils.locale.html | 14 +- docs/details/w2utils.lock.html | 30 +- docs/details/w2utils.scrollBarSize.html | 2 +- docs/details/w2utils.settings.html | 28 +- docs/details/w2utils.size.html | 14 +- docs/details/w2utils.stripTags.html | 14 +- docs/details/w2utils.transition.html | 58 +- docs/details/w2utils.unlock.html | 14 +- docs/generate.js | 112 +- docs/index.css | 142 +- docs/index.html | 20 +- docs/index.js | 508 +- docs/overview/fields.html | 232 +- docs/overview/form.html | 106 +- docs/overview/grid.html | 118 +- docs/overview/layout.html | 16 +- docs/overview/listview.html | 18 +- docs/overview/popup-overlays.html | 26 +- docs/overview/popup.html | 50 +- docs/overview/sidebar.html | 102 +- docs/overview/tabs.html | 28 +- docs/overview/toolbar.html | 38 +- docs/overview/utils-events.html | 32 +- docs/overview/utils-plugins.html | 26 +- docs/overview/utils.html | 6 +- docs/summary.css | 112 +- docs/summary/common-events.php | 16 +- docs/summary/common-methods.php | 28 +- docs/summary/common-props.php | 16 +- docs/summary/w2form-events.php | 36 +- docs/summary/w2form-methods.php | 56 +- docs/summary/w2form-props.php | 76 +- docs/summary/w2grid-events.php | 112 +- docs/summary/w2grid-methods.php | 308 +- docs/summary/w2grid-props.php | 132 +- docs/summary/w2layout-events.php | 12 +- docs/summary/w2layout-methods.php | 72 +- docs/summary/w2layout-props.php | 12 +- docs/summary/w2listview-events.php | 20 +- docs/summary/w2listview-methods.php | 60 +- docs/summary/w2listview-props.php | 32 +- docs/summary/w2popup-events.php | 20 +- docs/summary/w2popup-methods.php | 68 +- docs/summary/w2popup-props.php | 4 +- docs/summary/w2sidebar-events.php | 28 +- docs/summary/w2sidebar-methods.php | 100 +- docs/summary/w2sidebar-props.php | 40 +- docs/summary/w2tabs-events.php | 8 +- docs/summary/w2tabs-methods.php | 52 +- docs/summary/w2tabs-props.php | 12 +- docs/summary/w2toolbar-events.php | 4 +- docs/summary/w2toolbar-methods.php | 56 +- docs/summary/w2toolbar-props.php | 8 +- docs/summary/w2utils-methods.php | 108 +- docs/summary/w2utils-props.php | 12 +- libs/CodeMirror/mode/apl/index.html | 2 +- libs/CodeMirror/mode/asterisk/index.html | 58 +- libs/CodeMirror/mode/go/index.html | 36 +- libs/CodeMirror/mode/haxe/index.html | 106 +- libs/CodeMirror/mode/htmlembedded/index.html | 4 +- libs/CodeMirror/mode/http/index.html | 2 +- .../mode/javascript/typescript.html | 16 +- libs/CodeMirror/mode/less/index.html | 8 +- libs/CodeMirror/mode/mirc/index.html | 4 +- libs/CodeMirror/mode/perl/index.html | 16 +- libs/CodeMirror/mode/php/index.html | 4 +- libs/CodeMirror/mode/q/index.html | 120 +- libs/CodeMirror/mode/scheme/index.html | 34 +- libs/CodeMirror/mode/smarty/index.html | 26 +- libs/CodeMirror/mode/sql/index.html | 22 +- libs/CodeMirror/mode/stex/index.html | 2 +- libs/CodeMirror/mode/tcl/index.html | 14 +- libs/CodeMirror/mode/tiki/index.html | 2 +- libs/CodeMirror/mode/tiki/tiki.css | 20 +- libs/CodeMirror/mode/vb/index.html | 6 +- libs/CodeMirror/mode/vbscript/index.html | 6 +- libs/CodeMirror/mode/xquery/index.html | 30 +- readme.md | 18 +- server/php/index.php | 156 +- server/php/users.php | 64 +- server/php/w2db.php | 522 +- server/php/w2lib.php | 560 +- server/readme.md | 10 +- src/kickstart/app.js | 582 +- src/kickstart/ks-core.js | 390 +- src/kickstart/ks-route.js | 244 +- src/kickstart/less/src/general.less | 198 +- src/kickstart/less/src/login.less | 114 +- src/kickstart/less/src/mixins.less | 66 +- src/kickstart/less/src/top-tabs.less | 58 +- src/kickstart/less/src/top-toolbar.less | 116 +- src/less/src/buttons.less | 214 +- src/less/src/common.less | 408 +- src/less/src/fields.less | 846 +- src/less/src/form.less | 410 +- src/less/src/grid.less | 1322 +- src/less/src/images-dark.less | 24 +- src/less/src/images-dev.less | 24 +- src/less/src/images.less | 24 +- src/less/src/layout.less | 146 +- src/less/src/mixins.less | 134 +- src/less/src/popup.less | 234 +- src/less/src/sidebar.less | 388 +- src/less/src/tabs.less | 114 +- src/less/src/toolbar.less | 158 +- src/less/w2ui-dark.less | 16 +- src/locale/bg-bg.json | 146 +- src/locale/de-de.json | 122 +- src/locale/en-us.json | 30 +- src/locale/fr-fr.json | 122 +- src/locale/it-it.json | 122 +- src/locale/ja-jp.json | 148 +- src/locale/ko-kr.json | 120 +- src/locale/nl-nl.json | 122 +- src/locale/pl-pl.json | 136 +- src/locale/pt-br.json | 148 +- src/locale/ru-ru.json | 142 +- src/locale/tr-tr.json | 128 +- src/locale/zh-cn.json | 156 +- src/w2fields.js | 4162 +-- src/w2form.js | 1898 +- src/w2grid.js | 9798 +++--- src/w2layout.js | 2034 +- src/w2listview.js | 1384 +- src/w2popup.js | 1440 +- src/w2sidebar.js | 1626 +- src/w2tabs.js | 752 +- src/w2toolbar.js | 1000 +- src/w2utils.js | 3100 +- test/data.php | 50 +- test/fields-old.html | 24 +- test/fields.html | 506 +- test/form-old.html | 216 +- test/form-template.html | 124 +- test/form.html | 520 +- test/form.php | 34 +- test/form2.html | 130 +- test/grid-old.html | 146 +- test/grid-stop-request.html | 142 +- test/grid.html | 406 +- test/grid.json | 44 +- test/grid2.html | 158 +- test/ks.html | 8 +- test/ks.js | 1 - test/layout-grid-form.html | 212 +- test/layout-old.html | 38 +- test/layout.html | 124 +- test/listdat.json | 10 +- test/popup-old.html | 94 +- test/popup-template.html | 2 +- test/popup.html | 166 +- test/qunit/index.html | 22 +- test/qunit/index2.html | 24 +- test/qunit/lib/qunit.css | 174 +- test/qunit/lib/qunit.js | 3802 +-- test/qunit/tests/w2fields.js | 248 +- test/qunit/tests/w2grid.js | 130 +- test/qunit/tests/w2utils.js | 524 +- test/sidebar-old.html | 100 +- test/sidebar.html | 146 +- test/tabs-edit-grid.html | 192 +- test/tabs-old.html | 44 +- test/tabs.html | 52 +- test/toolbar-old.html | 52 +- test/toolbar.html | 72 +- w2ui.jquery.json | 22 +- 651 files changed, 53519 insertions(+), 53524 deletions(-) delete mode 100644 test/ks.js diff --git a/.gitignore b/.gitignore index b028887ba..0d12cb407 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,2 @@ tmp/* -*.txt - -# npm install cruft -node_modules/ - +node_modules/ \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index ac1077ce0..09eacf5d7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,232 +1,232 @@ module.exports = function (grunt) { - var w2ui = '/* w2ui 1.4.x (nightly) (c) http://w2ui.com, vitmalina@gmail.com */\n'; - var fields = '/* w2ui-fields.js 1.4.x (nightly), part of w2ui (c) http://w2ui.com, vitmalina@gmail.com */\n'; - var ks = '/* kicstart 0.1.x (nightly) (c) http://w2ui.com/kickstart, vitmalina@gmail.com */\n'; + var w2ui = '/* w2ui 1.4.x (nightly) (c) http://w2ui.com, vitmalina@gmail.com */\n'; + var fields = '/* w2ui-fields.js 1.4.x (nightly), part of w2ui (c) http://w2ui.com, vitmalina@gmail.com */\n'; + var ks = '/* kicstart 0.1.x (nightly) (c) http://w2ui.com/kickstart, vitmalina@gmail.com */\n'; - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), - clean: { - w2ui: [ - 'dist/w2ui.js', - 'dist/w2ui.min.js', - 'dist/w2ui.css', - 'dist/w2ui.min.css', - 'dist/w2ui-dark.css', - 'dist/w2ui-dark.min.css' - ], - fields: [ - 'dist/w2ui-fields.js', - 'dist/w2ui-fields.min.js', - 'dist/w2ui-fields.css', - 'dist/w2ui-fields.min.css' - ], - ks: [ - 'dist/kickstart.js', - 'dist/kickstart.min.js', - 'dist/kickstart.css', - 'dist/kickstart.min.css' - ] - }, + clean: { + w2ui: [ + 'dist/w2ui.js', + 'dist/w2ui.min.js', + 'dist/w2ui.css', + 'dist/w2ui.min.css', + 'dist/w2ui-dark.css', + 'dist/w2ui-dark.min.css' + ], + fields: [ + 'dist/w2ui-fields.js', + 'dist/w2ui-fields.min.js', + 'dist/w2ui-fields.css', + 'dist/w2ui-fields.min.css' + ], + ks: [ + 'dist/kickstart.js', + 'dist/kickstart.min.js', + 'dist/kickstart.css', + 'dist/kickstart.min.css' + ] + }, - less: { - w2ui: { - files: { - "dist/w2ui.css": "src/less/w2ui.less", - "dist/w2ui-dark.css": "src/less/w2ui-dark.less" - } - }, - "w2ui-min": { - options: { - cleancss: true, - report: 'min' - }, - files: { - "dist/w2ui.min.css": "dist/w2ui.css", - "dist/w2ui-dark.min.css": "dist/w2ui-dark.css" - } - }, - fields: { - files: { - "dist/w2ui-fields.css": "src/less/w2ui-fields.less" - } - }, - "fields-min": { - options: { - cleancss: true, - report: 'min' - }, - files: { - "dist/w2ui-fields.min.css": "dist/w2ui-fields.css" - } - }, - ks: { - files: { - "dist/kickstart.css": "src/kickstart/less/kickstart.less" - } - }, - "ks-min": { - options: { - cleancss: true, - report: 'min' - }, - files: { - "dist/kickstart.min.css": "dist/kickstart.css" - } - } - }, + less: { + w2ui: { + files: { + "dist/w2ui.css": "src/less/w2ui.less", + "dist/w2ui-dark.css": "src/less/w2ui-dark.less" + } + }, + "w2ui-min": { + options: { + cleancss: true, + report: 'min' + }, + files: { + "dist/w2ui.min.css": "dist/w2ui.css", + "dist/w2ui-dark.min.css": "dist/w2ui-dark.css" + } + }, + fields: { + files: { + "dist/w2ui-fields.css": "src/less/w2ui-fields.less" + } + }, + "fields-min": { + options: { + cleancss: true, + report: 'min' + }, + files: { + "dist/w2ui-fields.min.css": "dist/w2ui-fields.css" + } + }, + ks: { + files: { + "dist/kickstart.css": "src/kickstart/less/kickstart.less" + } + }, + "ks-min": { + options: { + cleancss: true, + report: 'min' + }, + files: { + "dist/kickstart.min.css": "dist/kickstart.css" + } + } + }, - concat: { - w2ui: { - options: { - banner: w2ui - }, - src: [ - 'src/w2utils.js', - 'src/w2grid.js', - 'src/w2layout.js', - 'src/w2popup.js', - 'src/w2tabs.js', - 'src/w2toolbar.js', - 'src/w2sidebar.js', - 'src/w2fields.js', - 'src/w2form.js', - 'src/w2listview.js' - ], - dest: 'dist/w2ui.js' - }, - fields: { - options: { - banner: fields - }, - src: [ - 'src/w2utils.js', - 'src/w2fields.js' - ], - dest: 'dist/w2ui-fields.js' - }, - ks: { - options: { - banner: ks - }, - src: ['src/kickstart/ks-core.js', 'src/kickstart/ks-route.js'], - dest: 'dist/kickstart.js' - }, - 'banner-w2ui-1': { - options: { banner: w2ui }, - src : 'dist/w2ui.css', - dest: 'dist/w2ui.css' - }, - 'banner-w2ui-2': { - options: { banner: w2ui }, - src : 'dist/w2ui.min.css', - dest: 'dist/w2ui.min.css' - }, - 'banner-w2ui-3': { - options: { banner: w2ui }, - src : 'dist/w2ui-dark.css', - dest: 'dist/w2ui-dark.css' - }, - 'banner-w2ui-4': { - options: { banner: w2ui }, - src : 'dist/w2ui-dark.min.css', - dest: 'dist/w2ui-dark.min.css' - }, - 'banner-fields-1': { - options: { banner: fields }, - src : 'dist/w2ui-fields.css', - dest: 'dist/w2ui-fields.css' - }, - 'banner-fields-2': { - options: { banner: fields }, - src : 'dist/w2ui-fields.min.css', - dest: 'dist/w2ui-fields.min.css' - }, - 'banner-ks-1': { - options: { banner: ks }, - src : 'dist/kickstart.css', - dest: 'dist/kickstart.css' - }, - 'banner-ks-2': { - options: { banner: ks }, - src : 'dist/kickstart.min.css', - dest: 'dist/kickstart.min.css' - } - }, + concat: { + w2ui: { + options: { + banner: w2ui + }, + src: [ + 'src/w2utils.js', + 'src/w2grid.js', + 'src/w2layout.js', + 'src/w2popup.js', + 'src/w2tabs.js', + 'src/w2toolbar.js', + 'src/w2sidebar.js', + 'src/w2fields.js', + 'src/w2form.js', + 'src/w2listview.js' + ], + dest: 'dist/w2ui.js' + }, + fields: { + options: { + banner: fields + }, + src: [ + 'src/w2utils.js', + 'src/w2fields.js' + ], + dest: 'dist/w2ui-fields.js' + }, + ks: { + options: { + banner: ks + }, + src: ['src/kickstart/ks-core.js', 'src/kickstart/ks-route.js'], + dest: 'dist/kickstart.js' + }, + 'banner-w2ui-1': { + options: { banner: w2ui }, + src : 'dist/w2ui.css', + dest : 'dist/w2ui.css' + }, + 'banner-w2ui-2': { + options : { banner: w2ui }, + src : 'dist/w2ui.min.css', + dest : 'dist/w2ui.min.css' + }, + 'banner-w2ui-3': { + options : { banner: w2ui }, + src : 'dist/w2ui-dark.css', + dest : 'dist/w2ui-dark.css' + }, + 'banner-w2ui-4': { + options : { banner: w2ui }, + src : 'dist/w2ui-dark.min.css', + dest : 'dist/w2ui-dark.min.css' + }, + 'banner-fields-1': { + options : { banner: fields }, + src : 'dist/w2ui-fields.css', + dest : 'dist/w2ui-fields.css' + }, + 'banner-fields-2': { + options : { banner: fields }, + src : 'dist/w2ui-fields.min.css', + dest : 'dist/w2ui-fields.min.css' + }, + 'banner-ks-1': { + options : { banner: ks }, + src : 'dist/kickstart.css', + dest : 'dist/kickstart.css' + }, + 'banner-ks-2': { + options : { banner: ks }, + src : 'dist/kickstart.min.css', + dest : 'dist/kickstart.min.css' + } + }, - uglify: { - w2ui: { - options: { - banner: w2ui - }, - files: { - 'dist/w2ui.min.js': 'dist/w2ui.js', - } - }, - fields: { - options: { - banner: fields - }, - files: { - 'dist/w2ui-fields.min.js': 'dist/w2ui-fields.js', - } - }, - ks: { - options: { - banner: ks - }, - files: { - 'dist/kickstart.min.js': 'dist/kickstart.js', - } - } + uglify: { + w2ui: { + options: { + banner: w2ui + }, + files: { + 'dist/w2ui.min.js': 'dist/w2ui.js', + } + }, + fields: { + options: { + banner: fields + }, + files: { + 'dist/w2ui-fields.min.js': 'dist/w2ui-fields.js', + } + }, + ks: { + options: { + banner: ks + }, + files: { + 'dist/kickstart.min.js': 'dist/kickstart.js', + } + } - }, + }, - shell: { - docs: { - options: { - stdout: true - }, - command: 'cd docs; node generate.js;' - } - }, + shell: { + docs: { + options: { + stdout: true + }, + command: 'cd docs; node generate.js;' + } + }, - watch: { - "w2ui" : { - files: ['src/*.js'], - tasks: ['concat:w2ui', 'uglify:w2ui'] - }, - "w2ui-less" : { - files: ['src/less/*.less', 'src/less/src/*.less'], - tasks: ['less:w2ui', 'less:w2ui-min', 'less:fields', 'less:fields-min', - 'concat:banner-w2ui-1', 'concat:banner-w2ui-2', 'concat:banner-w2ui-3', 'concat:banner-w2ui-4', - 'concat:banner-fields-1', 'concat:banner-fields-2'] - }, - "ks" : { - files: ['src/kickstart/*.js'], - tasks: ['concat:ks', 'uglify:ks'] - }, - "ks-less" : { - files: ['src/kickstart/less/*.less', 'src/kickstart/less/src/*.less'], - tasks: ['less:ks', 'less:ks-min', 'concat:banner-ks-1', 'concat:banner-ks-2'] - } - } - }); + watch: { + "w2ui" : { + files: ['src/*.js'], + tasks: ['concat:w2ui', 'uglify:w2ui'] + }, + "w2ui-less" : { + files: ['src/less/*.less', 'src/less/src/*.less'], + tasks: ['less:w2ui', 'less:w2ui-min', 'less:fields', 'less:fields-min', + 'concat:banner-w2ui-1', 'concat:banner-w2ui-2', 'concat:banner-w2ui-3', 'concat:banner-w2ui-4', + 'concat:banner-fields-1', 'concat:banner-fields-2'] + }, + "ks" : { + files: ['src/kickstart/*.js'], + tasks: ['concat:ks', 'uglify:ks'] + }, + "ks-less" : { + files: ['src/kickstart/less/*.less', 'src/kickstart/less/src/*.less'], + tasks: ['less:ks', 'less:ks-min', 'concat:banner-ks-1', 'concat:banner-ks-2'] + } + } + }); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-less'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-shell'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-less'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-shell'); - grunt.registerTask('default', ['clean', 'less', 'concat', 'uglify']); - grunt.registerTask('docs', ['shell:docs']); - grunt.registerTask('w2ui', ['clean:w2ui', 'less:w2ui', 'less:w2ui-min', 'concat:w2ui', 'uglify:w2ui', - 'concat:banner-w2ui-1', 'concat:banner-w2ui-2', 'concat:banner-w2ui-3', 'concat:banner-w2ui-4']); - grunt.registerTask('fields', ['clean:fields', 'less:fields', 'less:fields-min', 'concat:fields', 'uglify:fields', - 'concat:banner-fields-1', 'concat:banner-fields-2']); - grunt.registerTask('ks', ['clean:ks', 'less:ks', 'less:ks-min', 'concat:ks', 'uglify:ks', - 'concat:banner-ks-1', 'concat:banner-ks-2']); + grunt.registerTask('default', ['clean', 'less', 'concat', 'uglify']); + grunt.registerTask('docs', ['shell:docs']); + grunt.registerTask('w2ui', ['clean:w2ui', 'less:w2ui', 'less:w2ui-min', 'concat:w2ui', 'uglify:w2ui', + 'concat:banner-w2ui-1', 'concat:banner-w2ui-2', 'concat:banner-w2ui-3', 'concat:banner-w2ui-4']); + grunt.registerTask('fields', ['clean:fields', 'less:fields', 'less:fields-min', 'concat:fields', 'uglify:fields', + 'concat:banner-fields-1', 'concat:banner-fields-2']); + grunt.registerTask('ks', ['clean:ks', 'less:ks', 'less:ks-min', 'concat:ks', 'uglify:ks', + 'concat:banner-ks-1', 'concat:banner-ks-2']); }; \ No newline at end of file diff --git a/build.xml b/build.xml index b18e0a61f..3e7f58735 100644 --- a/build.xml +++ b/build.xml @@ -1,241 +1,241 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/code-mirror.js b/demos/code-mirror.js index a80fbf607..121dbd321 100644 --- a/demos/code-mirror.js +++ b/demos/code-mirror.js @@ -2,13 +2,13 @@ // Init Code Mirror mixed HTML in one command $(function () { - $('head').append( - '\n'+ - '\n'+ - '\n'+ - '\n'+ - '\n'+ - '\n'+ - '\n' - ); + $('head').append( + '\n'+ + '\n'+ + '\n'+ + '\n'+ + '\n'+ + '\n'+ + '\n' + ); }); \ No newline at end of file diff --git a/demos/data/content2.html b/demos/data/content2.html index 212037a28..882831ceb 100644 --- a/demos/data/content2.html +++ b/demos/data/content2.html @@ -1,24 +1,24 @@
- some image + some image
- some image + some image
- some image + some image
- some image + some image
- some image + some image
- some image + some image
- some image + some image
- some image + some image
\ No newline at end of file diff --git a/demos/data/form.html b/demos/data/form.html index 2004c7dbf..883dafb48 100644 --- a/demos/data/form.html +++ b/demos/data/form.html @@ -1,39 +1,39 @@
-
Text:
-
- -
-
Text (alpha-numeric):
-
- -
-
Number (int):
-
- -
-
Number (float):
-
- -
-
Date:
-
- -
-
List:
-
- -
-
Text Area:
-
-
@@ -21,11 +21,11 @@

From Textarea

diff --git a/demos/examples/editor-3.html b/demos/examples/editor-3.html index 79f1f21b6..d8585ffff 100644 --- a/demos/examples/editor-3.html +++ b/demos/examples/editor-3.html @@ -1,49 +1,49 @@
- -
-

Show/Hide Buttons

- If you need to hide some buttons from the toolbar, you need to set .showButtons property which is an object where you - specify what buttons are hidden. -

- The names of the buttons are: btn-undo, btn-redo, btn-break1, btn-paragraph, btn-font, btn-size, btn-break2, btn-bold, - btn-italic, btn-formating, btn-break3, btn-color, btn-bgcolor, btn-break4, btn-paste, btn-clear, btn-source, btn-break5, btn-align, btn-spacing, btn-lists, - btn-break6, btn-indent, btn-outdent, btn-break7, btn-link, btn-unlink, btn-break8, btn-fullscreen. -
-
-
+ +
+

Show/Hide Buttons

+ If you need to hide some buttons from the toolbar, you need to set .showButtons property which is an object where you + specify what buttons are hidden. +

+ The names of the buttons are: btn-undo, btn-redo, btn-break1, btn-paragraph, btn-font, btn-size, btn-break2, btn-bold, + btn-italic, btn-formating, btn-break3, btn-color, btn-bgcolor, btn-break4, btn-paste, btn-clear, btn-source, btn-break5, btn-align, btn-spacing, btn-lists, + btn-break6, btn-indent, btn-outdent, btn-break7, btn-link, btn-unlink, btn-break8, btn-fullscreen. +
+
+
- +
diff --git a/demos/examples/editor-4.html b/demos/examples/editor-4.html index ad4ad752a..5b7309370 100644 --- a/demos/examples/editor-4.html +++ b/demos/examples/editor-4.html @@ -1,35 +1,35 @@
-
-

Add Buttons

- It is often that you need to extend the functionality of the editor. You can easily add toolbar items and call editor's methods to - insert HTML or do other actions. -
-
-
+
+

Add Buttons

+ It is often that you need to extend the functionality of the editor. You can easily add toolbar items and call editor's methods to + insert HTML or do other actions. +
+
+
- +
- + diff --git a/demos/examples/forms-1.html b/demos/examples/forms-1.html index e7543e219..6d6eb1163 100644 --- a/demos/examples/forms-1.html +++ b/demos/examples/forms-1.html @@ -1,55 +1,55 @@
-
-

Simple Form

- Working with forms is common for a web developer. However, there is no way to create a unique template for all use cases. The w2ui library - streamlines most common tasks for you. The example below shows a simple form with two required fields, save and reset buttons. -
-
-
+
+

Simple Form

+ Working with forms is common for a web developer. However, there is no way to create a unique template for all use cases. The w2ui library + streamlines most common tasks for you. The example below shows a simple form with two required fields, save and reset buttons. +
+
+
-
-
First Name:
-
- -
-
Last Name:
-
- -
-
Text Area:
-
- -
-
+
+
First Name:
+
+ +
+
Last Name:
+
+ +
+
Text Area:
+
+ +
+
-
- - -
+
+ + +
diff --git a/demos/examples/forms-2.html b/demos/examples/forms-2.html index fe1e6c084..cc1d26f91 100644 --- a/demos/examples/forms-2.html +++ b/demos/examples/forms-2.html @@ -1,28 +1,28 @@
-
-

Field Types

- Because you can use your own HTML you can create any custom field types. All you need to do is to bind your fields to the w2form object so - you can take advantage of its methods and properties. The w2form object has implementation of most common field types as you can see in the - example below: -
-
- Below is the list of supported field types and what corresponding HTML element they need. Please note that there is no <select> - element. Similar functionality is done with list (single item selection) or enum (multi items selection). - - - - - - - - - - - - - -
text input[type=text] or textarea
int input[type=text]
float input[type=text]
hex input[type=text]
money input[type=text]
alphanumeric input[type=text]
email input[type=text]
checkbox input[type=checkbox]
password input[type=password]
date input[type=text]
list input[type=text]
enum input[type=text]
-
+
+

Field Types

+ Because you can use your own HTML you can create any custom field types. All you need to do is to bind your fields to the w2form object so + you can take advantage of its methods and properties. The w2form object has implementation of most common field types as you can see in the + example below: +
+
+ Below is the list of supported field types and what corresponding HTML element they need. Please note that there is no <select> + element. Similar functionality is done with list (single item selection) or enum (multi items selection). + + + + + + + + + + + + + +
text input[type=text] or textarea
int input[type=text]
float input[type=text]
hex input[type=text]
money input[type=text]
alphanumeric input[type=text]
email input[type=text]
checkbox input[type=checkbox]
password input[type=password]
date input[type=text]
list input[type=text]
enum input[type=text]
+
@@ -31,38 +31,38 @@

Field Types

diff --git a/demos/examples/forms-3.html b/demos/examples/forms-3.html index 86627ac7b..793d4e151 100644 --- a/demos/examples/forms-3.html +++ b/demos/examples/forms-3.html @@ -1,114 +1,114 @@
-
-

Large Form

- If you have a large form with many fields you can render the form in a variety of ways. There is no difference how you position HTML. - The w2form object binds to the fields that you specify. - There are several helper classes for variable width for labels and fields. - In the exampble below you can see w2ui-span4 and w2ui-span5 classes, where w2ui-span4 = 80px and w2ui-span5 = 100px. There - are w2ui-span1, ..., w2ui-span10, where each step is 20px. -
-
-
+
+

Large Form

+ If you have a large form with many fields you can render the form in a variety of ways. There is no difference how you position HTML. + The w2form object binds to the fields that you specify. + There are several helper classes for variable width for labels and fields. + In the exampble below you can see w2ui-span4 and w2ui-span5 classes, where w2ui-span4 = 80px and w2ui-span5 = 100px. There + are w2ui-span1, ..., w2ui-span10, where each step is 20px. +
+
+
-
-
-
General
-
-
First Name:
-
- -
-
Last Name:
-
- -
-
Comments:
-
- -
-
-
-
-
Address
-
-
Address Line 1:
-
- -
-
Address Line 2:
-
- -
-
City:
-
- -
-
State:
-
- -
-
Zip:
-
- -
-
-
-
-
Additional Fields
-
-
Short Bio:
-
- -
-
Talk Name:
-
- -
-
Talk Description:
-
- -
-
-
-
+
+
+
General
+
+
First Name:
+
+ +
+
Last Name:
+
+ +
+
Comments:
+
+ +
+
+
+
+
Address
+
+
Address Line 1:
+
+ +
+
Address Line 2:
+
+ +
+
City:
+
+ +
+
State:
+
+ +
+
Zip:
+
+ +
+
+
+
+
Additional Fields
+
+
Short Bio:
+
+ +
+
Talk Name:
+
+ +
+
Talk Description:
+
+ +
+
+
+
-
- - -
+
+ + +
\ No newline at end of file diff --git a/demos/examples/forms-4.html b/demos/examples/forms-4.html index c8f42decf..cc863f97c 100644 --- a/demos/examples/forms-4.html +++ b/demos/examples/forms-4.html @@ -1,11 +1,11 @@
-
-

Multi Page Form

- This is exactly the same form as in the previous example, but in this case the form is presented in three pages. - Click on the page link to switch pages. -
-
-
+
+

Multi Page Form

+ This is exactly the same form as in the previous example, but in this case the form is presented in three pages. + Click on the page link to switch pages. +
+
+
@@ -14,92 +14,92 @@

Multi Page Form

Page 3
-
-
First Name:
-
- -
-
Last Name:
-
- -
-
Comments:
-
- -
-
-
-
Address Line 1:
-
- -
-
Address Line 2:
-
- -
-
City:
-
- -
-
State:
-
- -
-
Zip:
-
- -
-
-
-
Talk Name:
-
- -
-
Talk Description:
-
- -
-
-
Short Bio:
-
- -
-
+
+
First Name:
+
+ +
+
Last Name:
+
+ +
+
Comments:
+
+ +
+
+
+
Address Line 1:
+
+ +
+
Address Line 2:
+
+ +
+
City:
+
+ +
+
State:
+
+ +
+
Zip:
+
+ +
+
+
+
Talk Name:
+
+ +
+
Talk Description:
+
+ +
+
+
Short Bio:
+
+ +
+
-
- - -
+
+ + +
diff --git a/demos/examples/forms-5.html b/demos/examples/forms-5.html index d0e1e001a..98df22d89 100644 --- a/demos/examples/forms-5.html +++ b/demos/examples/forms-5.html @@ -1,104 +1,104 @@
-
-

Form with Tabs

- The form below is exactly the same form as in previous two examples, but with tabs. Tabs simplify presentation of large forms. -
-
-
+
+

Form with Tabs

+ The form below is exactly the same form as in previous two examples, but with tabs. Tabs simplify presentation of large forms. +
+
+
-
-
First Name:
-
- -
-
Last Name:
-
- -
-
Comments:
-
- -
-
-
-
Address Line 1:
-
- -
-
Address Line 2:
-
- -
-
City:
-
- -
-
State:
-
- -
-
Zip:
-
- -
-
-
-
Short Bio:
-
- -
-
Talk Name:
-
- -
-
Talk Description:
-
- -
-
+
+
First Name:
+
+ +
+
Last Name:
+
+ +
+
Comments:
+
+ +
+
+
+
Address Line 1:
+
+ +
+
Address Line 2:
+
+ +
+
City:
+
+ +
+
State:
+
+ +
+
Zip:
+
+ +
+
+
+
Short Bio:
+
+ +
+
Talk Name:
+
+ +
+
Talk Description:
+
+ +
+
-
- - -
+
+ + +
diff --git a/demos/examples/forms-6.html b/demos/examples/forms-6.html index 3b14b9a9a..c65f86e2a 100644 --- a/demos/examples/forms-6.html +++ b/demos/examples/forms-6.html @@ -1,73 +1,73 @@
-
-

Events

- All important actions trigger events. It is easy to listen to any form event either by providing on"EventName" function or by - using on() and off() methods. Open up a console and see the event flow of the form below. -
-
-
+
+

Events

+ All important actions trigger events. It is easy to listen to any form event either by providing on"EventName" function or by + using on() and off() methods. Open up a console and see the event flow of the form below. +
+
+
-
-
First Name:
-
- -
-
Last Name:
-
- -
-
DOB:
-
- -
-
Category:
-
- -
-
Text Area:
-
- -
-
+
+
First Name:
+
+ +
+
Last Name:
+
+ +
+
DOB:
+
+ +
+
Category:
+
+ +
+
Text Area:
+
+ +
+
-
- - -
+
+ + +
diff --git a/demos/examples/forms-7.html b/demos/examples/forms-7.html index a946350cf..2ebfeeb26 100644 --- a/demos/examples/forms-7.html +++ b/demos/examples/forms-7.html @@ -1,63 +1,63 @@
-
-

Input Controls

- You do not need to have a form to use w2ui library's fields (input controls). All of the fields can be used outside of w2form on any - text input element. -
-
-
- Below is the list of supported control types and corresponding HTML elements they need. Please note that there is - no <select> element. Similar functionality is done with list (single item selection) or enum (multi items selection). - - - - - - - - - - - - - -
text input[type=text] or textarea
int input[type=text]
float input[type=text]
hex input[type=text]
money input[type=text]
alphanumeric input[type=text]
email input[type=text]
checkbox input[type=checkbox]
password input[type=password]
date input[type=text]
list input[type=text]
enum input[type=text]
-
-
+
+

Input Controls

+ You do not need to have a form to use w2ui library's fields (input controls). All of the fields can be used outside of w2form on any + text input element. +
+
+
+ Below is the list of supported control types and corresponding HTML elements they need. Please note that there is + no <select> element. Similar functionality is done with list (single item selection) or enum (multi items selection). + + + + + + + + + + + + + +
text input[type=text] or textarea
int input[type=text]
float input[type=text]
hex input[type=text]
money input[type=text]
alphanumeric input[type=text]
email input[type=text]
checkbox input[type=checkbox]
password input[type=password]
date input[type=text]
list input[type=text]
enum input[type=text]
+
+
- - int
+ - int
- - float
+ - float
- - money
+ - money
- - percent
+ - percent
- - date
+ - date
- - enum + - enum
diff --git a/demos/examples/forms-8.html b/demos/examples/forms-8.html index 234e3a123..f8abdb058 100644 --- a/demos/examples/forms-8.html +++ b/demos/examples/forms-8.html @@ -1,11 +1,11 @@
-
-

Form in a Popup

- It is a frequent task to open a form inside a popup. I have seen many examples from the community when it was not done - correctly. The demo below demonstrates how to do this right. The form take entire available space of the popup. -
-
-
+
+

Form in a Popup

+ It is a frequent task to open a form inside a popup. I have seen many examples from the community when it was not done + correctly. The demo below demonstrates how to do this right. The form take entire available space of the popup. +
+
+
@@ -16,70 +16,70 @@

Form in a Popup

\ No newline at end of file diff --git a/demos/examples/forms-9.html b/demos/examples/forms-9.html index 19672aed2..5fe3b6c06 100644 --- a/demos/examples/forms-9.html +++ b/demos/examples/forms-9.html @@ -1,56 +1,56 @@
-
-

Form with Toolbar

- The example below features a simple form with a toolbar. There ar no form buttons, but the actions of the form are mapped - to toolbar buttons. First two are placeholder buttons, and second two are mapped to form actions. -
-
-
+
+

Form with Toolbar

+ The example below features a simple form with a toolbar. There ar no form buttons, but the actions of the form are mapped + to toolbar buttons. First two are placeholder buttons, and second two are mapped to form actions. +
+
+
-
-
First Name:
-
- -
-
Last Name:
-
- -
-
Comments:
-
- -
-
+
+
First Name:
+
+ +
+
Last Name:
+
+ +
+
Comments:
+
+ +
+
diff --git a/demos/examples/grid-1.html b/demos/examples/grid-1.html index b72d9e348..978c3768d 100644 --- a/demos/examples/grid-1.html +++ b/demos/examples/grid-1.html @@ -1,11 +1,11 @@
-
-

Simple Grid

- The grid below displays data loaded from a url. The data should come in a JSON format (see list.json files for more details). In this JSON - file you can pass any grid property and it will be merged into the grid. -
-
-
+
+

Simple Grid

+ The grid below displays data loaded from a url. The data should come in a JSON format (see list.json files for more details). In this JSON + file you can pass any grid property and it will be merged into the grid. +
+
+
@@ -14,16 +14,16 @@

Simple Grid

@@ -32,17 +32,17 @@

Simple Grid

diff --git a/demos/examples/grid-10.html b/demos/examples/grid-10.html index 5eb371534..37b83f5ec 100644 --- a/demos/examples/grid-10.html +++ b/demos/examples/grid-10.html @@ -1,48 +1,48 @@
-
-

Select/Unselect Records

- It is important for any project to be able to work with selection easily. This example demonstrate the use of several methods - that allow you to select, unselect and get selected records from the grid. -
-
-
+
+

Select/Unselect Records

+ It is important for any project to be able to work with selection easily. This example demonstrate the use of several methods + that allow you to select, unselect and get selected records from the grid. +
+
+

- - - - - - + + + + + + diff --git a/demos/examples/grid-11.html b/demos/examples/grid-11.html index 53bfe0e44..f2f5dc5fb 100644 --- a/demos/examples/grid-11.html +++ b/demos/examples/grid-11.html @@ -1,11 +1,11 @@
-
-

Fixed/Resizable Grid

- If you set grid.fixedBody property to true, the size of the grid will be fixed. If you set the - fixedBody property to false, the grid to the height of its data. -
-
-
+
+

Fixed/Resizable Grid

+ If you set grid.fixedBody property to true, the size of the grid will be fixed. If you set the + fixedBody property to false, the grid to the height of its data. +
+
+
@@ -15,53 +15,53 @@

Fixed/Resizable Grid

     diff --git a/demos/examples/grid-12.html b/demos/examples/grid-12.html index 1ede5d8f5..8cd89d0ce 100644 --- a/demos/examples/grid-12.html +++ b/demos/examples/grid-12.html @@ -1,11 +1,11 @@
-
-

Column Sort

- By default column sorting is disabled, but it is quite easy to enable it. Just set sortable column property - to true. As a user you can sort by several columns at the same time if you cold the ctrl key (command key on a mac). -
-
-
+
+

Column Sort

+ By default column sorting is disabled, but it is quite easy to enable it. Just set sortable column property + to true. As a user you can sort by several columns at the same time if you cold the ctrl key (command key on a mac). +
+
+
@@ -14,29 +14,29 @@

Column Sort

diff --git a/demos/examples/grid-13.html b/demos/examples/grid-13.html index 716cf4f3d..e2d23b636 100644 --- a/demos/examples/grid-13.html +++ b/demos/examples/grid-13.html @@ -1,11 +1,11 @@
-
-

Column Groups

- The column headers of the grid can be displayed in a single line or they can be grouped. The example below demonstrates how to - define column header groups so that several columns appear groupped. -
-
-
+
+

Column Groups

+ The column headers of the grid can be displayed in a single line or they can be grouped. The example below demonstrates how to + define column header groups so that several columns appear groupped. +
+
+
@@ -14,50 +14,50 @@

Column Groups

diff --git a/demos/examples/grid-14.html b/demos/examples/grid-14.html index e025e9ed5..759e06d87 100644 --- a/demos/examples/grid-14.html +++ b/demos/examples/grid-14.html @@ -1,11 +1,11 @@
-
-

Summary Records

- The summary is displayed at the bottom of the grid in unscrollable sections. If a regular record has summary property set to true, it will - be automatically moved to the summary section. -
-
-
+
+

Summary Records

+ The summary is displayed at the bottom of the grid in unscrollable sections. If a regular record has summary property set to true, it will + be automatically moved to the summary section. +
+
+
@@ -13,52 +13,52 @@

Summary Records

diff --git a/demos/examples/grid-15.html b/demos/examples/grid-15.html index 4bab3b874..1968f31ec 100644 --- a/demos/examples/grid-15.html +++ b/demos/examples/grid-15.html @@ -1,11 +1,11 @@
-
-

Simple Search

- The grid has two search options. (1) simple search - one search box that searches through predefined searches. (2) An advanced search - a search overlay with predefined search fields). The example below demonstrates a simple search. +
+

Simple Search

+ The grid has two search options. (1) simple search - one search box that searches through predefined searches. (2) An advanced search - a search overlay with predefined search fields). The example below demonstrates a simple search. -
-
-
+
+
+
@@ -14,47 +14,47 @@

Simple Search

diff --git a/demos/examples/grid-16.html b/demos/examples/grid-16.html index c9bd8bb36..44e03e1bc 100644 --- a/demos/examples/grid-16.html +++ b/demos/examples/grid-16.html @@ -1,11 +1,11 @@
-
-

Advanced Search

- The grid has two search options. (1) simple search - one search box that searches through predefined searches. (2) An advanced - search - a search overlay with predefined search fields. The example below demonstrates an advanced search. -
-
-
+
+

Advanced Search

+ The grid has two search options. (1) simple search - one search box that searches through predefined searches. (2) An advanced + search - a search overlay with predefined search fields. The example below demonstrates an advanced search. +
+
+
@@ -14,47 +14,47 @@

Advanced Search

diff --git a/demos/examples/grid-17.html b/demos/examples/grid-17.html index c9993d180..3c39fa566 100644 --- a/demos/examples/grid-17.html +++ b/demos/examples/grid-17.html @@ -1,11 +1,11 @@
-
-

Grid Toolbar

- Grid uses w2toolbar as its toolbar. Which means you can add, remove, disable, enable, etc. buttons very easily. There are - some default controls that you can also use. Below is the grid that has all possible default controls. -
-
-
+
+

Grid Toolbar

+ Grid uses w2toolbar as its toolbar. Which means you can add, remove, disable, enable, etc. buttons very easily. There are + some default controls that you can also use. Below is the grid that has all possible default controls. +
+
+
@@ -13,61 +13,61 @@

Grid Toolbar

diff --git a/demos/examples/grid-18.html b/demos/examples/grid-18.html index d96263262..381eeffcd 100644 --- a/demos/examples/grid-18.html +++ b/demos/examples/grid-18.html @@ -1,62 +1,62 @@
-
-

Master -> Details

- There is a number of different events you can listen to in the grid. The example below demonstrates how to implement a simple - master -> detail list. In the example the grids use local data, but there is no restriction on this. -
-
-
+
+

Master -> Details

+ There is a number of different events you can listen to in the grid. The example below demonstrates how to implement a simple + master -> detail list. In the example the grids use local data, but there is no restriction on this. +
+
+
-
-
+
+
diff --git a/demos/examples/grid-19.html b/demos/examples/grid-19.html index 3572372db..14fb52f78 100644 --- a/demos/examples/grid-19.html +++ b/demos/examples/grid-19.html @@ -1,72 +1,72 @@
-
-

Two Grids

- Below is a quick example how to work with multiple grids. The example demonstrates how to catch events from one grid and move a record - from one grid to another. -
-
-
+
+

Two Grids

+ Below is a quick example how to work with multiple grids. The example demonstrates how to catch events from one grid and move a record + from one grid to another. +
+
+
-
-
+
+
diff --git a/demos/examples/grid-2.html b/demos/examples/grid-2.html index 051d805a8..185afb19b 100644 --- a/demos/examples/grid-2.html +++ b/demos/examples/grid-2.html @@ -1,11 +1,11 @@
-
-

Row Formating

- You can pass background and text color for the row in the JSON file. You can also pass any other Grid properties - in the JSON file. -
-
-
+
+

Row Formating

+ You can pass background and text color for the row in the JSON file. You can also pass any other Grid properties + in the JSON file. +
+
+
@@ -14,15 +14,15 @@

Row Formating

@@ -31,45 +31,45 @@

Row Formating

diff --git a/demos/examples/grid-20.html b/demos/examples/grid-20.html index 8202033fb..8b909955d 100644 --- a/demos/examples/grid-20.html +++ b/demos/examples/grid-20.html @@ -1,17 +1,17 @@
-
-

Render to a New Box

- When you create a grid it is not required to provide a container, thus it creates a grid in memory. - The example below illustrates how to create a grid in memory and render it when needed and where needed. -
-
-
+
+

Render to a New Box

+ When you create a grid it is not required to provide a container, thus it creates a grid in memory. + The example below illustrates how to create a grid in memory and render it when needed and where needed. +
+
+
-
-
+
+

@@ -20,23 +20,23 @@

Render to a New Box

diff --git a/demos/examples/grid-21.html b/demos/examples/grid-21.html index 4daa37d67..522fb4b47 100644 --- a/demos/examples/grid-21.html +++ b/demos/examples/grid-21.html @@ -1,12 +1,12 @@
-
-

Inline Editing

- All grids support inline editing. To enable inline editing add editable object for the column you - want to make editable. This object takes several parameters to control behaviour of the editable input control. You can make - particular records uneditable, see example below -
-
-
+
+

Inline Editing

+ All grids support inline editing. To enable inline editing add editable object for the column you + want to make editable. This object takes several parameters to control behaviour of the editable input control. You can make + particular records uneditable, see example below +
+
+
@@ -17,98 +17,98 @@

Inline Editing

diff --git a/demos/examples/grid-22.html b/demos/examples/grid-22.html index 2af6e5ba7..46c216bb4 100644 --- a/demos/examples/grid-22.html +++ b/demos/examples/grid-22.html @@ -1,10 +1,10 @@
-
-

Resizable Columns

- To make any column resizable, just add resizable: true in it definition. The grid below demonstrates resizable columns. -
-
-
+
+

Resizable Columns

+ To make any column resizable, just add resizable: true in it definition. The grid below demonstrates resizable columns. +
+
+
@@ -13,37 +13,37 @@

Resizable Columns

diff --git a/demos/examples/grid-23.html b/demos/examples/grid-23.html index 79165a3b1..c6cf782fb 100644 --- a/demos/examples/grid-23.html +++ b/demos/examples/grid-23.html @@ -1,11 +1,11 @@
-
-

Cell Formatting

- Cell formatting works by defining render function for the column. There is a set of predefined - formatting functions (int, float, number, money, date, percent) or you can define your own function. -
-
-
+
+

Cell Formatting

+ Cell formatting works by defining render function for the column. There is a set of predefined + formatting functions (int, float, number, money, date, percent) or you can define your own function. +
+
+
@@ -14,38 +14,38 @@

Cell Formatting

diff --git a/demos/examples/grid-24.html b/demos/examples/grid-24.html index 269f7b0ba..48a9c466e 100644 --- a/demos/examples/grid-24.html +++ b/demos/examples/grid-24.html @@ -1,11 +1,11 @@
-
-

Lock/Unlock Grid

- There are several utility functions of the grid that allow to lock/unlock content, display error message and change status. The - example below demonstrates some of this functions. -
-
-
+
+

Lock/Unlock Grid

+ There are several utility functions of the grid that allow to lock/unlock content, display error message and change status. The + example below demonstrates some of this functions. +
+
+
@@ -19,41 +19,41 @@

Lock/Unlock Grid

diff --git a/demos/examples/grid-25.html b/demos/examples/grid-25.html index 88d71c27f..15e1a68ea 100644 --- a/demos/examples/grid-25.html +++ b/demos/examples/grid-25.html @@ -1,10 +1,10 @@
-
-

Reorder Grid Columns

- You can enable grid columns reorder. -
-
-
+
+

Reorder Grid Columns

+ You can enable grid columns reorder. +
+
+
@@ -13,42 +13,42 @@

Reorder Grid Columns

diff --git a/demos/examples/grid-3.html b/demos/examples/grid-3.html index 4f2ad0ee6..f3b780964 100644 --- a/demos/examples/grid-3.html +++ b/demos/examples/grid-3.html @@ -1,62 +1,62 @@
-
-

Grid Elements

- Any Grid consists of header, toolbar, record headers, line numbers, and footer, as well as select record and expand record columns. - You can show/hide then at any time. -
-
-
+
+

Grid Elements

+ Any Grid consists of header, toolbar, record headers, line numbers, and footer, as well as select record and expand record columns. + You can show/hide then at any time. +
+
+

+ onclick="var obj = w2ui['grid']; obj.show.header = !obj.show.header; w2ui['grid'].refresh();"> + onclick="var obj = w2ui['grid']; obj.show.toolbar = !obj.show.toolbar; w2ui['grid'].refresh();"> + onclick="var obj = w2ui['grid']; obj.show.columnHeaders = !obj.show.columnHeaders; w2ui['grid'].refresh();"> + onclick="var obj = w2ui['grid']; obj.show.footer = !obj.show.footer; w2ui['grid'].refresh();"> + onclick="var obj = w2ui['grid']; obj.show.lineNumbers = !obj.show.lineNumbers; w2ui['grid'].refresh();"> + onclick="var obj = w2ui['grid']; obj.show.selectColumn = !obj.show.selectColumn; w2ui['grid'].refresh();"> + onclick="var obj = w2ui['grid']; obj.show.expandColumn = !obj.show.expandColumn; w2ui['grid'].refresh();"> @@ -65,17 +65,17 @@

Grid Elements

diff --git a/demos/examples/grid-4.html b/demos/examples/grid-4.html index a5908e3c4..820b2f9af 100644 --- a/demos/examples/grid-4.html +++ b/demos/examples/grid-4.html @@ -1,22 +1,22 @@
-
-

Local or Remote Data Source

- The data in the grid might come from a local or remote data source. If you define grid.url - property, the grid will assume that your data source is remote. Otherwise, the data source is local (all records are stored in - grid.records) array. If data source is remote, the grid will: -
    -
  • Pull records from the server on render
  • -
  • Pull records from the server on reload
  • -
  • Pull more records when user scrolls (if needed)
  • -
  • Submit search to the server (user types in a search field)
  • -
  • Submit sort to the server (user click on the column)
  • -
  • Submit delete when user clicks and confirms delete operation
  • -
  • Submit save when user clicks the save button
  • -
- Below is the example of the grid with local data source. -
-
-
+
+

Local or Remote Data Source

+ The data in the grid might come from a local or remote data source. If you define grid.url + property, the grid will assume that your data source is remote. Otherwise, the data source is local (all records are stored in + grid.records) array. If data source is remote, the grid will: +
    +
  • Pull records from the server on render
  • +
  • Pull records from the server on reload
  • +
  • Pull more records when user scrolls (if needed)
  • +
  • Submit search to the server (user types in a search field)
  • +
  • Submit sort to the server (user click on the column)
  • +
  • Submit delete when user clicks and confirms delete operation
  • +
  • Submit save when user clicks the save button
  • +
+ Below is the example of the grid with local data source. +
+
+
@@ -25,38 +25,38 @@

Local or Remote Data Source

diff --git a/demos/examples/grid-5.html b/demos/examples/grid-5.html index 57077ddc9..ffedcce16 100644 --- a/demos/examples/grid-5.html +++ b/demos/examples/grid-5.html @@ -1,12 +1,12 @@
-
-

Load Data Once

- If you define the url property, then each type a new page is opened it will submit a request to the server for the new portion - of the data. However, if you use the load() method, it will load data from the URL, but only once. The grid will think it has local - data source and will not send any more server side requests. -
-
-
+
+

Load Data Once

+ If you define the url property, then each type a new page is opened it will submit a request to the server for the new portion + of the data. However, if you use the load() method, it will load data from the URL, but only once. The grid will think it has local + data source and will not send any more server side requests. +
+
+
@@ -15,16 +15,16 @@

Load Data Once

@@ -33,17 +33,17 @@

Load Data Once

diff --git a/demos/examples/grid-6.html b/demos/examples/grid-6.html index 21c6fc976..610072aac 100644 --- a/demos/examples/grid-6.html +++ b/demos/examples/grid-6.html @@ -1,15 +1,15 @@
-
-

Single or Multiple Selection

- By default user can select multiple records if he holds ctrl (command on mak) key and clicks on multiple records. User can - also use shift key to select a range of records. If you set show.selectColumn = true, then the user will see an additional column - with checkboxes that indicate if the record is selected. -

- If you set multiSelect = false, then user will only be able to select one record at a time. The grid below allow you to select only - one record. -
-
-
+
+

Single or Multiple Selection

+ By default user can select multiple records if he holds ctrl (command on mak) key and clicks on multiple records. User can + also use shift key to select a range of records. If you set show.selectColumn = true, then the user will see an additional column + with checkboxes that indicate if the record is selected. +

+ If you set multiSelect = false, then user will only be able to select one record at a time. The grid below allow you to select only + one record. +
+
+
@@ -21,27 +21,27 @@

Single or Multiple Selection

diff --git a/demos/examples/grid-7.html b/demos/examples/grid-7.html index 044bb60ea..91afbb7db 100644 --- a/demos/examples/grid-7.html +++ b/demos/examples/grid-7.html @@ -1,11 +1,11 @@
-
-

Sub Grids

- It is easy to add grid as a subgrid. All you need to do is to add event onExpand and when it fires insert new grid inside the - container the grid creates for you. In the same way you can make any other HTML open up on expand. -
-
-
+
+

Sub Grids

+ It is easy to add grid as a subgrid. All you need to do is to add event onExpand and when it fires insert new grid inside the + container the grid creates for you. In the same way you can make any other HTML open up on expand. +
+
+
@@ -14,47 +14,47 @@

Sub Grids

diff --git a/demos/examples/grid-8.html b/demos/examples/grid-8.html index dd000ef10..813d7883e 100644 --- a/demos/examples/grid-8.html +++ b/demos/examples/grid-8.html @@ -1,11 +1,11 @@
-
-

Show/Hide Columns

- There are a number of useful functions to work with columns. You can add, remove, show, hide, find columns with these methods. The - grid below shows an example how to toggle columns. -
-
-
+
+

Show/Hide Columns

+ There are a number of useful functions to work with columns. You can add, remove, show, hide, find columns with these methods. The + grid below shows an example how to toggle columns. +
+
+
@@ -17,25 +17,25 @@

Show/Hide Columns

diff --git a/demos/examples/grid-9.html b/demos/examples/grid-9.html index 51f48d0dc..ff44cbfea 100644 --- a/demos/examples/grid-9.html +++ b/demos/examples/grid-9.html @@ -1,12 +1,12 @@
-
-

Add/Remove Record

- There are several ways to add and remove records. You can always change grid.records array and then refresh the - grid by calling grid.refresh() method. Or you can also use grid.add() method as - it is show in the example below. -
-
-
+
+

Add/Remove Record

+ There are several ways to add and remove records. You can always change grid.records array and then refresh the + grid by calling grid.refresh() method. Or you can also use grid.add() method as + it is show in the example below. +
+
+
@@ -18,70 +18,70 @@

Add/Remove Record

diff --git a/demos/examples/layout-1.html b/demos/examples/layout-1.html index d64bdf34d..178647ffa 100644 --- a/demos/examples/layout-1.html +++ b/demos/examples/layout-1.html @@ -1,13 +1,13 @@
-
-

Simple Layout

- This simple layout below has 3 panels, none of them are resizable. Layouts can be completely transparent, however, in the - example below I have define border and background to see its structure. - The layout listens window resize event and resizes itself when window is resized. Try to resize the window and - see how layout picks up the new size. -
-
-
+
+

Simple Layout

+ This simple layout below has 3 panels, none of them are resizable. Layouts can be completely transparent, however, in the + example below I have define border and background to see its structure. + The layout listens window resize event and resizes itself when window is resized. Try to resize the window and + see how layout picks up the new size. +
+
+
@@ -16,14 +16,14 @@

Simple Layout

diff --git a/demos/examples/layout-10.html b/demos/examples/layout-10.html index 7bb7103fc..ae351168b 100644 --- a/demos/examples/layout-10.html +++ b/demos/examples/layout-10.html @@ -1,16 +1,16 @@
-
-

Panel with Title

-

- A layout panel may be created with a title. -

- -

- You can dynamically load content into the main panel; this is done so you can observe the overflow behaviour of the panel (scrollbars). -

-
-
-
+
+

Panel with Title

+

+ A layout panel may be created with a title. +

+ +

+ You can dynamically load content into the main panel; this is done so you can observe the overflow behaviour of the panel (scrollbars). +

+
+
+
@@ -26,15 +26,15 @@

Panel with Title

diff --git a/demos/examples/layout-2.html b/demos/examples/layout-2.html index 1211d97d1..68c1eb82b 100644 --- a/demos/examples/layout-2.html +++ b/demos/examples/layout-2.html @@ -1,12 +1,12 @@
-
-

Resizable Panels

- Any panel can be resizable by simply setting resizable property to true. You can defining the size of the panels in pixels or percentage. - If you define an integer as the size, it will apply it in pixels, if you define as a string in the format 'xx%' it - will calculate percentage. -
-
-
+
+

Resizable Panels

+ Any panel can be resizable by simply setting resizable property to true. You can defining the size of the panels in pixels or percentage. + If you define an integer as the size, it will apply it in pixels, if you define as a string in the format 'xx%' it + will calculate percentage. +
+
+
@@ -15,16 +15,16 @@

Resizable Panels

diff --git a/demos/examples/layout-3.html b/demos/examples/layout-3.html index 634e79270..3449bbf07 100644 --- a/demos/examples/layout-3.html +++ b/demos/examples/layout-3.html @@ -1,11 +1,11 @@
-
-

Show/Hide Panels

- A layout may be created with up to 6 panels. The panels can be visible or hidden when they are created, and can be shown or hidden - during run time with animation or without. -
-
-
+
+

Show/Hide Panels

+ A layout may be created with up to 6 panels. The panels can be visible or hidden when they are created, and can be shown or hidden + during run time with animation or without. +
+
+
@@ -21,18 +21,18 @@

Show/Hide Panels

diff --git a/demos/examples/layout-4.html b/demos/examples/layout-4.html index e975c3256..30dc56a41 100644 --- a/demos/examples/layout-4.html +++ b/demos/examples/layout-4.html @@ -1,12 +1,12 @@
-
-

Load Content

- You can set (or get) the content of the panel with the .content() method. You can also load content from external url with .load() - method. If the content property of the panel is an object and has .render(box) method, it will be called to render the content when - needed. When layout is resized, it will call .resize(width, height) of all panels where content is an object. -
-
-
+
+

Load Content

+ You can set (or get) the content of the panel with the .content() method. You can also load content from external url with .load() + method. If the content property of the panel is an object and has .render(box) method, it will be called to render the content when + needed. When layout is resized, it will call .resize(width, height) of all panels where content is an object. +
+
+
@@ -28,15 +28,15 @@

Load Content

diff --git a/demos/examples/layout-5.html b/demos/examples/layout-5.html index 09684b677..f4939f642 100644 --- a/demos/examples/layout-5.html +++ b/demos/examples/layout-5.html @@ -1,11 +1,11 @@
-
-

Transitions

- It is very easy to add a nice transition when setting or loading content. All transition are implemented in w2utils library, which - is called to do the actual transition. The layout below is exactly like the previous one, but with added transition. -
-
-
+
+

Transitions

+ It is very easy to add a nice transition when setting or loading content. All transition are implemented in w2utils library, which + is called to do the actual transition. The layout below is exactly like the previous one, but with added transition. +
+
+
@@ -28,14 +28,14 @@

Transitions

diff --git a/demos/examples/layout-6.html b/demos/examples/layout-6.html index fd66fd438..c68d6f800 100644 --- a/demos/examples/layout-6.html +++ b/demos/examples/layout-6.html @@ -1,11 +1,11 @@
-
-

Event Listeners

- As with any w2ui widget, the panel follows common event flow. In example below you can see how to listen to all events dispatched to - the layout. -
-
-
+
+

Event Listeners

+ As with any w2ui widget, the panel follows common event flow. In example below you can see how to listen to all events dispatched to + the layout. +
+
+
@@ -26,24 +26,24 @@

Event Listeners

diff --git a/demos/examples/layout-7.html b/demos/examples/layout-7.html index 392308edd..e88982852 100644 --- a/demos/examples/layout-7.html +++ b/demos/examples/layout-7.html @@ -1,11 +1,11 @@
-
-

Nested Layouts

- If 6 panels are not enough for you, you can create nested layouts by assigning a layout to a panel. There is no limit how deep - you can go, but be reasonable :). In the example below the nested layout is yellow. -
-
-
+
+

Nested Layouts

+ If 6 panels are not enough for you, you can create nested layouts by assigning a layout to a panel. There is no limit how deep + you can go, but be reasonable :). In the example below the nested layout is yellow. +
+
+
@@ -31,31 +31,31 @@

Nested Layouts

diff --git a/demos/examples/layout-8.html b/demos/examples/layout-8.html index c0ee388e3..3fd0398e3 100644 --- a/demos/examples/layout-8.html +++ b/demos/examples/layout-8.html @@ -1,18 +1,18 @@
-
-

Panel with Tabs

-

- A layout panel may be created with tabs. It uses w2tabs object, therefore, you can use anything w2tabs support. There - is no need to define a name of the tabs, because it will be overwritten with layout.name + '_tabs'. It will also add tabs.owner - attribute that is a reference to the layout. -

- -

- You can dynamically load content into the main panel; this is done so you can observe the overflow behaviour of the panel (scrollbars). -

-
-
-
+
+

Panel with Tabs

+

+ A layout panel may be created with tabs. It uses w2tabs object, therefore, you can use anything w2tabs support. There + is no need to define a name of the tabs, because it will be overwritten with layout.name + '_tabs'. It will also add tabs.owner + attribute that is a reference to the layout. +

+ +

+ You can dynamically load content into the main panel; this is done so you can observe the overflow behaviour of the panel (scrollbars). +

+
+
+
@@ -28,27 +28,27 @@

Panel with Tabs

diff --git a/demos/examples/layout-9.html b/demos/examples/layout-9.html index 9ea3079dc..a334b3220 100644 --- a/demos/examples/layout-9.html +++ b/demos/examples/layout-9.html @@ -1,18 +1,18 @@
-
-

Panel with Toolbar

-

- A layout panel may be created with a toolbar. It uses w2toolbar object, therefore, you can use anything w2toolbar support. There - is no need to define a name of the toolbar, because it will be overwritten with layout.name + '_toolbar'. It will also add toolbar.owner - attribute that is a reference to the layout. -

- -

- You can dynamically load content into the main panel; this is done so you can observe the overflow behaviour of the panel (scrollbars). -

-
-
-
+
+

Panel with Toolbar

+

+ A layout panel may be created with a toolbar. It uses w2toolbar object, therefore, you can use anything w2toolbar support. There + is no need to define a name of the toolbar, because it will be overwritten with layout.name + '_toolbar'. It will also add toolbar.owner + attribute that is a reference to the layout. +

+ +

+ You can dynamically load content into the main panel; this is done so you can observe the overflow behaviour of the panel (scrollbars). +

+
+
+
@@ -20,35 +20,35 @@

Panel with Toolbar

diff --git a/demos/examples/listview-1.html b/demos/examples/listview-1.html index 6306a1b8e..abfdc08f4 100644 --- a/demos/examples/listview-1.html +++ b/demos/examples/listview-1.html @@ -1,10 +1,10 @@
-
-

Simple ListView

- Below is an example of how to use ListView. -
-
-
+
+

Simple ListView

+ Below is an example of how to use ListView. +
+
+
@@ -13,20 +13,20 @@

Simple ListView

diff --git a/demos/examples/listview-2.html b/demos/examples/listview-2.html index f77f33be6..9e673658a 100644 --- a/demos/examples/listview-2.html +++ b/demos/examples/listview-2.html @@ -1,10 +1,10 @@
-
-

Different view types

- Listview can represent items in different modes. An example below show you how to do that. -
-
-
+
+

Different view types

+ Listview can represent items in different modes. An example below show you how to do that. +
+
+
@@ -19,20 +19,20 @@

Different view types

diff --git a/demos/examples/listview-3.html b/demos/examples/listview-3.html index 0a669c112..6d6db5046 100644 --- a/demos/examples/listview-3.html +++ b/demos/examples/listview-3.html @@ -1,10 +1,10 @@
-
-

Selecting items

+
+

Selecting items

An example below show you how to select/deselect items by it's id. -
-
-
+
+
+
@@ -18,21 +18,21 @@

Selecting items

diff --git a/demos/examples/listview-4.html b/demos/examples/listview-4.html index c73155f11..1c533561a 100644 --- a/demos/examples/listview-4.html +++ b/demos/examples/listview-4.html @@ -1,10 +1,10 @@
-
-

Add/Remove Items

- You can add/remove items. -
-
-
+
+

Add/Remove Items

+ You can add/remove items. +
+
+
@@ -20,47 +20,47 @@

Add/Remove Items

diff --git a/demos/examples/listview-5.html b/demos/examples/listview-5.html index 25a51fc31..ec6c50513 100644 --- a/demos/examples/listview-5.html +++ b/demos/examples/listview-5.html @@ -1,10 +1,10 @@
-
-

Table view type

- Listview can represent items in table view. An example below show you how to customize columns. -
-
-
+
+

Table view type

+ Listview can represent items in table view. An example below show you how to customize columns. +
+
+
@@ -13,26 +13,26 @@

Table view type

diff --git a/demos/examples/popup-1.html b/demos/examples/popup-1.html index eb6d1aff6..587c6154e 100644 --- a/demos/examples/popup-1.html +++ b/demos/examples/popup-1.html @@ -1,12 +1,12 @@
-
-

Simple Popup

- You can open only one popup at a time. The popup can be either modal or not. If popup is modal, then it can only be closed if user - clicks the cross button or as a developer you can provide a button that closes the popup. If popup is not modal, then clicking - outside of the popup will close it. -
-
-
+
+

Simple Popup

+ You can open only one popup at a time. The popup can be either modal or not. If popup is modal, then it can only be closed if user + clicks the cross button or as a developer you can provide a button that closes the popup. If popup is not modal, then clicking + outside of the popup will close it. +
+
+
@@ -15,9 +15,9 @@

Simple Popup

diff --git a/demos/examples/popup-2.html b/demos/examples/popup-2.html index 09e8662a8..7fc8eb1b6 100644 --- a/demos/examples/popup-2.html +++ b/demos/examples/popup-2.html @@ -1,10 +1,10 @@
-
-

More Popup Options

- Below is another popup but with more options. You do not need to specify all the options, but only the ones needed. -
-
-
+
+

More Popup Options

+ Below is another popup but with more options. You do not need to specify all the options, but only the ones needed. +
+
+
@@ -13,26 +13,26 @@

More Popup Options

diff --git a/demos/examples/popup-3.html b/demos/examples/popup-3.html index e14f60597..949894b47 100644 --- a/demos/examples/popup-3.html +++ b/demos/examples/popup-3.html @@ -1,11 +1,11 @@
-
-

Popup Elements

- Each popup consists of 3 elements: title, body, and buttons. Each panel can contain any HTML. You can also have two buttons in the - title: max and close. -
-
-
+
+

Popup Elements

+ Each popup consists of 3 elements: title, body, and buttons. Each panel can contain any HTML. You can also have two buttons in the + title: max and close. +
+
+
@@ -15,16 +15,16 @@

Popup Elements

diff --git a/demos/examples/popup-4.html b/demos/examples/popup-4.html index 8f8a2fe14..6f6bf1059 100644 --- a/demos/examples/popup-4.html +++ b/demos/examples/popup-4.html @@ -1,16 +1,16 @@
-
-

Based on Markup

- You can load popup completely from a markup. It will read title, body, buttons, as well as width and height of the new - popup content. See example below how it works. The div that contains markup should have style="display: none", so it would not - be visible on the page, if you include it into the same page. -
- Use rel=title, rel=body, rel=buttons to defined popup parts and style="width: XXpx; height: XXpx; overflow: AA;" - of the initial div to define size and overflow. - outside of the popup will close it. -
-
-
+
+

Based on Markup

+ You can load popup completely from a markup. It will read title, body, buttons, as well as width and height of the new + popup content. See example below how it works. The div that contains markup should have style="display: none", so it would not + be visible on the page, if you include it into the same page. +
+ Use rel=title, rel=body, rel=buttons to defined popup parts and style="width: XXpx; height: XXpx; overflow: AA;" + of the initial div to define size and overflow. + outside of the popup will close it. +
+
+
@@ -18,39 +18,39 @@

Based on Markup

diff --git a/demos/examples/popup-5.html b/demos/examples/popup-5.html index 08a80242b..1a4e645ac 100644 --- a/demos/examples/popup-5.html +++ b/demos/examples/popup-5.html @@ -1,11 +1,11 @@
-
-

Load Content

- There are three ways popup can be open: from JavaScript, from Markup, loaded from a file. The example below shows how content can - be loaded from HTML file on the server. -
-
-
+
+

Load Content

+ There are three ways popup can be open: from JavaScript, from Markup, loaded from a file. The example below shows how content can + be loaded from HTML file on the server. +
+
+
diff --git a/demos/examples/popup-6.html b/demos/examples/popup-6.html index b19f8b3f9..bca34a025 100644 --- a/demos/examples/popup-6.html +++ b/demos/examples/popup-6.html @@ -1,11 +1,11 @@
-
-

Transitions

- Anytime you load new content, regardless the method, you can specify a transition type. If transition is not specified, then - the default will be used. All transitions are done with w2utils. -
-
-
+
+

Transitions

+ Anytime you load new content, regardless the method, you can specify a transition type. If transition is not specified, then + the default will be used. All transitions are done with w2utils. +
+
+
diff --git a/demos/examples/popup-7.html b/demos/examples/popup-7.html index 87d70926e..ad3cdfcd5 100644 --- a/demos/examples/popup-7.html +++ b/demos/examples/popup-7.html @@ -1,11 +1,11 @@
-
-

Slide a Message

- The w2ui library allows to open single popup (because of my strong UX convictions). However, in some cases you need to show - addition info without closing the popup. This is where sliding a message from the top comes in. -
-
-
+
+

Slide a Message

+ The w2ui library allows to open single popup (because of my strong UX convictions). However, in some cases you need to show + addition info without closing the popup. This is where sliding a message from the top comes in. +
+
+
@@ -14,22 +14,22 @@

Slide a Message

diff --git a/demos/examples/popup-8.html b/demos/examples/popup-8.html index 251c69b4f..1ae2941e5 100644 --- a/demos/examples/popup-8.html +++ b/demos/examples/popup-8.html @@ -1,10 +1,10 @@
-
-

Dialogs

- There are 2 standard dialogs that you can use out of the box: w2alert() and w2confirm(); -
-
-
+
+

Dialogs

+ There are 2 standard dialogs that you can use out of the box: w2alert() and w2confirm(); +
+
+
diff --git a/demos/examples/sidebar-1.html b/demos/examples/sidebar-1.html index 15226c56a..f9ac8c561 100644 --- a/demos/examples/sidebar-1.html +++ b/demos/examples/sidebar-1.html @@ -1,11 +1,11 @@
-
-

Simple Sidebar

- The w2sidebar object provides a quick solution for a vertical menu. The example below demonstrates a sample sidebar with - multiple items. Some of the items are nested. The very same object can be used to create tree structures. -
-
-
+
+

Simple Sidebar

+ The w2sidebar object provides a quick solution for a vertical menu. The example below demonstrates a sample sidebar with + multiple items. Some of the items are nested. The very same object can be used to create tree structures. +
+
+
@@ -14,27 +14,27 @@

Simple Sidebar

diff --git a/demos/examples/sidebar-2.html b/demos/examples/sidebar-2.html index 804dfde0a..1a5684ae0 100644 --- a/demos/examples/sidebar-2.html +++ b/demos/examples/sidebar-2.html @@ -1,56 +1,56 @@
-
-

Add/Remove Items

- You can add/remove items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that - needs rebuilding. The example below demonstrates this feature. -
-
-
+
+

Add/Remove Items

+ You can add/remove items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that + needs rebuilding. The example below demonstrates this feature. +
+
+
- - - + + +
diff --git a/demos/examples/sidebar-3.html b/demos/examples/sidebar-3.html index 7852cf294..681c0a429 100644 --- a/demos/examples/sidebar-3.html +++ b/demos/examples/sidebar-3.html @@ -1,35 +1,35 @@
-
-

Show/Hide Items

- You can show/hide items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that - needs rebuilding. The example below demonstrates this feature. -
-
-
+
+

Show/Hide Items

+ You can show/hide items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that + needs rebuilding. The example below demonstrates this feature. +
+
+
- - + +
diff --git a/demos/examples/sidebar-4.html b/demos/examples/sidebar-4.html index 25fde1cf1..1837e9296 100644 --- a/demos/examples/sidebar-4.html +++ b/demos/examples/sidebar-4.html @@ -1,34 +1,34 @@
-
-

Enable/Disable Items

- You can enable/disable items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that - needs rebuilding. The example below demonstrates this feature. -
-
-
+
+

Enable/Disable Items

+ You can enable/disable items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that + needs rebuilding. The example below demonstrates this feature. +
+
+
- - + +
diff --git a/demos/examples/sidebar-5.html b/demos/examples/sidebar-5.html index cb71ce7f2..52b2a80aa 100644 --- a/demos/examples/sidebar-5.html +++ b/demos/examples/sidebar-5.html @@ -1,34 +1,34 @@
-
-

Expand/Collapse Items

- You can expand/collapse items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that - needs rebuilding. The example below demonstrates this feature. -
-
-
+
+

Expand/Collapse Items

+ You can expand/collapse items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that + needs rebuilding. The example below demonstrates this feature. +
+
+
- - + +
diff --git a/demos/examples/sidebar-6.html b/demos/examples/sidebar-6.html index 33903b87a..61a40298a 100644 --- a/demos/examples/sidebar-6.html +++ b/demos/examples/sidebar-6.html @@ -1,35 +1,35 @@
-
-

Select/Unselect

- You can select/unselect items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that - needs rebuilding. The example below demonstrates this feature. -
-
-
+
+

Select/Unselect

+ You can select/unselect items to the sidebar during the run time. The library will automatically refresh the portion of the sidebar that + needs rebuilding. The example below demonstrates this feature. +
+
+
- - - + + +
diff --git a/demos/examples/sidebar-7.html b/demos/examples/sidebar-7.html index 1251f442c..347d20d9f 100644 --- a/demos/examples/sidebar-7.html +++ b/demos/examples/sidebar-7.html @@ -1,11 +1,11 @@
-
-

Events

- All important events are supported. In the example below I added an event listener for all events. You can see what events - are being sent in JavaScript console. -
-
-
+
+

Events

+ All important events are supported. In the example below I added an event listener for all events. You can see what events + are being sent in JavaScript console. +
+
+
@@ -14,26 +14,26 @@

Events

diff --git a/demos/examples/sidebar-8.html b/demos/examples/sidebar-8.html index 013fe29bb..884bebe10 100644 --- a/demos/examples/sidebar-8.html +++ b/demos/examples/sidebar-8.html @@ -1,10 +1,10 @@
-
-

Top & Bottom HTML

- You can add top and/or bottom HTML that will alwayst stay there. You can expand columns and if -
-
-
+
+

Top & Bottom HTML

+ You can add top and/or bottom HTML that will alwayst stay there. You can expand columns and if +
+
+
@@ -13,30 +13,30 @@

Top & Bottom HTML

diff --git a/demos/examples/tabs-1.html b/demos/examples/tabs-1.html index ee5e899ca..93ae5e121 100644 --- a/demos/examples/tabs-1.html +++ b/demos/examples/tabs-1.html @@ -1,10 +1,10 @@
-
-

Simple Tabs

- Below is an example of how to use tabs. -
-
-
+
+

Simple Tabs

+ Below is an example of how to use tabs. +
+
+
@@ -14,18 +14,18 @@

Simple Tabs

diff --git a/demos/examples/tabs-2.html b/demos/examples/tabs-2.html index 0b1a2e4bd..65e23f2a1 100644 --- a/demos/examples/tabs-2.html +++ b/demos/examples/tabs-2.html @@ -1,10 +1,10 @@
-
-

Set a Tab Active

- As a developer often you need to be able to switch to a tab. An example below show you how to do that. -
-
-
+
+

Set a Tab Active

+ As a developer often you need to be able to switch to a tab. An example below show you how to do that. +
+
+
@@ -16,15 +16,15 @@

Set a Tab Active

diff --git a/demos/examples/tabs-3.html b/demos/examples/tabs-3.html index fc7d522c5..240bafd80 100644 --- a/demos/examples/tabs-3.html +++ b/demos/examples/tabs-3.html @@ -1,10 +1,10 @@
-
-

Closable Tabs

- To make any tab closable, all you need to do is to set closable property to true. -
-
-
+
+

Closable Tabs

+ To make any tab closable, all you need to do is to set closable property to true. +
+
+
@@ -13,19 +13,19 @@

Closable Tabs

diff --git a/demos/examples/tabs-4.html b/demos/examples/tabs-4.html index 1246897ed..8da42eeb9 100644 --- a/demos/examples/tabs-4.html +++ b/demos/examples/tabs-4.html @@ -1,10 +1,10 @@
-
-

Add/Remove Tas

- You can add remove tabs quickly or with animation. -
-
-
+
+

Add/Remove Tas

+ You can add remove tabs quickly or with animation. +
+
+
@@ -20,47 +20,47 @@

Add/Remove Tas

diff --git a/demos/examples/tabs-5.html b/demos/examples/tabs-5.html index 3c61596a4..269645816 100644 --- a/demos/examples/tabs-5.html +++ b/demos/examples/tabs-5.html @@ -1,10 +1,10 @@
-
-

Enable/Disable Tabs

- It is easy to enable and disabled tabs -
-
-
+
+

Enable/Disable Tabs

+ It is easy to enable and disabled tabs +
+
+
@@ -16,15 +16,15 @@

Enable/Disable Tabs

diff --git a/demos/examples/tabs-6.html b/demos/examples/tabs-6.html index 4c4d34de4..398190fee 100644 --- a/demos/examples/tabs-6.html +++ b/demos/examples/tabs-6.html @@ -1,10 +1,10 @@
-
-

Show/Hide Tabs

- It is easy to show and hide tabs -
-
-
+
+

Show/Hide Tabs

+ It is easy to show and hide tabs +
+
+
@@ -15,16 +15,16 @@

Show/Hide Tabs

diff --git a/demos/examples/toolbar-1.html b/demos/examples/toolbar-1.html index 1e2161459..f697bebd1 100644 --- a/demos/examples/toolbar-1.html +++ b/demos/examples/toolbar-1.html @@ -1,11 +1,11 @@
-
-

Simple Toolbar

- The example below demonstrates how to create toolbars. The toolbar can hold multiple items and supports sprite icons or - iconic fonts. You can have both images and icon fonts in the same toolbar. For the click event info, see the console. -
-
-
+
+

Simple Toolbar

+ The example below demonstrates how to create toolbars. The toolbar can hold multiple items and supports sprite icons or + iconic fonts. You can have both images and icon fonts in the same toolbar. For the click event info, see the console. +
+
+
@@ -13,19 +13,19 @@

Simple Toolbar

diff --git a/demos/examples/toolbar-2.html b/demos/examples/toolbar-2.html index 63be776e6..6cba1b844 100644 --- a/demos/examples/toolbar-2.html +++ b/demos/examples/toolbar-2.html @@ -1,22 +1,22 @@
-
-

Advanced Toolbar

- There are 7 types of items that can be created in the toolbar: -
    -
  • button
  • -
  • radio button
  • -
  • check button
  • -
  • html item
  • -
  • drop menu
  • -
  • drop html
  • -
  • break
  • -
  • spacer
  • -
- Below you can see a toolbar with all types of items. This demo also shows how to add simple event listener to listen to all - events. -
-
-
+
+

Advanced Toolbar

+ There are 7 types of items that can be created in the toolbar: +
    +
  • button
  • +
  • radio button
  • +
  • check button
  • +
  • html item
  • +
  • drop menu
  • +
  • drop html
  • +
  • break
  • +
  • spacer
  • +
+ Below you can see a toolbar with all types of items. This demo also shows how to add simple event listener to listen to all + events. +
+
+
@@ -25,35 +25,35 @@

Advanced Toolbar

diff --git a/demos/examples/toolbar-3.html b/demos/examples/toolbar-3.html index 3b5e9e9b2..ed06bbffa 100644 --- a/demos/examples/toolbar-3.html +++ b/demos/examples/toolbar-3.html @@ -1,10 +1,10 @@
-
-

Add/Remove Buttons

- It is easy to add and remove buttons during the run time. The example below demonstrates how to do this. -
-
-
+
+

Add/Remove Buttons

+ It is easy to add and remove buttons during the run time. The example below demonstrates how to do this. +
+
+
@@ -13,33 +13,33 @@

Add/Remove Buttons

diff --git a/demos/examples/toolbar-4.html b/demos/examples/toolbar-4.html index ecd4cd8ac..5371f5d46 100644 --- a/demos/examples/toolbar-4.html +++ b/demos/examples/toolbar-4.html @@ -1,10 +1,10 @@
-
-

Show/Hide Buttons

- It is easy to show and hide buttons during the run time. The example below demonstrates how to do this. -
-
-
+
+

Show/Hide Buttons

+ It is easy to show and hide buttons during the run time. The example below demonstrates how to do this. +
+
+
@@ -13,19 +13,19 @@

Show/Hide Buttons

diff --git a/demos/examples/toolbar-5.html b/demos/examples/toolbar-5.html index 79788ce7a..11b318a47 100644 --- a/demos/examples/toolbar-5.html +++ b/demos/examples/toolbar-5.html @@ -1,10 +1,10 @@
-
-

Enable/Disable Buttons

- It is easy to enable and disable buttons during the run time. The example below demonstrates how to do this. -
-
-
+
+

Enable/Disable Buttons

+ It is easy to enable and disable buttons during the run time. The example below demonstrates how to do this. +
+
+
@@ -13,19 +13,19 @@

Enable/Disable Buttons

diff --git a/demos/examples/utils-1.html b/demos/examples/utils-1.html index 3521c876d..fbed8f10d 100644 --- a/demos/examples/utils-1.html +++ b/demos/examples/utils-1.html @@ -1,11 +1,11 @@
-
-

Validation

- A number of validation tools are provided by w2utils. Type anything in the field below to see validation at work. Try integers, floats, - money, dates, emails. -
-
-
+
+

Validation

+ A number of validation tools are provided by w2utils. Type anything in the field below to see validation at work. Try integers, floats, + money, dates, emails. +
+
+
@@ -25,20 +25,20 @@

Validation

diff --git a/demos/examples/utils-2.html b/demos/examples/utils-2.html index e729ff7ff..8b0bd90f4 100644 --- a/demos/examples/utils-2.html +++ b/demos/examples/utils-2.html @@ -1,16 +1,16 @@
-
-

Base64 Encoding and Decoding

- All server side languages provide base64 encoding and decoding functionality, but not JavaScript. You can use w2utils for all your - base64 needs. -
-
-
+
+

Base64 Encoding and Decoding

+ All server side languages provide base64 encoding and decoding functionality, but not JavaScript. You can use w2utils for all your + base64 needs. +
+
+


diff --git a/demos/examples/utils-3.html b/demos/examples/utils-3.html index fa2231977..08bc77294 100644 --- a/demos/examples/utils-3.html +++ b/demos/examples/utils-3.html @@ -1,69 +1,69 @@
-
-

Transitions

- If you have 2 divs with absolute positioning, you can transition them nicely. -
-
-
+
+

Transitions

+ If you have 2 divs with absolute positioning, you can transition them nicely. +
+
+
-
- This this first div. It jast has some text as example. This box does not have any other elements then some text. - This this first div. It jast has some text as example. This box does not have any other elements then some text. - This this first div. It jast has some text as example. This box does not have any other elements then some text. - This this first div. It jast has some text as example. This box does not have any other elements then some text. -
- +
+ This this first div. It jast has some text as example. This box does not have any other elements then some text. + This this first div. It jast has some text as example. This box does not have any other elements then some text. + This this first div. It jast has some text as example. This box does not have any other elements then some text. + This this first div. It jast has some text as example. This box does not have any other elements then some text. +
+


- + diff --git a/demos/examples/utils-4.html b/demos/examples/utils-4.html index 077bfa05f..29de90a6f 100644 --- a/demos/examples/utils-4.html +++ b/demos/examples/utils-4.html @@ -1,11 +1,11 @@
-
-

Overlays

- If you need to attach a short one-line message for an element or an input control - user $().w2tag(), if you need to attach - a larger multi-line message - use $().w2overlay(). The example below demonstrates how to use these functions. -
-
-
+
+

Overlays

+ If you need to attach a short one-line message for an element or an input control - user $().w2tag(), if you need to attach + a larger multi-line message - use $().w2overlay(). The example below demonstrates how to use these functions. +
+
+
@@ -20,8 +20,8 @@

Overlays

diff --git a/demos/index.css b/demos/index.css index 4e26c9e11..8727920f1 100644 --- a/demos/index.css +++ b/demos/index.css @@ -1,122 +1,122 @@ * { - margin: 0px; - padding: 0px; - box-sizing: border-box; + margin: 0px; + padding: 0px; + box-sizing: border-box; } body { - overflow: hidden; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; } h1 { - margin: 15px 0px; - font-size: 20px; + margin: 15px 0px; + font-size: 20px; } h2 { - margin: 8px 0px; - font-size: 13px; + margin: 8px 0px; + font-size: 13px; } ul { - margin: 10px 0px 10px 40px; + margin: 10px 0px 10px 40px; } p + p { - margin-top: 1em; + margin-top: 1em; } #main_layout { - position: absolute; - width: 100%; - height: 100%; + position: absolute; + width: 100%; + height: 100%; } #example_title { - margin-bottom: 20px; + margin-bottom: 20px; } #example_view { - margin-bottom: 30px; + margin-bottom: 30px; } .content { - padding: 10px; - line-height: 150%; + padding: 10px; + line-height: 150%; } .preview { - margin-bottom: 10px; - width: 100%; - border: 0px; - background-color: #efefef; - line-height: 150%; + margin-bottom: 10px; + width: 100%; + border: 0px; + background-color: #efefef; + line-height: 150%; } .btn-source { - text-decoration: none; - display: inline-block; - padding: 3px 12px; - font-size: 13px; - font-weight: normal; - font-family: verdana; - text-align: center; - white-space: nowrap; - cursor: pointer; - border: 1px solid transparent; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - color: #777; - background-color: #F5F5F5; - border-color: #D1D1D1; - text-shadow: 0px 1px 1px #FFF; + text-decoration: none; + display: inline-block; + padding: 3px 12px; + font-size: 13px; + font-weight: normal; + font-family: verdana; + text-align: center; + white-space: nowrap; + cursor: pointer; + border: 1px solid transparent; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + color: #777; + background-color: #F5F5F5; + border-color: #D1D1D1; + text-shadow: 0px 1px 1px #FFF; } .btn-source:hover { - color: #333; - background-color: #EBEBEB; - border-color: #aaa; - text-shadow: 0px 1px 1px #FFF; + color: #333; + background-color: #EBEBEB; + border-color: #aaa; + text-shadow: 0px 1px 1px #FFF; } /* CODE MIRROR */ .CodeMirror { - font-size: 12px; - margin-top: 10px; - margin-bottom: 20px; - border: 1px solid #ddd; - border-radius: 2px; + font-size: 12px; + margin-top: 10px; + margin-bottom: 20px; + border: 1px solid #ddd; + border-radius: 2px; } .CodeMirror * { - box-sizing: content-box; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; } .CodeMirror-lines { - line-height: 150%; - background-color: #fcfcfc; + line-height: 150%; + background-color: #fcfcfc; } .CodeMirror-code > div:nth-child(odd) { - background-color: #fff; + background-color: #fff; } /* ------------ */ table.list { - margin: 20px 0px; - border-collapse: collapse; + margin: 20px 0px; + border-collapse: collapse; } table.list td { - border: 1px solid #d1d1d1; - padding: 3px 10px !important; + border: 1px solid #d1d1d1; + padding: 3px 10px !important; } diff --git a/demos/index.html b/demos/index.html index 07573751e..de6768e09 100644 --- a/demos/index.html +++ b/demos/index.html @@ -1,17 +1,17 @@ - w2ui Demos - - - - - - - - + w2ui Demos + + + + + + + + -
+
\ No newline at end of file diff --git a/demos/index.js b/demos/index.js index 907a8a3f6..027334e9a 100644 --- a/demos/index.js +++ b/demos/index.js @@ -1,334 +1,334 @@ $(function () { - // init layout - var main_layout = $('#main_layout').w2layout({ - name: 'main_layout', - panels: [ - { type: 'top', size: 45, style: 'border: 0px; border-bottom: 1px solid silver; background-color: #fff; color: #555;', overflow: 'hidden'}, - { type: 'left', size: 240, resizable: true, style: 'border-right: 1px solid silver;' }, - { type: 'main', style: 'background-color: white;' } - ] - }); - w2ui['main_layout'].content('top', '
W2UI 1.3 Demos
'); - // w2ui['main_layout'].content('top', '
'+ - // 'Theme: '+ - // '   '+ - // 'Locale: '+ - // ''+ - // '
'); - // init sidebar - w2ui['main_layout'].content('left', $().w2sidebar({ - name: 'demo-sidebar', - img: null, - nodes: [ - { id: 'combo', text: 'Combinations', img: 'icon-folder', group1: true, - nodes: [ - { id: 'combo-1', text: 'Sidebar & Grid', icon: 'fa-star-empty' }, - { id: 'combo-2', text: 'Grid & Edit', icon: 'fa-star-empty' }, - { id: 'combo-3', text: 'Spreadsheet Like Grid', icon: 'fa-star-empty' }, - { id: 'combo-4', text: 'Buffered Scroll', icon: 'fa-star-empty' }, - { id: 'combo-9', text: 'Infinite Scroll', icon: 'fa-star-empty' }, - { id: 'combo-5', text: 'Tabs With Content', icon: 'fa-star-empty' }, - { id: 'combo-6', text: 'Layout & Dynamic Tabs', icon: 'fa-star-empty' }, - { id: 'combo-7', text: 'Popup & Grid', icon: 'fa-star-empty' }, - { id: 'combo-8', text: 'Popup & Layout', icon: 'fa-star-empty' }, - ] - }, - { id: 'layout', text: 'Layout', img: 'icon-folder', group1: true, - nodes: [ - { id: 'layout-1', text: 'Simple Layout', icon: 'fa-columns' }, - { id: 'layout-2', text: 'Resizable Panels', icon: 'fa-columns' }, - { id: 'layout-3', text: 'Show/Hide Panels', icon: 'fa-columns' }, - { id: 'layout-4', text: 'Load Content', icon: 'fa-columns' }, - { id: 'layout-5', text: 'Transitions', icon: 'fa-columns' }, - { id: 'layout-6', text: 'Event Listeners', icon: 'fa-columns' }, - { id: 'layout-7', text: 'Nested Layouts', icon: 'fa-columns' }, - { id: 'layout-8', text: 'Panel With Tabs', icon: 'fa-columns' }, - { id: 'layout-9', text: 'Panel With Toolbar', icon: 'fa-columns' }, - { id: 'layout-10', text: 'Panel With Title', icon: 'fa-columns' } - ] - }, - { id: 'grid', text: 'Grid', img: 'icon-folder', group1: true, - nodes: [ - { id: 'grid-1', text: 'Simple Grid', icon: 'fa-table' }, - { id: 'grid-3', text: 'Grid Elements', icon: 'fa-table' }, - { id: 'grid-2', text: 'Row Formating', icon: 'fa-table' }, - { id: 'grid-23',text: 'Cell Formatting', icon: 'fa-table' }, - { id: 'grid-4', text: 'Data Source', icon: 'fa-table' }, - { id: 'grid-5', text: 'Load Data Once', icon: 'fa-table' }, - { id: 'grid-6', text: 'Single or Multi Select', icon: 'fa-table' }, - { id: 'grid-7', text: 'Sub Grids', icon: 'fa-table' }, - { id: 'grid-8', text: 'Show/Hide Columns', icon: 'fa-table' }, - { id: 'grid-9', text: 'Add/Remove Records', icon: 'fa-table' }, - { id: 'grid-10', text: 'Select/Unselect Records', icon: 'fa-table' }, - { id: 'grid-11', text: 'Fixed/Resisable', icon: 'fa-table' }, - { id: 'grid-12', text: 'Column Sort', icon: 'fa-table' }, - { id: 'grid-13', text: 'Column Groups', icon: 'fa-table' }, - { id: 'grid-14', text: 'Summary Records', icon: 'fa-table' }, - { id: 'grid-15', text: 'Simple Search', icon: 'fa-table' }, - { id: 'grid-16', text: 'Advanced Search', icon: 'fa-table' }, - { id: 'grid-17', text: 'Grid Toolbar', icon: 'fa-table' }, - { id: 'grid-18', text: 'Master -> Detail', icon: 'fa-table' }, - { id: 'grid-19', text: 'Two Grids', icon: 'fa-table' }, - { id: 'grid-20', text: 'Render to a New Box', icon: 'fa-table' }, - { id: 'grid-21', text: 'Inline Editing', icon: 'fa-table' }, - { id: 'grid-22', text: 'Resizable Columns', icon: 'fa-table' }, - { id: 'grid-24', text: 'Lock/Unlock Grid', icon: 'fa-table' }, - { id: 'grid-25', text: 'Re-Order Columns', icon: 'fa-table' }, - //{ id: 'grid-26', text: 'Re-Order records', icon: 'fa-table' }, - //{ id: 'grid-27', text: 'Locked Columns', icon: 'fa-table' } - ] - }, - { id: 'toolbar', text: 'Toolbar', img: 'icon-folder', group1: true, - nodes: [ - { id: 'toolbar-1', text: 'Simple Toolbar', icon: 'fa-hand-up' }, - { id: 'toolbar-2', text: 'Advanced Toolbar', icon: 'fa-hand-up' }, - { id: 'toolbar-3', text: 'Add/Remove Buttons', icon: 'fa-hand-up' }, - { id: 'toolbar-4', text: 'Show/Hide Buttons', icon: 'fa-hand-up' }, - { id: 'toolbar-5', text: 'Enable/Disable Buttons', icon: 'fa-hand-up' } - ] - }, - { id: 'sidebar', text: 'Sidebar', img: 'icon-folder', group1: true, - nodes: [ - { id: 'sidebar-1', text: 'Simple Sidebar', icon: 'fa-hand-left' }, - { id: 'sidebar-2', text: 'Add/Remove', icon: 'fa-hand-left' }, - { id: 'sidebar-3', text: 'Show/Hide', icon: 'fa-hand-left' }, - { id: 'sidebar-4', text: 'Enable/Disable', icon: 'fa-hand-left' }, - { id: 'sidebar-5', text: 'Expand/Collapse', icon: 'fa-hand-left' }, - { id: 'sidebar-6', text: 'Select/Unselect', icon: 'fa-hand-left' }, - { id: 'sidebar-8', text: 'Top & Bottom HTML', icon: 'fa-hand-left' }, - { id: 'sidebar-7', text: 'Events', icon: 'fa-hand-left' } - ] - }, - { id: 'listview', text: 'ListView', img: 'icon-folder', group1: true, - nodes: [ - { id: 'listview-1', text: 'Simple ListView', icon: 'fa-folder-close-alt' }, - { id: 'listview-2', text: 'Different view types', icon: 'fa-folder-close-alt' }, - { id: 'listview-5', text: 'Table view type', icon: 'fa-folder-close-alt' }, - { id: 'listview-3', text: 'Selecting items', icon: 'fa-folder-close-alt' }, - { id: 'listview-4', text: 'Add/Remove items', icon: 'fa-folder-close-alt' } - ] - }, - { id: 'tabs', text: 'Tabs', img: 'icon-folder', group1: true, - nodes: [ - { id: 'tabs-1', text: 'Simple Tabs', icon: 'fa-folder-close-alt' }, - { id: 'tabs-2', text: 'Set a Tab Active', icon: 'fa-folder-close-alt' }, - { id: 'tabs-3', text: 'Closable Tabs', icon: 'fa-folder-close-alt' }, - { id: 'tabs-4', text: 'Add/Remove Tabs', icon: 'fa-folder-close-alt' }, - { id: 'tabs-5', text: 'Enable/Disabled Tabs', icon: 'fa-folder-close-alt' }, - { id: 'tabs-6', text: 'Show/Hide Tabs', icon: 'fa-folder-close-alt' } - ] - }, - { id: 'forms', text: 'Forms', img: 'icon-folder', group1: true, - nodes: [ - { id: 'forms-1', text: 'Simple Form', icon: 'fa-edit' }, - { id: 'forms-2', text: 'Field Types', icon: 'fa-edit' }, - { id: 'forms-3', text: 'Large Form', icon: 'fa-edit' }, - { id: 'forms-4', text: 'Multi Page Form', icon: 'fa-edit' }, - { id: 'forms-5', text: 'Form Tabs', icon: 'fa-edit' }, - { id: 'forms-9', text: 'Form Toolbar', icon: 'fa-edit' }, - { id: 'forms-8', text: 'Form in a Popup', icon: 'fa-edit' }, - { id: 'forms-6', text: 'Events', icon: 'fa-edit' }, - { id: 'forms-7', text: 'Input Controls', icon: 'fa-edit' } - ] - }, - { id: 'popup', text: 'Popup', img: 'icon-folder', group1: true, - nodes: [ - { id: 'popup-1', text: 'Simple Popup', icon: 'fa-list-alt' }, - { id: 'popup-2', text: 'More Options', icon: 'fa-list-alt' }, - { id: 'popup-3', text: 'Popup Elements', icon: 'fa-list-alt' }, - { id: 'popup-4', text: 'Based on Markup', icon: 'fa-list-alt' }, - { id: 'popup-5', text: 'Load Content', icon: 'fa-list-alt' }, - { id: 'popup-6', text: 'Transitions', icon: 'fa-list-alt' }, - { id: 'popup-7', text: 'Slide a Message', icon: 'fa-list-alt' }, - { id: 'popup-8', text: 'Dialogs', icon: 'fa-list-alt' } - ] - }, - { id: 'utils', text: 'Utilities', img: 'icon-folder', group1: true, - nodes: [ - { id: 'utils-1', text: 'Validation', icon: 'fa-star-empty' }, - { id: 'utils-2', text: 'Encoding', icon: 'fa-star-empty' }, - { id: 'utils-3', text: 'Transitions', icon: 'fa-star-empty' }, - { id: 'utils-4', text: 'Overlays', icon: 'fa-star-empty' } - ] - } - ], - onClick: function (event) { - var cmd = event.target; - if (parseInt(cmd.substr(cmd.length-1)) != cmd.substr(cmd.length-1)) return; - var tmp = w2ui['demo-sidebar'].get(cmd); - document.title = tmp.parent.text + ': ' + tmp.text + ' | w2ui'; - // delete previously created items - for (var widget in w2ui) { - var nm = w2ui[widget].name; - if (['main_layout', 'demo-sidebar'].indexOf(nm) == -1) $().w2destroy(nm); - } - // set hash - if (tmp.parent && tmp.parent.id != '') { - var pid = w2ui['demo-sidebar'].get(cmd).parent.id; - document.location.hash = '!'+ pid + '/' + cmd; - } - // load example - $.get('examples/'+ cmd +'.html', function (data) { - var tmp = data.split(''); - if (tmp.length == 1) { - alert('ERROR: cannot parse example.'); - console.log('ERROR: cannot parse example.', data); - return; - } - var html = tmp[1] ? $.trim(tmp[1]) : ''; - var js = tmp[2] ? $.trim(tmp[2]) : ''; - var css = tmp[3] ? $.trim(tmp[3]) : ''; - var json = tmp[4] ? $.trim(tmp[4]) : ''; - js = js.replace(/^]*>/, '').replace(/<\/script>$/, ''); - js = $.trim(js); - css = css.replace(/^]*>/, '').replace(/<\/style>$/, ''); - css = $.trim(css); - json = json.replace(/^]*>/, '').replace(/<\/script>$/, ''); - json = $.trim(json); - w2ui['main_layout'].content('main', tmp[0]); - $('#example_view').html( - '

Preview

'+ html + - '' + - ''); - var code = '\n'+ - '\n'+ - '\n'+ - ' W2UI Demo: '+ cmd +'\n'+ - ' \n'+ - ' \n'+ - ' \n'+ - '\n'+ - '\n\n'+ - html + '\n\n'+ - (js != '' ? '\n\n' : '') + - (css != '' ? '\n\n' : '') + - '\n'+ - ''; - $('#example_code').html('Show Source Code'+ - ''+ - '
'+ - '
'+ - ' '+ - ' '+ - ' '+ - ' '+ - ' '+ - '
'+ - '
'); - }); - } - })); + // init layout + var main_layout = $('#main_layout').w2layout({ + name: 'main_layout', + panels: [ + { type: 'top', size: 45, style: 'border: 0px; border-bottom: 1px solid silver; background-color: #fff; color: #555;', overflow: 'hidden'}, + { type: 'left', size: 240, resizable: true, style: 'border-right: 1px solid silver;' }, + { type: 'main', style: 'background-color: white;' } + ] + }); + w2ui['main_layout'].content('top', '
W2UI 1.3 Demos
'); + // w2ui['main_layout'].content('top', '
'+ + // 'Theme: '+ + // '   '+ + // 'Locale: '+ + // ''+ + // '
'); + // init sidebar + w2ui['main_layout'].content('left', $().w2sidebar({ + name: 'demo-sidebar', + img: null, + nodes: [ + { id: 'combo', text: 'Combinations', img: 'icon-folder', group1: true, + nodes: [ + { id: 'combo-1', text: 'Sidebar & Grid', icon: 'fa-star-empty' }, + { id: 'combo-2', text: 'Grid & Edit', icon: 'fa-star-empty' }, + { id: 'combo-3', text: 'Spreadsheet Like Grid', icon: 'fa-star-empty' }, + { id: 'combo-4', text: 'Buffered Scroll', icon: 'fa-star-empty' }, + { id: 'combo-9', text: 'Infinite Scroll', icon: 'fa-star-empty' }, + { id: 'combo-5', text: 'Tabs With Content', icon: 'fa-star-empty' }, + { id: 'combo-6', text: 'Layout & Dynamic Tabs', icon: 'fa-star-empty' }, + { id: 'combo-7', text: 'Popup & Grid', icon: 'fa-star-empty' }, + { id: 'combo-8', text: 'Popup & Layout', icon: 'fa-star-empty' }, + ] + }, + { id: 'layout', text: 'Layout', img: 'icon-folder', group1: true, + nodes: [ + { id: 'layout-1', text: 'Simple Layout', icon: 'fa-columns' }, + { id: 'layout-2', text: 'Resizable Panels', icon: 'fa-columns' }, + { id: 'layout-3', text: 'Show/Hide Panels', icon: 'fa-columns' }, + { id: 'layout-4', text: 'Load Content', icon: 'fa-columns' }, + { id: 'layout-5', text: 'Transitions', icon: 'fa-columns' }, + { id: 'layout-6', text: 'Event Listeners', icon: 'fa-columns' }, + { id: 'layout-7', text: 'Nested Layouts', icon: 'fa-columns' }, + { id: 'layout-8', text: 'Panel With Tabs', icon: 'fa-columns' }, + { id: 'layout-9', text: 'Panel With Toolbar', icon: 'fa-columns' }, + { id: 'layout-10', text: 'Panel With Title', icon: 'fa-columns' } + ] + }, + { id: 'grid', text: 'Grid', img: 'icon-folder', group1: true, + nodes: [ + { id: 'grid-1', text: 'Simple Grid', icon: 'fa-table' }, + { id: 'grid-3', text: 'Grid Elements', icon: 'fa-table' }, + { id: 'grid-2', text: 'Row Formating', icon: 'fa-table' }, + { id: 'grid-23',text: 'Cell Formatting', icon: 'fa-table' }, + { id: 'grid-4', text: 'Data Source', icon: 'fa-table' }, + { id: 'grid-5', text: 'Load Data Once', icon: 'fa-table' }, + { id: 'grid-6', text: 'Single or Multi Select', icon: 'fa-table' }, + { id: 'grid-7', text: 'Sub Grids', icon: 'fa-table' }, + { id: 'grid-8', text: 'Show/Hide Columns', icon: 'fa-table' }, + { id: 'grid-9', text: 'Add/Remove Records', icon: 'fa-table' }, + { id: 'grid-10', text: 'Select/Unselect Records', icon: 'fa-table' }, + { id: 'grid-11', text: 'Fixed/Resisable', icon: 'fa-table' }, + { id: 'grid-12', text: 'Column Sort', icon: 'fa-table' }, + { id: 'grid-13', text: 'Column Groups', icon: 'fa-table' }, + { id: 'grid-14', text: 'Summary Records', icon: 'fa-table' }, + { id: 'grid-15', text: 'Simple Search', icon: 'fa-table' }, + { id: 'grid-16', text: 'Advanced Search', icon: 'fa-table' }, + { id: 'grid-17', text: 'Grid Toolbar', icon: 'fa-table' }, + { id: 'grid-18', text: 'Master -> Detail', icon: 'fa-table' }, + { id: 'grid-19', text: 'Two Grids', icon: 'fa-table' }, + { id: 'grid-20', text: 'Render to a New Box', icon: 'fa-table' }, + { id: 'grid-21', text: 'Inline Editing', icon: 'fa-table' }, + { id: 'grid-22', text: 'Resizable Columns', icon: 'fa-table' }, + { id: 'grid-24', text: 'Lock/Unlock Grid', icon: 'fa-table' }, + { id: 'grid-25', text: 'Re-Order Columns', icon: 'fa-table' }, + //{ id: 'grid-26', text: 'Re-Order records', icon: 'fa-table' }, + //{ id: 'grid-27', text: 'Locked Columns', icon: 'fa-table' } + ] + }, + { id: 'toolbar', text: 'Toolbar', img: 'icon-folder', group1: true, + nodes: [ + { id: 'toolbar-1', text: 'Simple Toolbar', icon: 'fa-hand-up' }, + { id: 'toolbar-2', text: 'Advanced Toolbar', icon: 'fa-hand-up' }, + { id: 'toolbar-3', text: 'Add/Remove Buttons', icon: 'fa-hand-up' }, + { id: 'toolbar-4', text: 'Show/Hide Buttons', icon: 'fa-hand-up' }, + { id: 'toolbar-5', text: 'Enable/Disable Buttons', icon: 'fa-hand-up' } + ] + }, + { id: 'sidebar', text: 'Sidebar', img: 'icon-folder', group1: true, + nodes: [ + { id: 'sidebar-1', text: 'Simple Sidebar', icon: 'fa-hand-left' }, + { id: 'sidebar-2', text: 'Add/Remove', icon: 'fa-hand-left' }, + { id: 'sidebar-3', text: 'Show/Hide', icon: 'fa-hand-left' }, + { id: 'sidebar-4', text: 'Enable/Disable', icon: 'fa-hand-left' }, + { id: 'sidebar-5', text: 'Expand/Collapse', icon: 'fa-hand-left' }, + { id: 'sidebar-6', text: 'Select/Unselect', icon: 'fa-hand-left' }, + { id: 'sidebar-8', text: 'Top & Bottom HTML', icon: 'fa-hand-left' }, + { id: 'sidebar-7', text: 'Events', icon: 'fa-hand-left' } + ] + }, + { id: 'listview', text: 'ListView', img: 'icon-folder', group1: true, + nodes: [ + { id: 'listview-1', text: 'Simple ListView', icon: 'fa-folder-close-alt' }, + { id: 'listview-2', text: 'Different view types', icon: 'fa-folder-close-alt' }, + { id: 'listview-5', text: 'Table view type', icon: 'fa-folder-close-alt' }, + { id: 'listview-3', text: 'Selecting items', icon: 'fa-folder-close-alt' }, + { id: 'listview-4', text: 'Add/Remove items', icon: 'fa-folder-close-alt' } + ] + }, + { id: 'tabs', text: 'Tabs', img: 'icon-folder', group1: true, + nodes: [ + { id: 'tabs-1', text: 'Simple Tabs', icon: 'fa-folder-close-alt' }, + { id: 'tabs-2', text: 'Set a Tab Active', icon: 'fa-folder-close-alt' }, + { id: 'tabs-3', text: 'Closable Tabs', icon: 'fa-folder-close-alt' }, + { id: 'tabs-4', text: 'Add/Remove Tabs', icon: 'fa-folder-close-alt' }, + { id: 'tabs-5', text: 'Enable/Disabled Tabs', icon: 'fa-folder-close-alt' }, + { id: 'tabs-6', text: 'Show/Hide Tabs', icon: 'fa-folder-close-alt' } + ] + }, + { id: 'forms', text: 'Forms', img: 'icon-folder', group1: true, + nodes: [ + { id: 'forms-1', text: 'Simple Form', icon: 'fa-edit' }, + { id: 'forms-2', text: 'Field Types', icon: 'fa-edit' }, + { id: 'forms-3', text: 'Large Form', icon: 'fa-edit' }, + { id: 'forms-4', text: 'Multi Page Form', icon: 'fa-edit' }, + { id: 'forms-5', text: 'Form Tabs', icon: 'fa-edit' }, + { id: 'forms-9', text: 'Form Toolbar', icon: 'fa-edit' }, + { id: 'forms-8', text: 'Form in a Popup', icon: 'fa-edit' }, + { id: 'forms-6', text: 'Events', icon: 'fa-edit' }, + { id: 'forms-7', text: 'Input Controls', icon: 'fa-edit' } + ] + }, + { id: 'popup', text: 'Popup', img: 'icon-folder', group1: true, + nodes: [ + { id: 'popup-1', text: 'Simple Popup', icon: 'fa-list-alt' }, + { id: 'popup-2', text: 'More Options', icon: 'fa-list-alt' }, + { id: 'popup-3', text: 'Popup Elements', icon: 'fa-list-alt' }, + { id: 'popup-4', text: 'Based on Markup', icon: 'fa-list-alt' }, + { id: 'popup-5', text: 'Load Content', icon: 'fa-list-alt' }, + { id: 'popup-6', text: 'Transitions', icon: 'fa-list-alt' }, + { id: 'popup-7', text: 'Slide a Message', icon: 'fa-list-alt' }, + { id: 'popup-8', text: 'Dialogs', icon: 'fa-list-alt' } + ] + }, + { id: 'utils', text: 'Utilities', img: 'icon-folder', group1: true, + nodes: [ + { id: 'utils-1', text: 'Validation', icon: 'fa-star-empty' }, + { id: 'utils-2', text: 'Encoding', icon: 'fa-star-empty' }, + { id: 'utils-3', text: 'Transitions', icon: 'fa-star-empty' }, + { id: 'utils-4', text: 'Overlays', icon: 'fa-star-empty' } + ] + } + ], + onClick: function (event) { + var cmd = event.target; + if (parseInt(cmd.substr(cmd.length-1)) != cmd.substr(cmd.length-1)) return; + var tmp = w2ui['demo-sidebar'].get(cmd); + document.title = tmp.parent.text + ': ' + tmp.text + ' | w2ui'; + // delete previously created items + for (var widget in w2ui) { + var nm = w2ui[widget].name; + if (['main_layout', 'demo-sidebar'].indexOf(nm) == -1) $().w2destroy(nm); + } + // set hash + if (tmp.parent && tmp.parent.id != '') { + var pid = w2ui['demo-sidebar'].get(cmd).parent.id; + document.location.hash = '!'+ pid + '/' + cmd; + } + // load example + $.get('examples/'+ cmd +'.html', function (data) { + var tmp = data.split(''); + if (tmp.length == 1) { + alert('ERROR: cannot parse example.'); + console.log('ERROR: cannot parse example.', data); + return; + } + var html = tmp[1] ? $.trim(tmp[1]) : ''; + var js = tmp[2] ? $.trim(tmp[2]) : ''; + var css = tmp[3] ? $.trim(tmp[3]) : ''; + var json = tmp[4] ? $.trim(tmp[4]) : ''; + js = js.replace(/^]*>/, '').replace(/<\/script>$/, ''); + js = $.trim(js); + css = css.replace(/^]*>/, '').replace(/<\/style>$/, ''); + css = $.trim(css); + json = json.replace(/^]*>/, '').replace(/<\/script>$/, ''); + json = $.trim(json); + w2ui['main_layout'].content('main', tmp[0]); + $('#example_view').html( + '

Preview

'+ html + + '' + + ''); + var code = '\n'+ + '\n'+ + '\n'+ + ' W2UI Demo: '+ cmd +'\n'+ + ' \n'+ + ' \n'+ + ' \n'+ + '\n'+ + '\n\n'+ + html + '\n\n'+ + (js != '' ? '\n\n' : '') + + (css != '' ? '\n\n' : '') + + '\n'+ + ''; + $('#example_code').html('Show Source Code'+ + ''+ + '
'+ + '
'+ + ' '+ + ' '+ + ' '+ + ' '+ + ' '+ + '
'+ + '
'); + }); + } + })); - // check hash - setTimeout(function () { - var tmp = String(document.location.hash).split('/'); - switch (tmp[0]) { - default: - case '#!combo': - w2ui['demo-sidebar'].expand('combo'); - w2ui['demo-sidebar'].click(tmp[1] || 'combo-1'); - break; + // check hash + setTimeout(function () { + var tmp = String(document.location.hash).split('/'); + switch (tmp[0]) { + default: + case '#!combo': + w2ui['demo-sidebar'].expand('combo'); + w2ui['demo-sidebar'].click(tmp[1] || 'combo-1'); + break; - case '#!layout': - w2ui['demo-sidebar'].expand('layout'); - w2ui['demo-sidebar'].click(tmp[1] || 'layout-1'); - break; + case '#!layout': + w2ui['demo-sidebar'].expand('layout'); + w2ui['demo-sidebar'].click(tmp[1] || 'layout-1'); + break; - case '#!grid': - w2ui['demo-sidebar'].expand('grid'); - w2ui['demo-sidebar'].click(tmp[1] || 'grid-1'); - break; + case '#!grid': + w2ui['demo-sidebar'].expand('grid'); + w2ui['demo-sidebar'].click(tmp[1] || 'grid-1'); + break; - case '#!toolbar': - w2ui['demo-sidebar'].expand('toolbar'); - w2ui['demo-sidebar'].click(tmp[1] || 'toolbar-1'); - break; + case '#!toolbar': + w2ui['demo-sidebar'].expand('toolbar'); + w2ui['demo-sidebar'].click(tmp[1] || 'toolbar-1'); + break; - case '#!sidebar': - w2ui['demo-sidebar'].expand('sidebar'); - w2ui['demo-sidebar'].click(tmp[1] || 'sidebar-1'); - break; + case '#!sidebar': + w2ui['demo-sidebar'].expand('sidebar'); + w2ui['demo-sidebar'].click(tmp[1] || 'sidebar-1'); + break; - case '#!listview': - w2ui['demo-sidebar'].expand('listview'); - w2ui['demo-sidebar'].click(tmp[1] || 'listview-1'); - break; + case '#!listview': + w2ui['demo-sidebar'].expand('listview'); + w2ui['demo-sidebar'].click(tmp[1] || 'listview-1'); + break; - case '#!tabs': - w2ui['demo-sidebar'].expand('tabs'); - w2ui['demo-sidebar'].click(tmp[1] || 'tabs-1'); - break; + case '#!tabs': + w2ui['demo-sidebar'].expand('tabs'); + w2ui['demo-sidebar'].click(tmp[1] || 'tabs-1'); + break; - case '#!popup': - w2ui['demo-sidebar'].expand('popup'); - w2ui['demo-sidebar'].click(tmp[1] || 'popup-1'); - break; + case '#!popup': + w2ui['demo-sidebar'].expand('popup'); + w2ui['demo-sidebar'].click(tmp[1] || 'popup-1'); + break; - case '#!forms': - w2ui['demo-sidebar'].expand('forms'); - w2ui['demo-sidebar'].click(tmp[1] || 'forms-1'); - break; + case '#!forms': + w2ui['demo-sidebar'].expand('forms'); + w2ui['demo-sidebar'].click(tmp[1] || 'forms-1'); + break; - case '#!utils': - w2ui['demo-sidebar'].expand('utils'); - w2ui['demo-sidebar'].click(tmp[1] || 'utils-1'); - break; - }; - }, 100); + case '#!utils': + w2ui['demo-sidebar'].expand('utils'); + w2ui['demo-sidebar'].click(tmp[1] || 'utils-1'); + break; + }; + }, 100); }); function initCode() { - // CodeMirror - var text = $('#example_code .preview'); - if (text.length > 0) { - var cm = CodeMirror( - function(elt) { text[0].parentNode.replaceChild(elt, text[0]); }, - { - value : $.trim(text.val()), - mode : "text/html", - readOnly : true, - gutter : true, - lineNumbers : true - } - ); - cm.setSize(null, cm.doc.height + 15); - } - var text = $('#example_code .json'); - if (text.length > 0) { - var cm = CodeMirror( - function(elt) { text[0].parentNode.replaceChild(elt, text[0]); }, - { - value : $.trim(text.val()), - mode : "javascript", - readOnly : true, - gutter : true, - lineNumbers : true - } - ); - cm.setSize(null, cm.doc.height + 15); - } - $('#example_code .jsfiddle').on('click', function () { - // $('#fiddleForm textarea[name=html]').val(html || ''); - // $('#fiddleForm textarea[name=js]').val(js || ''); - // $('#fiddleForm textarea[name=css]').val(css || ''); - $('#fiddleForm').submit(); - }); + // CodeMirror + var text = $('#example_code .preview'); + if (text.length > 0) { + var cm = CodeMirror( + function(elt) { text[0].parentNode.replaceChild(elt, text[0]); }, + { + value : $.trim(text.val()), + mode : "text/html", + readOnly : true, + gutter : true, + lineNumbers : true + } + ); + cm.setSize(null, cm.doc.height + 15); + } + var text = $('#example_code .json'); + if (text.length > 0) { + var cm = CodeMirror( + function(elt) { text[0].parentNode.replaceChild(elt, text[0]); }, + { + value : $.trim(text.val()), + mode : "javascript", + readOnly : true, + gutter : true, + lineNumbers : true + } + ); + cm.setSize(null, cm.doc.height + 15); + } + $('#example_code .jsfiddle').on('click', function () { + // $('#fiddleForm textarea[name=html]').val(html || ''); + // $('#fiddleForm textarea[name=js]').val(js || ''); + // $('#fiddleForm textarea[name=css]').val(css || ''); + $('#fiddleForm').submit(); + }); } diff --git a/dist/kickstart.js b/dist/kickstart.js index e97bd0dd3..2f52bc7e5 100644 --- a/dist/kickstart.js +++ b/dist/kickstart.js @@ -5,213 +5,213 @@ **/ var kickStart = (function () { - var app = {}; + var app = {}; - // public scope - app.modules = {}; - app.config = {}; - app.define = define; - app.require = require; - app.register = register; + // public scope + app.modules = {}; + app.config = {}; + app.define = define; + app.require = require; + app.register = register; - return app; + return app; - // =========================================== - // -- Define modules + // =========================================== + // -- Define modules - function define (mod) { - // if string - it is path to the file - if (typeof mod == 'string') { - $.ajax({ - url : mod, - dataType: 'text', - cache : false, - async : false, // do it synchronosly - otherwise errors - success : function (data, success, xhr) { - if (success != 'success') { - console.log('ERROR: error while loading module definition from "'+ mod +'".'); - return; - } - try { - mod = JSON.parse(data); - } catch (e) { - console.log('ERROR: not valid JSON file "'+ mod +'".\n'+ e); - return; - } - }, - error : function (data, err, errData) { - console.log('ERROR: error while loading module definition from "'+ mod +'".'); - } - }); - } - if (!$.isArray(mod)) mod = [mod]; - for (var m in mod) { - if (app.modules.hasOwnProperty(mod[m].name)) { - console.log('ERROR: module ' + mod[m].name + ' is already registered.'); - return false; - } - app.modules[mod[m].name] = $.extend({}, mod[m], { loaded: false, files: {} }); - } - return true; - } + function define (mod) { + // if string - it is path to the file + if (typeof mod == 'string') { + $.ajax({ + url : mod, + dataType : 'text', + cache : false, + async : false, // do it synchronosly - otherwise errors + success : function (data, success, xhr) { + if (success != 'success') { + console.log('ERROR: error while loading module definition from "'+ mod +'".'); + return; + } + try { + mod = JSON.parse(data); + } catch (e) { + console.log('ERROR: not valid JSON file "'+ mod +'".\n'+ e); + return; + } + }, + error : function (data, err, errData) { + console.log('ERROR: error while loading module definition from "'+ mod +'".'); + } + }); + } + if (!$.isArray(mod)) mod = [mod]; + for (var m in mod) { + if (app.modules.hasOwnProperty(mod[m].name)) { + console.log('ERROR: module ' + mod[m].name + ' is already registered.'); + return false; + } + app.modules[mod[m].name] = $.extend({}, mod[m], { loaded: false, files: {} }); + } + return true; + } - // =========================================== - // -- Register module + // =========================================== + // -- Register module - function register (name, moduleFunction) { - // check if modules id defined - if (app.hasOwnProperty(name)) { - console.log('ERROR: Namespace '+ name +' is already registered'); - return false; - } - if (!app.modules.hasOwnProperty(name)) { - console.log('ERROR: Namespace '+ name +' is not defined, first define it with kickStart.define'); - return false; - } - // register module - var mod = null; - for (var m in app.modules) { - if (app.modules[m].name == name) mod = app.modules[m]; - } - // init module - app[name] = moduleFunction(mod.files, mod); - app.modules[name].loaded = true; - return; - } + function register (name, moduleFunction) { + // check if modules id defined + if (app.hasOwnProperty(name)) { + console.log('ERROR: Namespace '+ name +' is already registered'); + return false; + } + if (!app.modules.hasOwnProperty(name)) { + console.log('ERROR: Namespace '+ name +' is not defined, first define it with kickStart.define'); + return false; + } + // register module + var mod = null; + for (var m in app.modules) { + if (app.modules[m].name == name) mod = app.modules[m]; + } + // init module + app[name] = moduleFunction(mod.files, mod); + app.modules[name].loaded = true; + return; + } - // =========================================== - // -- Load Modules + // =========================================== + // -- Load Modules - function require (names, callBack) { // returns promise - if (!$.isArray(names)) names = [names]; - var modCount = names.length; - var failed = false; - var promise = { - ready: function (callBack) { // a module loaded - promise._ready = callBack; - return promise; - }, - fail: function (callBack) { // a module loading failed - promise._fail = callBack; - return promise; - }, - done: function (callBack) { // all loaded - promise._done = callBack; - return promise; - }, - always: function (callBack) { - promise._always = callBack; - return promise; - } - }; - setTimeout(function () { - for (var n in names) { - var name = names[n]; - // already loaded ? - if (typeof app[name] != 'undefined') { - modCount--; - isFinished(); - } else if (typeof app.modules[name] == 'undefined') { - console.log('ERROR: module ' + name + ' is not defined.'); - } else { - (function (name) { // need closure - // load dependencies - getFiles(app.modules[name].assets.concat([app.modules[name].main]), function (files) { - var main = files[app.modules[name].main]; - delete files[app.modules[name].main]; - // register assets - app.modules[name].files = files; - app.modules[name].loaded = true; - // execute main file - try { - eval(main); - } catch (e) { - failed = true; - // find error line - var err = e.stack.split('\n'); - var tmp = err[1].match(/:([\d]){1,10}:([\d]{1,10})/gi); - if (tmp) tmp = tmp[0].split(':'); - if (tmp) { - // display error - console.error('ERROR: ' + err[0] + ' ==> ' + app.modules[name].main + ', line: '+ tmp[1] + ', character: '+ tmp[2]); - console.log(e.stack); - } else { - console.error('ERROR: ' + app.modules[name].main); - console.log(e.stack); - } - if (typeof app.config.fail == 'function') app.config.fail(app.modules[name]); - if (typeof promise._fail == 'function') promise._fail(app.modules[name]); - } - // check ready - if (typeof app.config.ready == 'function') app.config.ready(app.modules[name]); - if (typeof promise._ready == 'function') promise._ready(app.modules[name]); - modCount--; - isFinished(); - }); - })(name); - } - } - }, 1); - // promise need to be returned immidiately - return promise; + function require (names, callBack) { // returns promise + if (!$.isArray(names)) names = [names]; + var modCount = names.length; + var failed = false; + var promise = { + ready: function (callBack) { // a module loaded + promise._ready = callBack; + return promise; + }, + fail: function (callBack) { // a module loading failed + promise._fail = callBack; + return promise; + }, + done: function (callBack) { // all loaded + promise._done = callBack; + return promise; + }, + always: function (callBack) { + promise._always = callBack; + return promise; + } + }; + setTimeout(function () { + for (var n in names) { + var name = names[n]; + // already loaded ? + if (typeof app[name] != 'undefined') { + modCount--; + isFinished(); + } else if (typeof app.modules[name] == 'undefined') { + console.log('ERROR: module ' + name + ' is not defined.'); + } else { + (function (name) { // need closure + // load dependencies + getFiles(app.modules[name].assets.concat([app.modules[name].main]), function (files) { + var main = files[app.modules[name].main]; + delete files[app.modules[name].main]; + // register assets + app.modules[name].files = files; + app.modules[name].loaded = true; + // execute main file + try { + eval(main); + } catch (e) { + failed = true; + // find error line + var err = e.stack.split('\n'); + var tmp = err[1].match(/:([\d]){1,10}:([\d]{1,10})/gi); + if (tmp) tmp = tmp[0].split(':'); + if (tmp) { + // display error + console.error('ERROR: ' + err[0] + ' ==> ' + app.modules[name].main + ', line: '+ tmp[1] + ', character: '+ tmp[2]); + console.log(e.stack); + } else { + console.error('ERROR: ' + app.modules[name].main); + console.log(e.stack); + } + if (typeof app.config.fail == 'function') app.config.fail(app.modules[name]); + if (typeof promise._fail == 'function') promise._fail(app.modules[name]); + } + // check ready + if (typeof app.config.ready == 'function') app.config.ready(app.modules[name]); + if (typeof promise._ready == 'function') promise._ready(app.modules[name]); + modCount--; + isFinished(); + }); + })(name); + } + } + }, 1); + // promise need to be returned immidiately + return promise; - function isFinished () { - if (modCount == 0) { - if (failed !== true) { - if (typeof app.config.done == 'function') app.config.done(app.modules[name]); - if (typeof promise._done == 'function') promise._done(app.modules[name]); - if (typeof callBack == 'function') callBack(); - } - if (typeof app.config.always == 'function') app.config.always(app.modules[name]); - if (typeof promise._always == 'function') promise._always(); - } - } - } + function isFinished () { + if (modCount == 0) { + if (failed !== true) { + if (typeof app.config.done == 'function') app.config.done(app.modules[name]); + if (typeof promise._done == 'function') promise._done(app.modules[name]); + if (typeof callBack == 'function') callBack(); + } + if (typeof app.config.always == 'function') app.config.always(app.modules[name]); + if (typeof promise._always == 'function') promise._always(); + } + } + } - // =========================================== - // -- Loads a set of files and returns - // -- its contents to the callBack function + // =========================================== + // -- Loads a set of files and returns + // -- its contents to the callBack function - function getFiles (files, callBack) { - var bufferObj = {}; - var bufferLen = files.length; - - for (var i in files) { - // need a closure - (function () { - var index = i; - var path = files[i]; - $.ajax({ - url : path, - dataType: 'text', - cache : false, - success : function (data, success, xhr) { - if (success != 'success') { - console.log('ERROR: error while getting a file '+ path +'.'); - return; - } - bufferObj[path] = xhr.responseText; - loadDone(); + function getFiles (files, callBack) { + var bufferObj = {}; + var bufferLen = files.length; + + for (var i in files) { + // need a closure + (function () { + var index = i; + var path = files[i]; + $.ajax({ + url : path, + dataType: 'text', + cache : false, + success : function (data, success, xhr) { + if (success != 'success') { + console.log('ERROR: error while getting a file '+ path +'.'); + return; + } + bufferObj[path] = xhr.responseText; + loadDone(); - }, - error : function (data, err, errData) { - if (err == 'error') { - console.log('ERROR: failed to load '+ files[i] +'.'); - } else { - console.log('ERROR: file "'+ files[i] + '" is loaded, but with a parsing error(s) in line '+ errData.line +': '+ errData.message); - bufferObj[path] = xhr.responseText; - loadDone(); - } - } - }); - })(); - } - // internal counter - function loadDone () { - bufferLen--; - if (bufferLen <= 0) callBack(bufferObj); - } - } + }, + error : function (data, err, errData) { + if (err == 'error') { + console.log('ERROR: failed to load '+ files[i] +'.'); + } else { + console.log('ERROR: file "'+ files[i] + '" is loaded, but with a parsing error(s) in line '+ errData.line +': '+ errData.message); + bufferObj[path] = xhr.responseText; + loadDone(); + } + } + }); + })(); + } + // internal counter + function loadDone () { + bufferLen--; + if (bufferLen <= 0) callBack(bufferObj); + } + } })(); /************************************************ * Library: KickStart - Minimalistic Framework @@ -220,138 +220,138 @@ var kickStart = (function () { kickStart.define({ name: 'route' }); kickStart.register('route', function () { - var app = kickStart; - // private scope - var routes = {}; - var routeRE = {}; - var options = { debug : false }; + var app = kickStart; + // private scope + var routes = {}; + var routeRE = {}; + var options = { debug : false }; - addListener(); - return { - add : add, - remove : remove, - go : go, - get : get, - process : process, - list : list - } + addListener(); + return { + add : add, + remove : remove, + go : go, + get : get, + process : process, + list : list + } - /* - * Public methods - */ + /* + * Public methods + */ - function add (route, handler) { - if (typeof route == 'object') { - for (var r in route) { - var tmp = String('/'+ r).replace(/\/{2,}/g, '/'); - routes[tmp] = route[r]; - } - return app.route; - } - route = String('/'+route).replace(/\/{2,}/g, '/'); - routes[route] = handler; - return app.route; - } + function add (route, handler) { + if (typeof route == 'object') { + for (var r in route) { + var tmp = String('/'+ r).replace(/\/{2,}/g, '/'); + routes[tmp] = route[r]; + } + return app.route; + } + route = String('/'+route).replace(/\/{2,}/g, '/'); + routes[route] = handler; + return app.route; + } - function remove (route) { - route = String('/'+route).replace(/\/{2,}/g, '/'); - delete routes[route]; - delete routeRE[route]; - return app.route; - } + function remove (route) { + route = String('/'+route).replace(/\/{2,}/g, '/'); + delete routes[route]; + delete routeRE[route]; + return app.route; + } - function go (route) { - route = String('/'+route).replace(/\/{2,}/g, '/'); - setTimeout(function () { window.location.hash = route; }, 1); - return app.route; - } + function go (route) { + route = String('/'+route).replace(/\/{2,}/g, '/'); + setTimeout(function () { window.location.hash = route; }, 1); + return app.route; + } - function get () { - return window.location.hash.substr(1).replace(/\/{2,}/g, '/'); - } + function get () { + return window.location.hash.substr(1).replace(/\/{2,}/g, '/'); + } - function list () { - prepare(); - var res = {}; - for (var r in routes) { - var tmp = routeRE[r].keys; - var keys = []; - for (var t in tmp) keys.push(tmp[t].name); - res[r] = keys; - } - return res; - } + function list () { + prepare(); + var res = {}; + for (var r in routes) { + var tmp = routeRE[r].keys; + var keys = []; + for (var t in tmp) keys.push(tmp[t].name); + res[r] = keys; + } + return res; + } - function process () { - prepare(); - // match routes - var hash = window.location.hash.substr(1).replace(/\/{2,}/g, '/'); - if (hash == '') hash = '/'; - var tmp = hash.split('/'); - // check if modules is loaed - if (tmp[1] && typeof app[tmp[1]] == 'undefined') { - if (options.debug) console.log('ROUTE: load module ' + tmp[1]); - app.require(tmp[1]).done(function () { - if (app.modules[tmp[1]]) process(); - }); - } else { - // process route - for (var r in routeRE) { - var params = {}; - var tmp = routeRE[r].path.exec(hash); - if (tmp) { // match - var i = 1; - for (var p in routeRE[r].keys) { - params[routeRE[r].keys[p].name] = tmp[i]; - i++; - } - if (options.debug) console.log('ROUTE:', r, params); - routes[r](r, params); - } - } - } - } + function process () { + prepare(); + // match routes + var hash = window.location.hash.substr(1).replace(/\/{2,}/g, '/'); + if (hash == '') hash = '/'; + var tmp = hash.split('/'); + // check if modules is loaed + if (tmp[1] && typeof app[tmp[1]] == 'undefined') { + if (options.debug) console.log('ROUTE: load module ' + tmp[1]); + app.require(tmp[1]).done(function () { + if (app.modules[tmp[1]]) process(); + }); + } else { + // process route + for (var r in routeRE) { + var params = {}; + var tmp = routeRE[r].path.exec(hash); + if (tmp) { // match + var i = 1; + for (var p in routeRE[r].keys) { + params[routeRE[r].keys[p].name] = tmp[i]; + i++; + } + if (options.debug) console.log('ROUTE:', r, params); + routes[r](r, params); + } + } + } + } - /* - * Private methods - */ + /* + * Private methods + */ - function prepare () { - // make sure all routes are parsed to RegEx - for (var r in routes) { - if (routeRE[r]) continue; - var keys = []; - var path = r - .replace(/\/\(/g, '(?:/') - .replace(/\+/g, '__plus__') - .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional) { - keys.push({ name: key, optional: !! optional }); - slash = slash || ''; - return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || ''); - }) - .replace(/([\/.])/g, '\\$1') - .replace(/__plus__/g, '(.+)') - .replace(/\*/g, '(.*)'); - routeRE[r] = { - path : new RegExp('^' + path + '$', 'i'), - keys : keys - } - } - } + function prepare () { + // make sure all routes are parsed to RegEx + for (var r in routes) { + if (routeRE[r]) continue; + var keys = []; + var path = r + .replace(/\/\(/g, '(?:/') + .replace(/\+/g, '__plus__') + .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional) { + keys.push({ name: key, optional: !! optional }); + slash = slash || ''; + return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || ''); + }) + .replace(/([\/.])/g, '\\$1') + .replace(/__plus__/g, '(.+)') + .replace(/\*/g, '(.*)'); + routeRE[r] = { + path : new RegExp('^' + path + '$', 'i'), + keys : keys + } + } + } - function addListener () { - if (window.addEventListener) { - window.addEventListener('hashchange', process, false); - } else { - window.attachEvent('onhashchange', process); - } - } + function addListener () { + if (window.addEventListener) { + window.addEventListener('hashchange', process, false); + } else { + window.attachEvent('onhashchange', process); + } + } - function removeListener () { - if (window.removeEventListener) { - window.removeEventListener('hashchange', process); - } else { - window.detachEvent('onhashchange', process); - } - } + function removeListener () { + if (window.removeEventListener) { + window.removeEventListener('hashchange', process); + } else { + window.detachEvent('onhashchange', process); + } + } }); \ No newline at end of file diff --git a/dist/w2ui-dark.css b/dist/w2ui-dark.css index 09966722c..f8990263c 100644 --- a/dist/w2ui-dark.css +++ b/dist/w2ui-dark.css @@ -716,7 +716,7 @@ select { border-top-color: #81C6FF; } /* -* ARROWS +* ARROWS */ .arrow-up { background: none; @@ -768,7 +768,7 @@ select { line-height: 0; } /* -* COLOR overlay +* COLOR overlay */ .w2ui-color { padding: 5px; @@ -800,7 +800,7 @@ select { border: 1px solid #fff; } /* -* DATE overlay +* DATE overlay */ .w2ui-calendar { margin: 0px; @@ -988,7 +988,7 @@ select { padding: 6px; } /* -* Time +* Time */ .w2ui-calendar-time { padding: 5px; @@ -1024,7 +1024,7 @@ select { background-image: linear-gradient(top,#ffffff 20%,#f6f6f6 50%,#eeeeee 52%,#f4f4f4 100%); } /* -* Drop down menu +* Drop down menu */ .w2ui-drop-menu td { white-space: nowrap; @@ -1044,7 +1044,7 @@ select { border-bottom: 1px solid #D3D2D4; } /* -* ENUM items +* ENUM items */ .w2ui-list { color: #c0c8d5; diff --git a/dist/w2ui-fields.css b/dist/w2ui-fields.css index 41473da29..1a1ea67cb 100644 --- a/dist/w2ui-fields.css +++ b/dist/w2ui-fields.css @@ -311,7 +311,7 @@ select { border-top-color: #81C6FF; } /* -* ARROWS +* ARROWS */ .arrow-up { background: none; @@ -363,7 +363,7 @@ select { line-height: 0; } /* -* COLOR overlay +* COLOR overlay */ .w2ui-color { padding: 5px; @@ -395,7 +395,7 @@ select { border: 1px solid #fff; } /* -* DATE overlay +* DATE overlay */ .w2ui-calendar { margin: 0px; @@ -583,7 +583,7 @@ select { padding: 6px; } /* -* Time +* Time */ .w2ui-calendar-time { padding: 5px; @@ -619,7 +619,7 @@ select { background-image: linear-gradient(top,#ffffff 20%,#f6f6f6 50%,#eeeeee 52%,#f4f4f4 100%); } /* -* Drop down menu +* Drop down menu */ .w2ui-drop-menu td { white-space: nowrap; @@ -639,7 +639,7 @@ select { border-bottom: 1px solid #D3D2D4; } /* -* ENUM items +* ENUM items */ .w2ui-list { color: inherit; diff --git a/dist/w2ui-fields.js b/dist/w2ui-fields.js index f83352524..03f151760 100644 --- a/dist/w2ui-fields.js +++ b/dist/w2ui-fields.js @@ -5,866 +5,866 @@ var w2obj = w2obj || {}; // expose object to be able to overwrite default functi /************************************************ * Library: Web 2.0 UI for jQuery * - Following objects are defines -* - w2ui - object that will contain all widgets -* - w2obj - object with widget prototypes -* - w2utils - basic utilities -* - $().w2render - common render -* - $().w2destroy - common destroy -* - $().w2marker - marker plugin -* - $().w2tag - tag plugin -* - $().w2overlay - overlay plugin -* - $().w2menu - menu plugin -* - w2utils.event - generic event object -* - w2utils.keyboard - object for keyboard navigation +* - w2ui - object that will contain all widgets +* - w2obj - object with widget prototypes +* - w2utils - basic utilities +* - $().w2render - common render +* - $().w2destroy - common destroy +* - $().w2marker - marker plugin +* - $().w2tag - tag plugin +* - $().w2overlay - overlay plugin +* - $().w2menu - menu plugin +* - w2utils.event - generic event object +* - w2utils.keyboard - object for keyboard navigation * - Dependencies: jQuery * * == NICE TO HAVE == -* - date has problems in FF new Date('yyyy-mm-dd') breaks -* - bug: w2utils.formatDate('2011-31-01', 'yyyy-dd-mm'); - wrong foratter -* - overlay should be displayed where more space (on top or on bottom) -* - write and article how to replace certain framework functions -* - format date and time is buggy -* - onComplete should pass widget as context (this) -* - add maxHeight for the w2menu -* - user localization from another lib (make it generic), https://github.com/jquery/globalize#readme -* - hidden and disabled in menus -* - isTime should support seconds -* - TEST On IOS +* - date has problems in FF new Date('yyyy-mm-dd') breaks +* - bug: w2utils.formatDate('2011-31-01', 'yyyy-dd-mm'); - wrong foratter +* - overlay should be displayed where more space (on top or on bottom) +* - write and article how to replace certain framework functions +* - format date and time is buggy +* - onComplete should pass widget as context (this) +* - add maxHeight for the w2menu +* - user localization from another lib (make it generic), https://github.com/jquery/globalize#readme +* - hidden and disabled in menus +* - isTime should support seconds +* - TEST On IOS * * == 1.4 changes -* - lock(box, options) || lock(box, msg, spinner) -* - updated age() date(), formatDate(), formatTime() - input format either '2013/12/21 19:03:59 PST' or unix timestamp -* - formatNumer(num, groupSymbol) - added new param -* - improved localization support (currency prefix, suffix, numbger group symbol) -* - improoved overlays (better positioning, refresh, etc.) -* - multiple overlay at the same time (if it has name) -* - overlay options.css removed, I have added options.style -* - ability to open searchable w2menu -* - w2confirm({}) +* - lock(box, options) || lock(box, msg, spinner) +* - updated age() date(), formatDate(), formatTime() - input format either '2013/12/21 19:03:59 PST' or unix timestamp +* - formatNumer(num, groupSymbol) - added new param +* - improved localization support (currency prefix, suffix, numbger group symbol) +* - improoved overlays (better positioning, refresh, etc.) +* - multiple overlay at the same time (if it has name) +* - overlay options.css removed, I have added options.style +* - ability to open searchable w2menu +* - w2confirm({}) * ************************************************/ var w2utils = (function () { - var tmp = {}; // for some temp variables - var obj = { - settings : { - "locale" : "en-us", - "date_format" : "m/d/yyyy", - "date_display" : "Mon d, yyyy", - "time_format" : "h12", - "currencyPrefix": "$", - "currencySuffix": "", - "currencyPrecision": 2, - "groupSymbol" : ",", - "shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - "fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - "shortdays" : ["M", "T", "W", "T", "F", "S", "S"], - "fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], - "RESTfull" : false, - "phrases" : {} // empty object for english phrases - }, - isInt : isInt, - isFloat : isFloat, - isMoney : isMoney, - isHex : isHex, - isAlphaNumeric : isAlphaNumeric, - isEmail : isEmail, - isDate : isDate, - isTime : isTime, - age : age, - date : date, - size : size, - formatNumber : formatNumber, - formatDate : formatDate, - formatTime : formatTime, - formatDateTime : formatDateTime, - stripTags : stripTags, - encodeTags : encodeTags, - escapeId : escapeId, - base64encode : base64encode, - base64decode : base64decode, - transition : transition, - lock : lock, - unlock : unlock, - lang : lang, - locale : locale, - getSize : getSize, - scrollBarSize : scrollBarSize, - checkName : checkName, - checkUniqueId : checkUniqueId - }; - return obj; - - function isInt (val) { - var re = /^[-+]?[0-9]+$/; - return re.test(val); - } - - function isFloat (val) { - return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)); - } - - function isMoney (val) { - var se = w2utils.settings; - var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +'[-+]?[0-9]*[\.]?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i'); - if (typeof val === 'string') { - val = val.replace(new RegExp(se.groupSymbol, 'g'), ''); - } - if (typeof val === 'object' || val === '') return false; - return re.test(val); - } - - function isHex (val) { - var re = /^[a-fA-F0-9]+$/; - return re.test(val); - } - - function isAlphaNumeric (val) { - var re = /^[a-zA-Z0-9_-]+$/; - return re.test(val); - } - - function isEmail (val) { - var email = /^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; - return email.test(val); - } - - function isDate (val, format, retDate) { - if (!val) return false; - - var dt = 'Invalid Date'; - var month, day, year; - - if (format == null) format = w2utils.settings.date_format; - - if (typeof val.getUTCFullYear === 'function' && typeof val.getUTCMonth === 'function' && typeof val.getUTCDate === 'function') { - year = val.getUTCFullYear(); - month = val.getUTCMonth(); - day = val.getUTCDate(); - } else if (typeof val.getFullYear === 'function' && typeof val.getMonth === 'function' && typeof val.getDate === 'function') { - year = val.getFullYear(); - month = val.getMonth(); - day = val.getDate(); - } else { - val = String(val); - // convert month formats - if (RegExp('mon', 'ig').test(format)) { - format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); - val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); - for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) { - var t = w2utils.settings.fullmonths[m]; - val = val.replace(RegExp(t, 'ig'), (parseInt(m) + 1)).replace(RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)); - } - } - // format date - var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); - var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); - if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } - if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } - if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } - if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } - if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } - if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } - if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } - } - if (!isInt(year)) return false; - if (!isInt(month)) return false; - if (!isInt(day)) return false; - year = +year; - month = +month; - day = +day; - dt = new Date(year, month - 1, day); - // do checks - if (month == null) return false; - if (dt === 'Invalid Date') return false; - if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false; - if (retDate === true) return dt; else return true; - } - - function isTime (val, retTime) { - // Both formats 10:20pm and 22:20 - if (val == null) return false; - var max, pm; - // -- process american format - val = String(val); - val = val.toUpperCase(); - pm = val.indexOf('PM') >= 0; - var ampm = (pm || val.indexOf('AM') >= 0); - if (ampm) max = 12; else max = 24; - val = val.replace('AM', '').replace('PM', ''); - val = $.trim(val); - // --- - var tmp = val.split(':'); - var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0); - // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: - if ((!ampm || tmp.length !== 1) && tmp.length !== 2) { return false; } - if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; } - if (tmp.length === 2 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; } - // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). - // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. - if (!ampm && max === h && m !== 0) { return false; } - if (ampm && tmp.length === 1 && h === 0) { return false; } - - if (retTime === true) { - if (pm) h += 12; - return { - hours: h, - minutes: m - }; - } - return true; - } - - function age (dateStr) { - if (dateStr === '' || dateStr == null) return ''; - var d1 = new Date(dateStr); - if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps - if (d1 === 'Invalid Date') return ''; - - var d2 = new Date(); - var sec = (d2.getTime() - d1.getTime()) / 1000; - var amount = ''; - var type = ''; - if (sec < 0) { - amount = 'future'; - type = ''; - } else if (sec < 60) { - amount = Math.floor(sec); - type = 'sec'; - if (sec < 0) { amount = 0; type = 'sec'; } - } else if (sec < 60*60) { - amount = Math.floor(sec/60); - type = 'min'; - } else if (sec < 24*60*60) { - amount = Math.floor(sec/60/60); - type = 'hour'; - } else if (sec < 30*24*60*60) { - amount = Math.floor(sec/24/60/60); - type = 'day'; - } else if (sec < 12*30*24*60*60) { - amount = Math.floor(sec/30/24/60/60*10)/10; - type = 'month'; - } else if (sec >= 12*30*24*60*60) { - amount = Math.floor(sec/12/30/24/60/60*10)/10; - type = 'year'; - } - return amount + ' ' + type + (amount > 1 ? 's' : ''); - } - - function date (dateStr) { - if (dateStr === '' || dateStr == null) return ''; - var d1 = new Date(dateStr); - if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps - if (d1 === 'Invalid Date') return ''; - - var months = w2utils.settings.shortmonths; - var d2 = new Date(); // today - var d3 = new Date(); - d3.setTime(d3.getTime() - 86400000); // yesterday - - var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear(); - var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear(); - var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear(); - - var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); - var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); - var dsp = dd1; - if (dd1 === dd2) dsp = time; - if (dd1 === dd3) dsp = w2utils.lang('Yesterday'); - - return ''+ dsp +''; - } - - function size (sizeStr) { - if (!w2utils.isFloat(sizeStr) || sizeStr === '') return ''; - sizeStr = parseFloat(sizeStr); - if (sizeStr === 0) return 0; - var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB']; - var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ); - return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + sizes[i]; - } - - function formatNumber (val, groupSymbol) { - var ret = ''; - if (groupSymbol == null) groupSymbol = w2utils.settings.groupSymbol || ','; - // check if this is a number - if (w2utils.isFloat(val) || w2utils.isInt(val) || w2utils.isMoney(val)) { - tmp = String(val).split('.'); - ret = String(tmp[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + groupSymbol); - if (tmp[1] != null) ret += '.' + tmp[1]; - } - return ret; - } - - function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String - var months = w2utils.settings.shortmonths; - var fullMonths = w2utils.settings.fullmonths; - if (!format) format = this.settings.date_format; - if (dateStr === '' || dateStr == null) return ''; - - var dt = new Date(dateStr); - if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps - if (dt === 'Invalid Date') return ''; - - var year = dt.getFullYear(); - var month = dt.getMonth(); - var date = dt.getDate(); - return format.toLowerCase() - .replace('month', w2utils.settings.fullmonths[month]) - .replace('mon', w2utils.settings.shortmonths[month]) - .replace(/yyyy/g, year) - .replace(/yyy/g, year) - .replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2)) - .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceeded by a letter - .replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1)) - .replace(/dd/g, (date < 10 ? '0' : '') + date) - .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceeded by a letter - } - - function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String - var months = w2utils.settings.shortmonths; - var fullMonths = w2utils.settings.fullmonths; - if (!format) format = (this.settings.time_format === 'h12' ? 'hh:mi pm' : 'h24:mi'); - if (dateStr === '' || dateStr == null) return ''; - - var dt = new Date(dateStr); - if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps - if (w2utils.isTime(dateStr)) { - var tmp = w2utils.isTime(dateStr, true); - dt = new Date(); - dt.setHours(tmp.hours); - dt.setMinutes(tmp.minutes); - } - if (dt === 'Invalid Date') return ''; - - var type = 'am'; - var hour = dt.getHours(); - var h24 = dt.getHours(); - var min = dt.getMinutes(); - var sec = dt.getSeconds(); - if (min < 10) min = '0' + min; - if (sec < 10) sec = '0' + sec; - if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { - if (hour >= 12) type = 'pm'; - if (hour > 12) hour = hour - 12; - } - return format.toLowerCase() - .replace('am', type) - .replace('pm', type) - .replace('hh', hour) - .replace('h24', h24) - .replace('mm', min) - .replace('mi', min) - .replace('ss', sec) - .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceeded by a letter - } - - function formatDateTime(dateStr, format) { - var fmt; - if (typeof format !== 'string') { - fmt = [this.settings.date_format, this.settings.time_format]; - } else { - fmt = format.split('|'); - } - return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]); - } - - function stripTags (html) { - if (html === null) return html; - switch (typeof html) { - case 'number': - break; - case 'string': - html = $.trim(String(html).replace(/(<([^>]+)>)/ig, "")); - break; - case 'object': - for (var a in html) html[a] = this.stripTags(html[a]); - break; - } - return html; - } - - function encodeTags (html) { - if (html === null) return html; - switch (typeof html) { - case 'number': - break; - case 'string': - html = String(html).replace(/&/g, "&").replace(/>/g, ">").replace(/\|\/? {}\\])/g, '\\$1'); - } - - function base64encode (input) { - var output = ""; - var chr1, chr2, chr3, enc1, enc2, enc3, enc4; - var i = 0; - var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - input = utf8_encode(input); - - while (i < input.length) { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); - } - - function utf8_encode (string) { - var string = String(string).replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - } - return utftext; - } - - return output; - } - - function base64decode (input) { - var output = ""; - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0; - var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - enc1 = keyStr.indexOf(input.charAt(i++)); - enc2 = keyStr.indexOf(input.charAt(i++)); - enc3 = keyStr.indexOf(input.charAt(i++)); - enc4 = keyStr.indexOf(input.charAt(i++)); - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - output = output + String.fromCharCode(chr1); - if (enc3 !== 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 !== 64) { - output = output + String.fromCharCode(chr3); - } - } - output = utf8_decode(output); - - function utf8_decode (utftext) { - var string = ""; - var i = 0; - var c = 0, c2, c3; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string += String.fromCharCode(c); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return string; - } - - return output; - } - - function transition (div_old, div_new, type, callBack) { - var width = $(div_old).width(); - var height = $(div_old).height(); - var time = 0.5; - - if (!div_old || !div_new) { - console.log('ERROR: Cannot do transition when one of the divs is null'); - return; - } - - div_old.parentNode.style.cssText += cross('perspective', '700px') +'; overflow: hidden;'; - div_old.style.cssText += '; position: absolute; z-index: 1019; '+ cross('backface-visibility', 'hidden'); - div_new.style.cssText += '; position: absolute; z-index: 1020; '+ cross('backface-visibility', 'hidden'); - - switch (type) { - case 'slide-left': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d('+ width + 'px, 0, 0)', 'translate('+ width +'px, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); - }, 1); - break; - - case 'slide-right': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0px, 0, 0)', 'translate(0px, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d('+ width +'px, 0, 0)', 'translate('+ width +'px, 0)'); - }, 1); - break; - - case 'slide-down': - // init divs - div_old.style.cssText += 'overflow: hidden; z-index: 1; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; z-index: 0; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); - }, 1); - break; - - case 'slide-up': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - }, 1); - break; - - case 'flip-left': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(-180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(180deg)'); - }, 1); - break; - - case 'flip-right': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(-180deg)'); - }, 1); - break; - - case 'flip-down': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(-180deg)'); - }, 1); - break; - - case 'flip-up': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(-180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(180deg)'); - }, 1); - break; - - case 'pop-in': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') + '; '+ cross('transform', 'scale(.8)') + '; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time+'s') +';'; - }, 1); - break; - - case 'pop-out': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1.7)') +'; opacity: 0;'; - }, 1); - break; - - default: - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time +'s') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time +'s'); - }, 1); - break; - } - - setTimeout(function () { - if (type === 'slide-down') { - $(div_old).css('z-index', '1019'); - $(div_new).css('z-index', '1020'); - } - if (div_new) { - $(div_new).css({ - 'opacity': '1', - '-webkit-transition': '', - '-moz-transition': '', - '-ms-transition': '', - '-o-transition': '', - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '', - '-webkit-backface-visibility': '', - '-moz-backface-visibility': '', - '-ms-backface-visibility': '', - '-o-backface-visibility': '' - }); - } - if (div_old) { - $(div_old).css({ - 'opacity': '1', - '-webkit-transition': '', - '-moz-transition': '', - '-ms-transition': '', - '-o-transition': '', - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '', - '-webkit-backface-visibility': '', - '-moz-backface-visibility': '', - '-ms-backface-visibility': '', - '-o-backface-visibility': '' - }); - if (div_old.parentNode) $(div_old.parentNode).css({ - '-webkit-perspective': '', - '-moz-perspective': '', - '-ms-perspective': '', - '-o-perspective': '' - }); - } - if (typeof callBack === 'function') callBack(); - }, time * 1000); - - function cross(property, value, none_webkit_value) { - var isWebkit=!!window.webkitURL; // jQuery no longer supports $.browser - RR - if (!isWebkit && typeof none_webkit_value !== 'undefined') value = none_webkit_value; - return ';'+ property +': '+ value +'; -webkit-'+ property +': '+ value +'; -moz-'+ property +': '+ value +'; '+ - '-ms-'+ property +': '+ value +'; -o-'+ property +': '+ value +';'; - } - } - - function lock (box, msg, spinner) { - var options = {}; - if (typeof msg === 'object') { - options = msg; - } else { - options.msg = msg; - options.spinner = spinner; - } - if (!options.msg && options.msg !== 0) options.msg = ''; - w2utils.unlock(box); - $(box).prepend( - '
'+ - '
' - ); - var $lock = $(box).find('.w2ui-lock'); - var mess = $(box).find('.w2ui-lock-msg'); - if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' }); - if (options.spinner === true) options.msg = '
' + options.msg; - if (options.opacity != null) $lock.css('opacity', options.opacity); - if (typeof $lock.fadeIn == 'function') { - $lock.fadeIn(200); - mess.html(options.msg).fadeIn(200); - } else { - $lock.show(); - mess.html(options.msg).show(0); - } - // hide all tags (do not hide overlays as the form can be in overlay) - $().w2tag(); - } - - function unlock (box) { - $(box).find('.w2ui-lock').remove(); - $(box).find('.w2ui-lock-msg').remove(); - } - - function getSize (el, type) { - var $el = $(el); - var bwidth = { - left: parseInt($el.css('border-left-width')) || 0, - right: parseInt($el.css('border-right-width')) || 0, - top: parseInt($el.css('border-top-width')) || 0, - bottom: parseInt($el.css('border-bottom-width')) || 0 - }; - var mwidth = { - left: parseInt($el.css('margin-left')) || 0, - right: parseInt($el.css('margin-right')) || 0, - top: parseInt($el.css('margin-top')) || 0, - bottom: parseInt($el.css('margin-bottom')) || 0 - }; - var pwidth = { - left: parseInt($el.css('padding-left')) || 0, - right: parseInt($el.css('padding-right')) || 0, - top: parseInt($el.css('padding-top')) || 0, - bottom: parseInt($el.css('padding-bottom')) || 0 - }; - switch (type) { - case 'top': return bwidth.top + mwidth.top + pwidth.top; - case 'bottom': return bwidth.bottom + mwidth.bottom + pwidth.bottom; - case 'left': return bwidth.left + mwidth.left + pwidth.left; - case 'right': return bwidth.right + mwidth.right + pwidth.right; - case 'width': return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width()); - case 'height': return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height()); - case '+width': return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right; - case '+height': return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom; - } - return 0; - } - - function lang (phrase) { - var translation = this.settings.phrases[phrase]; - if (translation == null) return phrase; else return translation; - } - - function locale (locale) { - if (!locale) locale = 'en-us'; - if (locale.length === 5) locale = 'locale/'+ locale +'.json'; - // load from the file - $.ajax({ - url : locale, - type : "GET", - dataType: "JSON", - async : false, - cache : false, - success : function (data, status, xhr) { - w2utils.settings = $.extend(true, w2utils.settings, data); - // apply translation to some prototype functions - var p = w2obj.grid.prototype; - for (var b in p.buttons) { - p.buttons[b].caption = w2utils.lang(p.buttons[b].caption); - p.buttons[b].hint = w2utils.lang(p.buttons[b].hint); - } - p.msgDelete = w2utils.lang(p.msgDelete); - p.msgNotJSON = w2utils.lang(p.msgNotJSON); - p.msgRefresh = w2utils.lang(p.msgRefresh); - }, - error : function (xhr, status, msg) { - console.log('ERROR: Cannot load locale '+ locale); - } - }); - } - - function scrollBarSize () { - if (tmp.scrollBarSize) return tmp.scrollBarSize; - var html = - '
'+ - '
1
'+ - '
'; - $('body').append(html); - tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width(); - $('#_scrollbar_width').remove(); - if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+ - return tmp.scrollBarSize; - } + var tmp = {}; // for some temp variables + var obj = { + settings : { + "locale" : "en-us", + "date_format" : "m/d/yyyy", + "date_display" : "Mon d, yyyy", + "time_format" : "h12", + "currencyPrefix" : "$", + "currencySuffix" : "", + "currencyPrecision" : 2, + "groupSymbol" : ",", + "shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + "fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + "shortdays" : ["M", "T", "W", "T", "F", "S", "S"], + "fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + "RESTfull" : false, + "phrases" : {} // empty object for english phrases + }, + isInt : isInt, + isFloat : isFloat, + isMoney : isMoney, + isHex : isHex, + isAlphaNumeric : isAlphaNumeric, + isEmail : isEmail, + isDate : isDate, + isTime : isTime, + age : age, + date : date, + size : size, + formatNumber : formatNumber, + formatDate : formatDate, + formatTime : formatTime, + formatDateTime : formatDateTime, + stripTags : stripTags, + encodeTags : encodeTags, + escapeId : escapeId, + base64encode : base64encode, + base64decode : base64decode, + transition : transition, + lock : lock, + unlock : unlock, + lang : lang, + locale : locale, + getSize : getSize, + scrollBarSize : scrollBarSize, + checkName : checkName, + checkUniqueId : checkUniqueId + }; + return obj; + + function isInt (val) { + var re = /^[-+]?[0-9]+$/; + return re.test(val); + } + + function isFloat (val) { + return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)); + } + + function isMoney (val) { + var se = w2utils.settings; + var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +'[-+]?[0-9]*[\.]?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i'); + if (typeof val === 'string') { + val = val.replace(new RegExp(se.groupSymbol, 'g'), ''); + } + if (typeof val === 'object' || val === '') return false; + return re.test(val); + } + + function isHex (val) { + var re = /^[a-fA-F0-9]+$/; + return re.test(val); + } + + function isAlphaNumeric (val) { + var re = /^[a-zA-Z0-9_-]+$/; + return re.test(val); + } + + function isEmail (val) { + var email = /^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; + return email.test(val); + } + + function isDate (val, format, retDate) { + if (!val) return false; + + var dt = 'Invalid Date'; + var month, day, year; + + if (format == null) format = w2utils.settings.date_format; + + if (typeof val.getUTCFullYear === 'function' && typeof val.getUTCMonth === 'function' && typeof val.getUTCDate === 'function') { + year = val.getUTCFullYear(); + month = val.getUTCMonth(); + day = val.getUTCDate(); + } else if (typeof val.getFullYear === 'function' && typeof val.getMonth === 'function' && typeof val.getDate === 'function') { + year = val.getFullYear(); + month = val.getMonth(); + day = val.getDate(); + } else { + val = String(val); + // convert month formats + if (RegExp('mon', 'ig').test(format)) { + format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) { + var t = w2utils.settings.fullmonths[m]; + val = val.replace(RegExp(t, 'ig'), (parseInt(m) + 1)).replace(RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)); + } + } + // format date + var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); + var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); + if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + } + if (!isInt(year)) return false; + if (!isInt(month)) return false; + if (!isInt(day)) return false; + year = +year; + month = +month; + day = +day; + dt = new Date(year, month - 1, day); + // do checks + if (month == null) return false; + if (dt === 'Invalid Date') return false; + if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false; + if (retDate === true) return dt; else return true; + } + + function isTime (val, retTime) { + // Both formats 10:20pm and 22:20 + if (val == null) return false; + var max, pm; + // -- process american format + val = String(val); + val = val.toUpperCase(); + pm = val.indexOf('PM') >= 0; + var ampm = (pm || val.indexOf('AM') >= 0); + if (ampm) max = 12; else max = 24; + val = val.replace('AM', '').replace('PM', ''); + val = $.trim(val); + // --- + var tmp = val.split(':'); + var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0); + // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: + if ((!ampm || tmp.length !== 1) && tmp.length !== 2) { return false; } + if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; } + if (tmp.length === 2 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; } + // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). + // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. + if (!ampm && max === h && m !== 0) { return false; } + if (ampm && tmp.length === 1 && h === 0) { return false; } + + if (retTime === true) { + if (pm) h += 12; + return { + hours: h, + minutes: m + }; + } + return true; + } + + function age (dateStr) { + if (dateStr === '' || dateStr == null) return ''; + var d1 = new Date(dateStr); + if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps + if (d1 === 'Invalid Date') return ''; + + var d2 = new Date(); + var sec = (d2.getTime() - d1.getTime()) / 1000; + var amount = ''; + var type = ''; + if (sec < 0) { + amount = 'future'; + type = ''; + } else if (sec < 60) { + amount = Math.floor(sec); + type = 'sec'; + if (sec < 0) { amount = 0; type = 'sec'; } + } else if (sec < 60*60) { + amount = Math.floor(sec/60); + type = 'min'; + } else if (sec < 24*60*60) { + amount = Math.floor(sec/60/60); + type = 'hour'; + } else if (sec < 30*24*60*60) { + amount = Math.floor(sec/24/60/60); + type = 'day'; + } else if (sec < 12*30*24*60*60) { + amount = Math.floor(sec/30/24/60/60*10)/10; + type = 'month'; + } else if (sec >= 12*30*24*60*60) { + amount = Math.floor(sec/12/30/24/60/60*10)/10; + type = 'year'; + } + return amount + ' ' + type + (amount > 1 ? 's' : ''); + } + + function date (dateStr) { + if (dateStr === '' || dateStr == null) return ''; + var d1 = new Date(dateStr); + if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps + if (d1 === 'Invalid Date') return ''; + + var months = w2utils.settings.shortmonths; + var d2 = new Date(); // today + var d3 = new Date(); + d3.setTime(d3.getTime() - 86400000); // yesterday + + var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear(); + var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear(); + var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear(); + + var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var dsp = dd1; + if (dd1 === dd2) dsp = time; + if (dd1 === dd3) dsp = w2utils.lang('Yesterday'); + + return ''+ dsp +''; + } + + function size (sizeStr) { + if (!w2utils.isFloat(sizeStr) || sizeStr === '') return ''; + sizeStr = parseFloat(sizeStr); + if (sizeStr === 0) return 0; + var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB']; + var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ); + return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + sizes[i]; + } + + function formatNumber (val, groupSymbol) { + var ret = ''; + if (groupSymbol == null) groupSymbol = w2utils.settings.groupSymbol || ','; + // check if this is a number + if (w2utils.isFloat(val) || w2utils.isInt(val) || w2utils.isMoney(val)) { + tmp = String(val).split('.'); + ret = String(tmp[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + groupSymbol); + if (tmp[1] != null) ret += '.' + tmp[1]; + } + return ret; + } + + function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + var months = w2utils.settings.shortmonths; + var fullMonths = w2utils.settings.fullmonths; + if (!format) format = this.settings.date_format; + if (dateStr === '' || dateStr == null) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (dt === 'Invalid Date') return ''; + + var year = dt.getFullYear(); + var month = dt.getMonth(); + var date = dt.getDate(); + return format.toLowerCase() + .replace('month', w2utils.settings.fullmonths[month]) + .replace('mon', w2utils.settings.shortmonths[month]) + .replace(/yyyy/g, year) + .replace(/yyy/g, year) + .replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2)) + .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceeded by a letter + .replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1)) + .replace(/dd/g, (date < 10 ? '0' : '') + date) + .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceeded by a letter + } + + function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + var months = w2utils.settings.shortmonths; + var fullMonths = w2utils.settings.fullmonths; + if (!format) format = (this.settings.time_format === 'h12' ? 'hh:mi pm' : 'h24:mi'); + if (dateStr === '' || dateStr == null) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (w2utils.isTime(dateStr)) { + var tmp = w2utils.isTime(dateStr, true); + dt = new Date(); + dt.setHours(tmp.hours); + dt.setMinutes(tmp.minutes); + } + if (dt === 'Invalid Date') return ''; + + var type = 'am'; + var hour = dt.getHours(); + var h24 = dt.getHours(); + var min = dt.getMinutes(); + var sec = dt.getSeconds(); + if (min < 10) min = '0' + min; + if (sec < 10) sec = '0' + sec; + if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { + if (hour >= 12) type = 'pm'; + if (hour > 12) hour = hour - 12; + } + return format.toLowerCase() + .replace('am', type) + .replace('pm', type) + .replace('hh', hour) + .replace('h24', h24) + .replace('mm', min) + .replace('mi', min) + .replace('ss', sec) + .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceeded by a letter + } + + function formatDateTime(dateStr, format) { + var fmt; + if (typeof format !== 'string') { + fmt = [this.settings.date_format, this.settings.time_format]; + } else { + fmt = format.split('|'); + } + return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]); + } + + function stripTags (html) { + if (html === null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = $.trim(String(html).replace(/(<([^>]+)>)/ig, "")); + break; + case 'object': + for (var a in html) html[a] = this.stripTags(html[a]); + break; + } + return html; + } + + function encodeTags (html) { + if (html === null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = String(html).replace(/&/g, "&").replace(/>/g, ">").replace(/\|\/? {}\\])/g, '\\$1'); + } + + function base64encode (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = utf8_encode(input); + + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); + } + + function utf8_encode (string) { + var string = String(string).replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + } + + return output; + } + + function base64decode (input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 !== 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 !== 64) { + output = output + String.fromCharCode(chr3); + } + } + output = utf8_decode(output); + + function utf8_decode (utftext) { + var string = ""; + var i = 0; + var c = 0, c2, c3; + + while ( i < utftext.length ) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + + return string; + } + + return output; + } + + function transition (div_old, div_new, type, callBack) { + var width = $(div_old).width(); + var height = $(div_old).height(); + var time = 0.5; + + if (!div_old || !div_new) { + console.log('ERROR: Cannot do transition when one of the divs is null'); + return; + } + + div_old.parentNode.style.cssText += cross('perspective', '700px') +'; overflow: hidden;'; + div_old.style.cssText += '; position: absolute; z-index: 1019; '+ cross('backface-visibility', 'hidden'); + div_new.style.cssText += '; position: absolute; z-index: 1020; '+ cross('backface-visibility', 'hidden'); + + switch (type) { + case 'slide-left': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d('+ width + 'px, 0, 0)', 'translate('+ width +'px, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); + }, 1); + break; + + case 'slide-right': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0px, 0, 0)', 'translate(0px, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d('+ width +'px, 0, 0)', 'translate('+ width +'px, 0)'); + }, 1); + break; + + case 'slide-down': + // init divs + div_old.style.cssText += 'overflow: hidden; z-index: 1; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; z-index: 0; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); + }, 1); + break; + + case 'slide-up': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + }, 1); + break; + + case 'flip-left': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(-180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(180deg)'); + }, 1); + break; + + case 'flip-right': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(-180deg)'); + }, 1); + break; + + case 'flip-down': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(-180deg)'); + }, 1); + break; + + case 'flip-up': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(-180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(180deg)'); + }, 1); + break; + + case 'pop-in': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') + '; '+ cross('transform', 'scale(.8)') + '; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time+'s') +';'; + }, 1); + break; + + case 'pop-out': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1.7)') +'; opacity: 0;'; + }, 1); + break; + + default: + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time +'s') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time +'s'); + }, 1); + break; + } + + setTimeout(function () { + if (type === 'slide-down') { + $(div_old).css('z-index', '1019'); + $(div_new).css('z-index', '1020'); + } + if (div_new) { + $(div_new).css({ + 'opacity': '1', + '-webkit-transition': '', + '-moz-transition': '', + '-ms-transition': '', + '-o-transition': '', + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '', + '-webkit-backface-visibility': '', + '-moz-backface-visibility': '', + '-ms-backface-visibility': '', + '-o-backface-visibility': '' + }); + } + if (div_old) { + $(div_old).css({ + 'opacity': '1', + '-webkit-transition': '', + '-moz-transition': '', + '-ms-transition': '', + '-o-transition': '', + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '', + '-webkit-backface-visibility': '', + '-moz-backface-visibility': '', + '-ms-backface-visibility': '', + '-o-backface-visibility': '' + }); + if (div_old.parentNode) $(div_old.parentNode).css({ + '-webkit-perspective': '', + '-moz-perspective': '', + '-ms-perspective': '', + '-o-perspective': '' + }); + } + if (typeof callBack === 'function') callBack(); + }, time * 1000); + + function cross(property, value, none_webkit_value) { + var isWebkit=!!window.webkitURL; // jQuery no longer supports $.browser - RR + if (!isWebkit && typeof none_webkit_value !== 'undefined') value = none_webkit_value; + return ';'+ property +': '+ value +'; -webkit-'+ property +': '+ value +'; -moz-'+ property +': '+ value +'; '+ + '-ms-'+ property +': '+ value +'; -o-'+ property +': '+ value +';'; + } + } + + function lock (box, msg, spinner) { + var options = {}; + if (typeof msg === 'object') { + options = msg; + } else { + options.msg = msg; + options.spinner = spinner; + } + if (!options.msg && options.msg !== 0) options.msg = ''; + w2utils.unlock(box); + $(box).prepend( + '
'+ + '
' + ); + var $lock = $(box).find('.w2ui-lock'); + var mess = $(box).find('.w2ui-lock-msg'); + if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' }); + if (options.spinner === true) options.msg = '
' + options.msg; + if (options.opacity != null) $lock.css('opacity', options.opacity); + if (typeof $lock.fadeIn == 'function') { + $lock.fadeIn(200); + mess.html(options.msg).fadeIn(200); + } else { + $lock.show(); + mess.html(options.msg).show(0); + } + // hide all tags (do not hide overlays as the form can be in overlay) + $().w2tag(); + } + + function unlock (box) { + $(box).find('.w2ui-lock').remove(); + $(box).find('.w2ui-lock-msg').remove(); + } + + function getSize (el, type) { + var $el = $(el); + var bwidth = { + left : parseInt($el.css('border-left-width')) || 0, + right : parseInt($el.css('border-right-width')) || 0, + top : parseInt($el.css('border-top-width')) || 0, + bottom : parseInt($el.css('border-bottom-width')) || 0 + }; + var mwidth = { + left : parseInt($el.css('margin-left')) || 0, + right : parseInt($el.css('margin-right')) || 0, + top : parseInt($el.css('margin-top')) || 0, + bottom : parseInt($el.css('margin-bottom')) || 0 + }; + var pwidth = { + left : parseInt($el.css('padding-left')) || 0, + right : parseInt($el.css('padding-right')) || 0, + top : parseInt($el.css('padding-top')) || 0, + bottom : parseInt($el.css('padding-bottom')) || 0 + }; + switch (type) { + case 'top' : return bwidth.top + mwidth.top + pwidth.top; + case 'bottom' : return bwidth.bottom + mwidth.bottom + pwidth.bottom; + case 'left' : return bwidth.left + mwidth.left + pwidth.left; + case 'right' : return bwidth.right + mwidth.right + pwidth.right; + case 'width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width()); + case 'height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height()); + case '+width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right; + case '+height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom; + } + return 0; + } + + function lang (phrase) { + var translation = this.settings.phrases[phrase]; + if (translation == null) return phrase; else return translation; + } + + function locale (locale) { + if (!locale) locale = 'en-us'; + if (locale.length === 5) locale = 'locale/'+ locale +'.json'; + // load from the file + $.ajax({ + url : locale, + type : "GET", + dataType : "JSON", + async : false, + cache : false, + success : function (data, status, xhr) { + w2utils.settings = $.extend(true, w2utils.settings, data); + // apply translation to some prototype functions + var p = w2obj.grid.prototype; + for (var b in p.buttons) { + p.buttons[b].caption = w2utils.lang(p.buttons[b].caption); + p.buttons[b].hint = w2utils.lang(p.buttons[b].hint); + } + p.msgDelete = w2utils.lang(p.msgDelete); + p.msgNotJSON = w2utils.lang(p.msgNotJSON); + p.msgRefresh = w2utils.lang(p.msgRefresh); + }, + error : function (xhr, status, msg) { + console.log('ERROR: Cannot load locale '+ locale); + } + }); + } + + function scrollBarSize () { + if (tmp.scrollBarSize) return tmp.scrollBarSize; + var html = + '
'+ + '
1
'+ + '
'; + $('body').append(html); + tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width(); + $('#_scrollbar_width').remove(); + if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+ + return tmp.scrollBarSize; + } function checkName (params, component) { // was w2checkNameParam - if (!params || typeof params.name === 'undefined') { - console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().'); - return false; - } - if (typeof w2ui[params.name] !== 'undefined') { - console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').'); - return false; - } - if (!w2utils.isAlphaNumeric(params.name)) { - console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); - return false; - } - return true; - } - - function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId - if (!$.isArray(items)) items = [items]; - for (var i = 0; i < items.length; i++) { - if (items[i].id === id) { - console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')'); - return false; - } - } - return true; - } + if (!params || typeof params.name === 'undefined') { + console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().'); + return false; + } + if (typeof w2ui[params.name] !== 'undefined') { + console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').'); + return false; + } + if (!w2utils.isAlphaNumeric(params.name)) { + console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); + return false; + } + return true; + } + + function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId + if (!$.isArray(items)) items = [items]; + for (var i = 0; i < items.length; i++) { + if (items[i].id === id) { + console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')'); + return false; + } + } + return true; + } })(); /*********************************************************** @@ -876,102 +876,102 @@ var w2utils = (function () { w2utils.event = { - on: function (eventData, handler) { - if (!$.isPlainObject(eventData)) eventData = { type: eventData }; - eventData = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, eventData); - - if (!eventData.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; } - if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; } - this.handlers.push({ event: eventData, handler: handler }); - }, - - off: function (eventData, handler) { - if (!$.isPlainObject(eventData)) eventData = { type: eventData }; - eventData = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, eventData); - - if (!eventData.type) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; } - if (!handler) { handler = null; } - // remove handlers - var newHandlers = []; - for (var h = 0, len = this.handlers.length; h < len; h++) { - var t = this.handlers[h]; - if ((t.event.type === eventData.type || eventData.type === '*') && - (t.event.target === eventData.target || eventData.target === null) && - (t.handler === handler || handler === null)) - { - // match - } else { - newHandlers.push(t); - } - } - this.handlers = newHandlers; - }, - - trigger: function (eventData) { - var eventData = $.extend({ type: null, phase: 'before', target: null }, eventData, { - isStopped: false, isCancelled: false, - preventDefault : function () { this.isCancelled = true; }, - stopPropagation : function () { this.isStopped = true; } - }); - if (eventData.phase === 'before') eventData.onComplete = null; - var args, fun, tmp; - if (eventData.target == null) eventData.target = null; - // process events in REVERSE order - for (var h = this.handlers.length-1; h >= 0; h--) { - var item = this.handlers[h]; - if ((item.event.type === eventData.type || item.event.type === '*') && - (item.event.target === eventData.target || item.event.target === null) && - (item.event.execute === eventData.phase || item.event.execute === '*' || item.event.phase === '*')) - { - eventData = $.extend({}, item.event, eventData); - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(item.handler); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - item.handler.call(this, eventData.target, eventData); // old way for back compatibility - } else { - item.handler.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true - } - } - // main object events - var funName = 'on' + eventData.type.substr(0,1).toUpperCase() + eventData.type.substr(1); - if (eventData.phase === 'before' && typeof this[funName] === 'function') { - fun = this[funName]; - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(fun); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - fun.call(this, eventData.target, eventData); // old way for back compatibility - } else { - fun.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true - } - // item object events - if (eventData.object != null && eventData.phase === 'before' && - typeof eventData.object[funName] === 'function') - { - fun = eventData.object[funName]; - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(fun); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - fun.call(this, eventData.target, eventData); // old way for back compatibility - } else { - fun.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; - } - // execute onComplete - if (eventData.phase === 'after' && typeof eventData.onComplete === 'function') eventData.onComplete.call(this, eventData); - - return eventData; - } + on: function (eventData, handler) { + if (!$.isPlainObject(eventData)) eventData = { type: eventData }; + eventData = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, eventData); + + if (!eventData.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; } + if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; } + this.handlers.push({ event: eventData, handler: handler }); + }, + + off: function (eventData, handler) { + if (!$.isPlainObject(eventData)) eventData = { type: eventData }; + eventData = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, eventData); + + if (!eventData.type) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; } + if (!handler) { handler = null; } + // remove handlers + var newHandlers = []; + for (var h = 0, len = this.handlers.length; h < len; h++) { + var t = this.handlers[h]; + if ((t.event.type === eventData.type || eventData.type === '*') && + (t.event.target === eventData.target || eventData.target === null) && + (t.handler === handler || handler === null)) + { + // match + } else { + newHandlers.push(t); + } + } + this.handlers = newHandlers; + }, + + trigger: function (eventData) { + var eventData = $.extend({ type: null, phase: 'before', target: null }, eventData, { + isStopped: false, isCancelled: false, + preventDefault : function () { this.isCancelled = true; }, + stopPropagation : function () { this.isStopped = true; } + }); + if (eventData.phase === 'before') eventData.onComplete = null; + var args, fun, tmp; + if (eventData.target == null) eventData.target = null; + // process events in REVERSE order + for (var h = this.handlers.length-1; h >= 0; h--) { + var item = this.handlers[h]; + if ((item.event.type === eventData.type || item.event.type === '*') && + (item.event.target === eventData.target || item.event.target === null) && + (item.event.execute === eventData.phase || item.event.execute === '*' || item.event.phase === '*')) + { + eventData = $.extend({}, item.event, eventData); + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(item.handler); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + item.handler.call(this, eventData.target, eventData); // old way for back compatibility + } else { + item.handler.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true + } + } + // main object events + var funName = 'on' + eventData.type.substr(0,1).toUpperCase() + eventData.type.substr(1); + if (eventData.phase === 'before' && typeof this[funName] === 'function') { + fun = this[funName]; + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, eventData.target, eventData); // old way for back compatibility + } else { + fun.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true + } + // item object events + if (eventData.object != null && eventData.phase === 'before' && + typeof eventData.object[funName] === 'function') + { + fun = eventData.object[funName]; + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, eventData.target, eventData); // old way for back compatibility + } else { + fun.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; + } + // execute onComplete + if (eventData.phase === 'after' && typeof eventData.onComplete === 'function') eventData.onComplete.call(this, eventData); + + return eventData; + } }; /*********************************************************** @@ -983,52 +983,52 @@ w2utils.event = { *********************************************************/ w2utils.keyboard = (function (obj) { - // private scope - var w2ui_name = null; - - obj.active = active; - obj.clear = clear; - obj.register = register; - - init(); - return obj; - - function init() { - $(document).on('keydown', keydown); - $(document).on('mousedown', mousedown); - } - - function keydown (event) { - var tag = event.target.tagName; - if ($.inArray(tag, ['INPUT', 'SELECT', 'TEXTAREA']) !== -1) return; - if ($(event.target).prop('contenteditable') === 'true') return; - if (!w2ui_name) return; - // pass to appropriate widget - if (w2ui[w2ui_name] && typeof w2ui[w2ui_name].keydown === 'function') { - w2ui[w2ui_name].keydown.call(w2ui[w2ui_name], event); - } - } - - function mousedown (event) { - var tag = event.target.tagName; - var obj = $(event.target).parents('.w2ui-reset'); - if (obj.length > 0) { - var name = obj.attr('name'); - if (w2ui[name] && w2ui[name].keyboard) w2ui_name = name; - } - } - - function active (new_w2ui_name) { - if (typeof new_w2ui_name !== 'undefined') w2ui_name = new_w2ui_name; - return w2ui_name; - } - - function clear () { - w2ui_name = null; - } - - function register () { - } + // private scope + var w2ui_name = null; + + obj.active = active; + obj.clear = clear; + obj.register = register; + + init(); + return obj; + + function init() { + $(document).on('keydown', keydown); + $(document).on('mousedown', mousedown); + } + + function keydown (event) { + var tag = event.target.tagName; + if ($.inArray(tag, ['INPUT', 'SELECT', 'TEXTAREA']) !== -1) return; + if ($(event.target).prop('contenteditable') === 'true') return; + if (!w2ui_name) return; + // pass to appropriate widget + if (w2ui[w2ui_name] && typeof w2ui[w2ui_name].keydown === 'function') { + w2ui[w2ui_name].keydown.call(w2ui[w2ui_name], event); + } + } + + function mousedown (event) { + var tag = event.target.tagName; + var obj = $(event.target).parents('.w2ui-reset'); + if (obj.length > 0) { + var name = obj.attr('name'); + if (w2ui[name] && w2ui[name].keyboard) w2ui_name = name; + } + } + + function active (new_w2ui_name) { + if (typeof new_w2ui_name !== 'undefined') w2ui_name = new_w2ui_name; + return w2ui_name; + } + + function clear () { + w2ui_name = null; + } + + function register () { + } })({}); @@ -1040,2721 +1040,2721 @@ w2utils.keyboard = (function (obj) { (function () { - $.fn.w2render = function (name) { - if ($(this).length > 0) { - if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]); - if (typeof name === 'object') name.render($(this)[0]); - } - }; - - $.fn.w2destroy = function (name) { - if (!name && this.length > 0) name = this.attr('name'); - if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy(); - if (typeof name === 'object') name.destroy(); - }; - - $.fn.w2marker = function (str) { - if (str === '' || str == null) { // remove marker - return $(this).each(function (index, el) { - el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark - }); - } else { // add marker - return $(this).each(function (index, el) { - if (typeof str === 'string') str = [str]; - el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark - for (var s in str) { - var tmp = str[s]; - if (typeof tmp !== 'string') tmp = String(tmp); - // escape regex special chars - tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&').replace(//g, '<'); - var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags - el.innerHTML = el.innerHTML.replace(regex, replaceValue); - } - function replaceValue(matched) { // mark new - return '' + matched + ''; - } - }); - } - }; - - // -- w2tag - appears on the right side from element, there can be multiple on screen at a time - - $.fn.w2tag = function (text, options) { - if (!$.isPlainObject(options)) options = {}; - if (!$.isPlainObject(options.css)) options.css = {}; - if (typeof options['class'] === 'undefined') options['class'] = ''; - // remove all tags - if ($(this).length === 0) { - $('.w2ui-tag').each(function (index, elem) { - var opt = $(elem).data('options'); - if (opt == null) opt = {}; - $($(elem).data('taged-el')).removeClass( opt['class'] ); - clearInterval($(elem).data('timer')); - $(elem).remove(); - }); - return; - } - return $(this).each(function (index, el) { - // show or hide tag - var tagOrigID = el.id; - var tagID = w2utils.escapeId(el.id); - if (text === '' || text == null) { - $('#w2ui-tag-'+tagID).css('opacity', 0); - setTimeout(function () { - // remmove element - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - $('#w2ui-tag-'+tagID).remove(); - }, 300); - } else { - // remove elements - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - $('#w2ui-tag-'+tagID).remove(); - // insert - $('body').append( - '
'); - - var timer = setInterval(function () { - // monitor if destroyed - if ($(el).length === 0 || ($(el).offset().left === 0 && $(el).offset().top === 0)) { - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - tmp_hide(); - return; - } - // monitor if moved - if ($('#w2ui-tag-'+tagID).data('position') !== ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) { - $('#w2ui-tag-'+tagID).css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s', - left: ($(el).offset().left + el.offsetWidth) + 'px', - top: $(el).offset().top + 'px' - }).data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top); - } - }, 100); - setTimeout(function () { - if (!$(el).offset()) return; - $('#w2ui-tag-'+tagID).css({ - opacity: '1', - left: ($(el).offset().left + el.offsetWidth) + 'px', - top: $(el).offset().top + 'px' - }).html('
'+ text +'
') - .data('text', text) - .data('taged-el', el) - .data('options', options) - .data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) - .data('timer', timer); - $(el).off('keypress', tmp_hide).on('keypress', tmp_hide).off('change', tmp_hide).on('change', tmp_hide) - .css(options.css).addClass(options['class']); - if (typeof options.onShow === 'function') options.onShow(); - }, 1); - var originalCSS = ''; - if ($(el).length > 0) originalCSS = $(el)[0].style.cssText; - // bind event to hide it - function tmp_hide() { - $tag = $('#w2ui-tag-'+tagID); - if ($tag.length <= 0) return; - clearInterval($tag.data('timer')); - $tag.remove(); - $(el).off('keypress', tmp_hide).removeClass(options['class']); - if ($(el).length > 0) $(el)[0].style.cssText = originalCSS; - if (typeof options.onHide === 'function') options.onHide(); - } - } - }); - }; - - // w2overlay - appears under the element, there can be only one at a time - - $.fn.w2overlay = function (html, options) { - var obj = this; - var name = ''; - var defaults = { - name : null, // it not null, then allows multiple concurent overlays - align : 'none', // can be none, left, right, both - left : 0, // offset left - top : 0, // offset top - tipLeft : 30, // tip offset left - width : 0, // fixed width - height : 0, // fixed height - maxWidth : null, // max width if any - maxHeight : null, // max height if any - style : '', // additional style for main div - 'class' : '', // additional class name for main dvi - onShow : null, // event on show - onHide : null, // event on hide - openAbove : false, // show abover control - tmp : {} - }; - if (!$.isPlainObject(options)) options = {}; - options = $.extend({}, defaults, options); - if (options.name) name = '-' + options.name; - // if empty then hide - var tmp_hide; - if (this.length === 0 || html === '' || html == null) { - if ($('#w2ui-overlay'+ name).length > 0) { - tmp_hide = $('#w2ui-overlay'+ name)[0].hide; - if (typeof tmp_hide === 'function') tmp_hide(); - } else { - $('#w2ui-overlay'+ name).remove(); - } - return $(this); - } - if ($('#w2ui-overlay'+ name).length > 0) { - tmp_hide = $('#w2ui-overlay'+ name)[0].hide; - $(document).off('click', tmp_hide); - if (typeof tmp_hide === 'function') tmp_hide(); - } - $('body').append( - '' - ); - // init - var div1 = $('#w2ui-overlay'+ name); - var div2 = div1.find(' > div'); - div2.html(html); - // pick bg color of first div - var bc = div2.css('background-color'); - if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css('background-color', bc); - - div1.data('element', obj.length > 0 ? obj[0] : null) - .data('options', options) - .data('position', $(obj).offset().left + 'x' + $(obj).offset().top) - .fadeIn('fast').on('mousedown', function (event) { - $('#w2ui-overlay'+ name).data('keepOpen', true); - if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName) === -1) event.preventDefault(); - }); - div1[0].hide = hide; - div1[0].resize = resize; - - // need time to display - resize(); - setTimeout(function () { - resize(); - $(document).off('click', hide).on('click', hide); - if (typeof options.onShow === 'function') options.onShow(); - }, 10); - - monitor(); - return $(this); - - // monitor position - function monitor() { - var tmp = $('#w2ui-overlay'+ name); - if (tmp.data('element') !== obj[0]) return; // it if it different overlay - if (tmp.length === 0) return; - var pos = $(obj).offset().left + 'x' + $(obj).offset().top; - if (tmp.data('position') !== pos) { - hide(); - } else { - setTimeout(monitor, 250); - } - } - - // click anywhere else hides the drop down - function hide () { - var div1 = $('#w2ui-overlay'+ name); - if (div1.data('keepOpen') === true) { - div1.removeData('keepOpen'); - return; - } - var result; - if (typeof options.onHide === 'function') result = options.onHide(); - if (result === false) return; - div1.remove(); - $(document).off('click', hide); - clearInterval(div1.data('timer')); - } - - function resize () { - var div1 = $('#w2ui-overlay'+ name); - var div2 = div1.find(' > div'); - // if goes over the screen, limit height and width - if (div1.length > 0) { - div2.height('auto').width('auto'); - // width/height - var overflowX = false; - var overflowY = false; - var h = div2.height(); - var w = div2.width(); - if (options.width && options.width < w) w = options.width; - if (w < 30) w = 30; - // if content of specific height - if (options.tmp.contentHeight) { - h = options.tmp.contentHeight; - div2.height(h); - setTimeout(function () { - if (div2.height() > div2.find('div.menu > table').height()) { - div2.find('div.menu').css('overflow-y', 'hidden'); - } - }, 1); - setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); - } - if (options.tmp.contentWidth) { - w = options.tmp.contentWidth; - div2.width(w); - setTimeout(function () { - if (div2.width() > div2.find('div.menu > table').width()) { - div2.find('div.menu').css('overflow-x', 'hidden'); - } - }, 1); - setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); - } - // alignment - switch (options.align) { - case 'both': - options.left = 17; - if (options.width === 0) options.width = w2utils.getSize($(obj), 'width'); - break; - case 'left': - options.left = 17; - break; - case 'right': - options.tipLeft = w - 45; - options.left = w2utils.getSize($(obj), 'width') - w + 10; - break; - } - // adjust position - var tmp = (w - 17) / 2; - var boxLeft = options.left; - var boxWidth = options.width; - var tipLeft = options.tipLeft; - if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto'); - if (tmp < 25) { - boxLeft = 25 - tmp; - tipLeft = Math.floor(tmp); - } - // Y coord - div1.css({ - top : (obj.offset().top + w2utils.getSize(obj, 'height') + options.top + 7) + 'px', - left : ((obj.offset().left > 25 ? obj.offset().left : 25) + boxLeft) + 'px', - 'min-width' : boxWidth, - 'min-height': (options.height ? options.height : 'auto') - }); - // $(window).height() - has a problem in FF20 - var maxHeight = window.innerHeight + $(document).scrollTop() - div2.offset().top - 7; - var maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; - if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) { - // show on top - maxHeight = div2.offset().top - $(document).scrollTop() - 7; - if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; - if (h > maxHeight) { - overflowY = true; - div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); - h = maxHeight; - } - div1.css('top', ($(obj).offset().top - h - 24 + options.top) + 'px'); - div1.find('>style').html( - '#w2ui-overlay'+ name +':before { display: none; margin-left: '+ parseInt(tipLeft) +'px; }'+ - '#w2ui-overlay'+ name +':after { display: block; margin-left: '+ parseInt(tipLeft) +'px; }' - ); - } else { - // show under - if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; - if (h > maxHeight) { - overflowY = true; - div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); - } - div1.find('>style').html( - '#w2ui-overlay'+ name +':before { display: block; margin-left: '+ parseInt(tipLeft) +'px; }'+ - '#w2ui-overlay'+ name +':after { display: none; margin-left: '+ parseInt(tipLeft) +'px; }' - ); - } - // check width - w = div2.width(); - maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; - if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth; - if (w > maxWidth && options.align !== 'both') { - options.align = 'right'; - setTimeout(function () { resize(); }, 1); - } - // check scroll bar - if (overflowY && overflowX) div2.width(w + w2utils.scrollBarSize() + 2); - } - } - }; - - $.fn.w2menu = function (menu, options) { - /* - ITEM STRUCTURE - item : { - id : null, - text : '', - style : '', - hidden : true - ... - } - */ - var defaults = { - index : null, // current selected - items : [], - render : null, - msgNoItems : 'No items', - onSelect : null, - tmp : {} - }; - var obj = this; - var name = ''; - if (menu === 'refresh') { - // if not show - call blur - if ($('#w2ui-overlay'+ name).length > 0) { - options = $.extend($.fn.w2menuOptions, options); - var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); - $('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML()); - $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); - mresize(); - } else { - $(this).w2menu(options); - } - } else { - if (arguments.length === 1) options = menu; else options.items = menu; - if (typeof options !== 'object') options = {}; - options = $.extend({}, defaults, options); - $.fn.w2menuOptions = options; - if (options.name) name = '-' + options.name; - if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select; - if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender; - // since only one overlay can exist at a time - $.fn.w2menuHandler = function (event, index) { - if (typeof options.onSelect === 'function') { - // need time so that menu first hides - setTimeout(function () { - options.onSelect({ - index : index, - item : options.items[index], - originalEvent: event - }); - }, 10); - } - }; - var html = ''; - if (options.search) { - html += - '
'+ - ' '+ - ' '+ - '
'; - options.style += ';background-color: #ECECEC'; - options.index = 0; - for (var i in options.items) options.items[i].hidden = false; - } - html += ''; - var ret = $(this).w2overlay(html, options); - setTimeout(function () { - $('#w2ui-overlay'+ name +' #menu-search') - .on('keyup', change) - .on('keydown', function (event) { - // cancel tab key - if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); } - }); - }, 200); - mresize(); - return ret; - } - - function mresize() { - setTimeout(function () { - // show selected - $('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected'); - var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']'); - var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); - cur.addClass('w2ui-selected'); - if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10); - if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width(); - $('#w2ui-overlay'+ name)[0].resize(); - // scroll into view - if (cur.length > 0) { - var top = cur[0].offsetTop - 5; // 5 is margin top - var el = $('#w2ui-overlay'+ name +' div.menu'); - var height = el.height(); - $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); - if (top < scrTop || top + cur.height() > scrTop + height) { - $('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); - } - } - }, 1); - } - - function change(event) { - var search = this.value; - var key = event.keyCode; - var cancel = false; - switch (key) { - case 13: // enter - $('#w2ui-overlay'+ name).remove(); - $.fn.w2menuHandler(event, options.index); - break; - case 9: // tab - case 27: // escape - $('#w2ui-overlay'+ name).remove(); - $.fn.w2menuHandler(event, -1); - break; - case 38: // up - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index--; - while (options.index > 0 && options.items[options.index].hidden) options.index--; - if (options.index === 0 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } - if (options.index < 0) options.index = 0; - cancel = true; - break; - case 40: // down - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index++; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (options.index === options.items.length-1 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index--; - } - if (options.index >= options.items.length) options.index = options.items.length - 1; - cancel = true; - break; - } - // filter - if (!cancel) { - var shown = 0; - for (var i in options.items) { - var item = options.items[i]; - var prefix = ''; - var suffix = ''; - if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^'; - if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$'; - try { - var re = new RegExp(prefix + search + suffix, 'i'); - if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true; - if (options.applyFilter !== true) item.hidden = false; - } catch (e) {} - // do not show selected items - if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true; - if (item.hidden !== true) shown++; - } - options.index = 0; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (shown <= 0) options.index = -1; - } - $(obj).w2menu('refresh', options); - mresize(); - } - - function getMenuHTML () { - if (options.spinner) { - return '
'+ - '
'+ - '
Loading...
'+ - '
'; - } - var count = 0; - var menu_html = ''; - var img = null, icon = null; - for (var f = 0; f < options.items.length; f++) { - var mitem = options.items[f]; - if (typeof mitem === 'string') { - mitem = { id: mitem, text: mitem }; - } else { - if (mitem.text != null && mitem.id == null) mitem.id = mitem.text; - if (mitem.text == null && mitem.id != null) mitem.text = mitem.id; - if (mitem.caption != null) mitem.text = mitem.caption; - img = mitem.img; - icon = mitem.icon; - if (img == null) img = null; - if (icon == null) icon = null; - } - if (mitem.hidden !== true) { - var imgd = ''; - var txt = mitem.text; - if (typeof options.render === 'function') txt = options.render(mitem, options); - if (img) imgd = ''; - if (icon) imgd = ''; - // render only if non-empty - if (typeof txt !== 'undefined' && txt !== '' && !(/^-+$/.test(txt))) { - var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd'); - if (options.altRows !== true) bg = ''; - menu_html += - ''+ - imgd + - ' '+ - ''; - count++; - } else { - // horizontal line - menu_html += ''; - } - } - options.items[f] = mitem; - } - if (count === 0) { - menu_html += ''; - } - menu_html += "
'+ txt +'
'+ options.msgNoItems +'
"; - return menu_html; - } - }; + $.fn.w2render = function (name) { + if ($(this).length > 0) { + if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]); + if (typeof name === 'object') name.render($(this)[0]); + } + }; + + $.fn.w2destroy = function (name) { + if (!name && this.length > 0) name = this.attr('name'); + if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy(); + if (typeof name === 'object') name.destroy(); + }; + + $.fn.w2marker = function (str) { + if (str === '' || str == null) { // remove marker + return $(this).each(function (index, el) { + el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark + }); + } else { // add marker + return $(this).each(function (index, el) { + if (typeof str === 'string') str = [str]; + el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark + for (var s in str) { + var tmp = str[s]; + if (typeof tmp !== 'string') tmp = String(tmp); + // escape regex special chars + tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&').replace(//g, '<'); + var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags + el.innerHTML = el.innerHTML.replace(regex, replaceValue); + } + function replaceValue(matched) { // mark new + return '' + matched + ''; + } + }); + } + }; + + // -- w2tag - appears on the right side from element, there can be multiple on screen at a time + + $.fn.w2tag = function (text, options) { + if (!$.isPlainObject(options)) options = {}; + if (!$.isPlainObject(options.css)) options.css = {}; + if (typeof options['class'] === 'undefined') options['class'] = ''; + // remove all tags + if ($(this).length === 0) { + $('.w2ui-tag').each(function (index, elem) { + var opt = $(elem).data('options'); + if (opt == null) opt = {}; + $($(elem).data('taged-el')).removeClass( opt['class'] ); + clearInterval($(elem).data('timer')); + $(elem).remove(); + }); + return; + } + return $(this).each(function (index, el) { + // show or hide tag + var tagOrigID = el.id; + var tagID = w2utils.escapeId(el.id); + if (text === '' || text == null) { + $('#w2ui-tag-'+tagID).css('opacity', 0); + setTimeout(function () { + // remmove element + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + $('#w2ui-tag-'+tagID).remove(); + }, 300); + } else { + // remove elements + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + $('#w2ui-tag-'+tagID).remove(); + // insert + $('body').append( + '
'); + + var timer = setInterval(function () { + // monitor if destroyed + if ($(el).length === 0 || ($(el).offset().left === 0 && $(el).offset().top === 0)) { + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + tmp_hide(); + return; + } + // monitor if moved + if ($('#w2ui-tag-'+tagID).data('position') !== ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) { + $('#w2ui-tag-'+tagID).css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s', + left: ($(el).offset().left + el.offsetWidth) + 'px', + top: $(el).offset().top + 'px' + }).data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top); + } + }, 100); + setTimeout(function () { + if (!$(el).offset()) return; + $('#w2ui-tag-'+tagID).css({ + opacity: '1', + left: ($(el).offset().left + el.offsetWidth) + 'px', + top: $(el).offset().top + 'px' + }).html('
'+ text +'
') + .data('text', text) + .data('taged-el', el) + .data('options', options) + .data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) + .data('timer', timer); + $(el).off('keypress', tmp_hide).on('keypress', tmp_hide).off('change', tmp_hide).on('change', tmp_hide) + .css(options.css).addClass(options['class']); + if (typeof options.onShow === 'function') options.onShow(); + }, 1); + var originalCSS = ''; + if ($(el).length > 0) originalCSS = $(el)[0].style.cssText; + // bind event to hide it + function tmp_hide() { + $tag = $('#w2ui-tag-'+tagID); + if ($tag.length <= 0) return; + clearInterval($tag.data('timer')); + $tag.remove(); + $(el).off('keypress', tmp_hide).removeClass(options['class']); + if ($(el).length > 0) $(el)[0].style.cssText = originalCSS; + if (typeof options.onHide === 'function') options.onHide(); + } + } + }); + }; + + // w2overlay - appears under the element, there can be only one at a time + + $.fn.w2overlay = function (html, options) { + var obj = this; + var name = ''; + var defaults = { + name : null, // it not null, then allows multiple concurent overlays + align : 'none', // can be none, left, right, both + left : 0, // offset left + top : 0, // offset top + tipLeft : 30, // tip offset left + width : 0, // fixed width + height : 0, // fixed height + maxWidth : null, // max width if any + maxHeight : null, // max height if any + style : '', // additional style for main div + 'class' : '', // additional class name for main dvi + onShow : null, // event on show + onHide : null, // event on hide + openAbove : false, // show abover control + tmp : {} + }; + if (!$.isPlainObject(options)) options = {}; + options = $.extend({}, defaults, options); + if (options.name) name = '-' + options.name; + // if empty then hide + var tmp_hide; + if (this.length === 0 || html === '' || html == null) { + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + if (typeof tmp_hide === 'function') tmp_hide(); + } else { + $('#w2ui-overlay'+ name).remove(); + } + return $(this); + } + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + $(document).off('click', tmp_hide); + if (typeof tmp_hide === 'function') tmp_hide(); + } + $('body').append( + '' + ); + // init + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + div2.html(html); + // pick bg color of first div + var bc = div2.css('background-color'); + if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css('background-color', bc); + + div1.data('element', obj.length > 0 ? obj[0] : null) + .data('options', options) + .data('position', $(obj).offset().left + 'x' + $(obj).offset().top) + .fadeIn('fast').on('mousedown', function (event) { + $('#w2ui-overlay'+ name).data('keepOpen', true); + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName) === -1) event.preventDefault(); + }); + div1[0].hide = hide; + div1[0].resize = resize; + + // need time to display + resize(); + setTimeout(function () { + resize(); + $(document).off('click', hide).on('click', hide); + if (typeof options.onShow === 'function') options.onShow(); + }, 10); + + monitor(); + return $(this); + + // monitor position + function monitor() { + var tmp = $('#w2ui-overlay'+ name); + if (tmp.data('element') !== obj[0]) return; // it if it different overlay + if (tmp.length === 0) return; + var pos = $(obj).offset().left + 'x' + $(obj).offset().top; + if (tmp.data('position') !== pos) { + hide(); + } else { + setTimeout(monitor, 250); + } + } + + // click anywhere else hides the drop down + function hide () { + var div1 = $('#w2ui-overlay'+ name); + if (div1.data('keepOpen') === true) { + div1.removeData('keepOpen'); + return; + } + var result; + if (typeof options.onHide === 'function') result = options.onHide(); + if (result === false) return; + div1.remove(); + $(document).off('click', hide); + clearInterval(div1.data('timer')); + } + + function resize () { + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + // if goes over the screen, limit height and width + if (div1.length > 0) { + div2.height('auto').width('auto'); + // width/height + var overflowX = false; + var overflowY = false; + var h = div2.height(); + var w = div2.width(); + if (options.width && options.width < w) w = options.width; + if (w < 30) w = 30; + // if content of specific height + if (options.tmp.contentHeight) { + h = options.tmp.contentHeight; + div2.height(h); + setTimeout(function () { + if (div2.height() > div2.find('div.menu > table').height()) { + div2.find('div.menu').css('overflow-y', 'hidden'); + } + }, 1); + setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); + } + if (options.tmp.contentWidth) { + w = options.tmp.contentWidth; + div2.width(w); + setTimeout(function () { + if (div2.width() > div2.find('div.menu > table').width()) { + div2.find('div.menu').css('overflow-x', 'hidden'); + } + }, 1); + setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); + } + // alignment + switch (options.align) { + case 'both': + options.left = 17; + if (options.width === 0) options.width = w2utils.getSize($(obj), 'width'); + break; + case 'left': + options.left = 17; + break; + case 'right': + options.tipLeft = w - 45; + options.left = w2utils.getSize($(obj), 'width') - w + 10; + break; + } + // adjust position + var tmp = (w - 17) / 2; + var boxLeft = options.left; + var boxWidth = options.width; + var tipLeft = options.tipLeft; + if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto'); + if (tmp < 25) { + boxLeft = 25 - tmp; + tipLeft = Math.floor(tmp); + } + // Y coord + div1.css({ + top : (obj.offset().top + w2utils.getSize(obj, 'height') + options.top + 7) + 'px', + left : ((obj.offset().left > 25 ? obj.offset().left : 25) + boxLeft) + 'px', + 'min-width' : boxWidth, + 'min-height': (options.height ? options.height : 'auto') + }); + // $(window).height() - has a problem in FF20 + var maxHeight = window.innerHeight + $(document).scrollTop() - div2.offset().top - 7; + var maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; + if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) { + // show on top + maxHeight = div2.offset().top - $(document).scrollTop() - 7; + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + h = maxHeight; + } + div1.css('top', ($(obj).offset().top - h - 24 + options.top) + 'px'); + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { display: none; margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { display: block; margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } else { + // show under + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + } + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { display: block; margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { display: none; margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } + // check width + w = div2.width(); + maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; + if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth; + if (w > maxWidth && options.align !== 'both') { + options.align = 'right'; + setTimeout(function () { resize(); }, 1); + } + // check scroll bar + if (overflowY && overflowX) div2.width(w + w2utils.scrollBarSize() + 2); + } + } + }; + + $.fn.w2menu = function (menu, options) { + /* + ITEM STRUCTURE + item : { + id : null, + text : '', + style : '', + hidden : true + ... + } + */ + var defaults = { + index : null, // current selected + items : [], + render : null, + msgNoItems : 'No items', + onSelect : null, + tmp : {} + }; + var obj = this; + var name = ''; + if (menu === 'refresh') { + // if not show - call blur + if ($('#w2ui-overlay'+ name).length > 0) { + options = $.extend($.fn.w2menuOptions, options); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + $('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML()); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + mresize(); + } else { + $(this).w2menu(options); + } + } else { + if (arguments.length === 1) options = menu; else options.items = menu; + if (typeof options !== 'object') options = {}; + options = $.extend({}, defaults, options); + $.fn.w2menuOptions = options; + if (options.name) name = '-' + options.name; + if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select; + if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender; + // since only one overlay can exist at a time + $.fn.w2menuHandler = function (event, index) { + if (typeof options.onSelect === 'function') { + // need time so that menu first hides + setTimeout(function () { + options.onSelect({ + index : index, + item : options.items[index], + originalEvent: event + }); + }, 10); + } + }; + var html = ''; + if (options.search) { + html += + '
'+ + ' '+ + ' '+ + '
'; + options.style += ';background-color: #ECECEC'; + options.index = 0; + for (var i in options.items) options.items[i].hidden = false; + } + html += ''; + var ret = $(this).w2overlay(html, options); + setTimeout(function () { + $('#w2ui-overlay'+ name +' #menu-search') + .on('keyup', change) + .on('keydown', function (event) { + // cancel tab key + if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); } + }); + }, 200); + mresize(); + return ret; + } + + function mresize() { + setTimeout(function () { + // show selected + $('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected'); + var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']'); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + cur.addClass('w2ui-selected'); + if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10); + if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width(); + $('#w2ui-overlay'+ name)[0].resize(); + // scroll into view + if (cur.length > 0) { + var top = cur[0].offsetTop - 5; // 5 is margin top + var el = $('#w2ui-overlay'+ name +' div.menu'); + var height = el.height(); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + if (top < scrTop || top + cur.height() > scrTop + height) { + $('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); + } + } + }, 1); + } + + function change(event) { + var search = this.value; + var key = event.keyCode; + var cancel = false; + switch (key) { + case 13: // enter + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuHandler(event, options.index); + break; + case 9: // tab + case 27: // escape + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuHandler(event, -1); + break; + case 38: // up + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index--; + while (options.index > 0 && options.items[options.index].hidden) options.index--; + if (options.index === 0 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } + if (options.index < 0) options.index = 0; + cancel = true; + break; + case 40: // down + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index++; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (options.index === options.items.length-1 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index--; + } + if (options.index >= options.items.length) options.index = options.items.length - 1; + cancel = true; + break; + } + // filter + if (!cancel) { + var shown = 0; + for (var i in options.items) { + var item = options.items[i]; + var prefix = ''; + var suffix = ''; + if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^'; + if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$'; + try { + var re = new RegExp(prefix + search + suffix, 'i'); + if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true; + if (options.applyFilter !== true) item.hidden = false; + } catch (e) {} + // do not show selected items + if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true; + if (item.hidden !== true) shown++; + } + options.index = 0; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (shown <= 0) options.index = -1; + } + $(obj).w2menu('refresh', options); + mresize(); + } + + function getMenuHTML () { + if (options.spinner) { + return '
'+ + '
'+ + '
Loading...
'+ + '
'; + } + var count = 0; + var menu_html = ''; + var img = null, icon = null; + for (var f = 0; f < options.items.length; f++) { + var mitem = options.items[f]; + if (typeof mitem === 'string') { + mitem = { id: mitem, text: mitem }; + } else { + if (mitem.text != null && mitem.id == null) mitem.id = mitem.text; + if (mitem.text == null && mitem.id != null) mitem.text = mitem.id; + if (mitem.caption != null) mitem.text = mitem.caption; + img = mitem.img; + icon = mitem.icon; + if (img == null) img = null; + if (icon == null) icon = null; + } + if (mitem.hidden !== true) { + var imgd = ''; + var txt = mitem.text; + if (typeof options.render === 'function') txt = options.render(mitem, options); + if (img) imgd = ''; + if (icon) imgd = ''; + // render only if non-empty + if (typeof txt !== 'undefined' && txt !== '' && !(/^-+$/.test(txt))) { + var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd'); + if (options.altRows !== true) bg = ''; + menu_html += + ''+ + imgd + + ' '+ + ''; + count++; + } else { + // horizontal line + menu_html += ''; + } + } + options.items[f] = mitem; + } + if (count === 0) { + menu_html += ''; + } + menu_html += "
'+ txt +'
'+ options.msgNoItems +'
"; + return menu_html; + } + }; })(); /************************************************************************ * Library: Web 2.0 UI for jQuery (using prototypical inheritance) * - Following objects defined -* - w2field - various field controls -* - $().w2field - jQuery wrapper +* - w2field - various field controls +* - $().w2field - jQuery wrapper * - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - upload (regular files) -* - BUG with prefix/postfix and arrows (test in different contexts) -* - prefix and suffix are slow (100ms or so) -* - multiple date selection -* - month selection, year selections -* - arrows no longer work (for int) -* - add postData for autocomplete -* - form to support custom types -* - bug: if input is hidden and then enum is applied, then when it becomes visible, it will be 110px +* - upload (regular files) +* - BUG with prefix/postfix and arrows (test in different contexts) +* - prefix and suffix are slow (100ms or so) +* - multiple date selection +* - month selection, year selections +* - arrows no longer work (for int) +* - add postData for autocomplete +* - form to support custom types +* - bug: if input is hidden and then enum is applied, then when it becomes visible, it will be 110px * * == 1.4 Changes == -* - select - for select, list - for drop down (needs this in grid) -* - $().addType() - changes sligtly (this.el) -* - $().removeType() - new method -* - enum add events: onLoad, onRequest, onDelete, for already selected elements -* - enum - refresh happens on each key press even if not needed (for speed) -* - rewrire everythin in objects (w2ftext, w2fenum, w2fdate) -* - render calendar to the div -* - added .btn with colors -* - added enum.style and file.style attributes -* - test all fields as Read Only -* - added openOnFocus -* - deprecated -- change: showAll -> applyFilter -* - color: select with keyboard -* - enum: addNew event -* - added icon and onIconClick -* - new: clearCache -* - easy way to add icons -* - easy way to navigate month/year in dates -* - added step for numeric inputs -* - changed prepopulate -> minLength -* - added options.postData +* - select - for select, list - for drop down (needs this in grid) +* - $().addType() - changes sligtly (this.el) +* - $().removeType() - new method +* - enum add events: onLoad, onRequest, onDelete, for already selected elements +* - enum - refresh happens on each key press even if not needed (for speed) +* - rewrire everythin in objects (w2ftext, w2fenum, w2fdate) +* - render calendar to the div +* - added .btn with colors +* - added enum.style and file.style attributes +* - test all fields as Read Only +* - added openOnFocus +* - deprecated -- change: showAll -> applyFilter +* - color: select with keyboard +* - enum: addNew event +* - added icon and onIconClick +* - new: clearCache +* - easy way to add icons +* - easy way to navigate month/year in dates +* - added step for numeric inputs +* - changed prepopulate -> minLength +* - added options.postData * ************************************************************************/ (function ($) { - var w2field = function (options) { - // public properties - this.el = null - this.helpers = {}; // object or helper elements - this.type = options.type || 'text'; - this.options = $.extend(true, {}, options); - this.onSearch = options.onSearch || null; - this.onRequest = options.onRequest || null; - this.onLoad = options.onLoad || null; - this.onError = options.onError || null; - this.onClick = options.onClick || null; - this.onAdd = options.onAdd || null; - this.onNew = options.onNew || null; - this.onRemove = options.onRemove || null; - this.onMouseOver= options.onMouseOver || null; - this.onMouseOut = options.onMouseOut || null; - this.onIconClick= options.onIconClick || null; - this.tmp = {}; // temp object - // clean up some options - delete this.options.type; - delete this.options.onSearch; - delete this.options.onRequest; - delete this.options.onLoad; - delete this.options.onError; - delete this.options.onClick; - delete this.options.onMouseOver; - delete this.options.onMouseOut; - delete this.options.onIconClick; - // extend with defaults - $.extend(true, this, w2obj.field); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2field = function (method, options) { - // call direct - if (this.length == 0) { - var pr = w2field.prototype; - if (pr[method]) { - return pr[method].apply(pr, Array.prototype.slice.call(arguments, 1)); - } - } else { - if (typeof method == 'string' && typeof options == 'object') { - method = $.extend(true, {}, options, { type: method }); - } - if (typeof method == 'string' && typeof options == 'undefined') { - method = { type: method }; - } - method.type = String(method.type).toLowerCase(); - return this.each(function (index, el) { - var obj = $(el).data('w2field'); - // if object is not defined, define it - if (typeof obj == 'undefined') { - var obj = new w2field(method); - $.extend(obj, { handlers: [] }); - if (el) obj.el = $(el)[0]; - obj.init(); - $(el).data('w2field', obj); - return obj; - } else { // fully re-init - obj.clear(); - if (method.type == 'clear') return; - var obj = new w2field(method); - $.extend(obj, { handlers: [] }); - if (el) obj.el = $(el)[0]; - obj.init(); - $(el).data('w2field', obj); - return obj; - } - return null; - }); - } - } - - // ==================================================== - // -- Implementation of core functionality - - /* To add custom types - $().w2field('addType', 'myType', function (options) { - $(this.el).on('keypress', function (event) { - if (event.metaKey || event.ctrlKey || event.altKey - || (event.charCode != event.keyCode && event.keyCode > 0)) return; - var ch = String.fromCharCode(event.charCode); - if (ch != 'a' && ch != 'b' && ch != 'c') { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; - } - }); - $(this.el).on('blur', function (event) { // keyCode & charCode differ in FireFox - var ch = this.value; - if (ch != 'a' && ch != 'b' && ch != 'c') { - $(this).w2tag(w2utils.lang("Not a single charecter from the set of 'abc'")); - } - }); - }); - */ - - w2field.prototype = { - - custom: {}, // map of custom types - - pallete: [ - ['000000', '444444', '666666', '999999', 'CCCCCC', 'EEEEEE', 'F3F3F3', 'FFFFFF'], - ['FF011B', 'FF9838', 'FFFD59', '01FD55', '00FFFE', '0424F3', '9B24F4', 'FF21F5'], - ['F4CCCC', 'FCE5CD', 'FFF2CC', 'D9EAD3', 'D0E0E3', 'CFE2F3', 'D9D1E9', 'EAD1DC'], - ['EA9899', 'F9CB9C', 'FEE599', 'B6D7A8', 'A2C4C9', '9FC5E8', 'B4A7D6', 'D5A6BD'], - ['E06666', 'F6B26B', 'FED966', '93C47D', '76A5AF', '6FA8DC', '8E7CC3', 'C27BA0'], - ['CC0814', 'E69138', 'F1C232', '6AA84F', '45818E', '3D85C6', '674EA7', 'A54D79'], - ['99050C', 'B45F17', 'BF901F', '37761D', '124F5C', '0A5394', '351C75', '741B47'], - ['660205', '783F0B', '7F6011', '274E12', '0C343D', '063762', '20124D', '4C1030'] - ], - - addType: function (type, handler) { - type = String(type).toLowerCase(); - this.custom[type] = handler; - return true; - }, - - removeType: function (type) { - type = String(type).toLowerCase(); - if (!this.custom[type]) return false; - delete this.custom[type]; - return true - }, - - init: function () { - var obj = this; - var options = this.options; - var defaults; - - // Custom Types - if (typeof this.custom[this.type] == 'function') { - this.custom[this.type].call(this, options); - return; - } - // only for INPUT or TEXTAREA - if (['INPUT', 'TEXTAREA'].indexOf(this.el.tagName) == -1) { - console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el); - return; - } - - switch (this.type) { - case 'text': - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'alphanumeric': - case 'hex': - defaults = { - min : null, - max : null, - step : 1, - placeholder : '', - autoFormat : true, - currencyPrefix : w2utils.settings.currencyPrefix, - currencySuffix : w2utils.settings.currencySuffix, - currencyPrecision: w2utils.settings.currencyPrecision, - groupSymbol : w2utils.settings.groupSymbol, - arrows : false, - keyboard : true, - precision : null, - silent : true, - prefix : '', - suffix : '' - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g'); - options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol + ']', 'g'); - options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g'); - // no keyboard support needed - if (['text', 'alphanumeric', 'hex'].indexOf(this.type) != -1) { - options.arrows = false; - options.keyboard = false; - } - this.addPrefix(); // only will add if needed - this.addSuffix(); - $(this.el).attr('placeholder', options.placeholder); - break; - - case 'color': - defaults = { - prefix : '#', - suffix : '
 
', - placeholder : '', - arrows : false, - keyboard : false - }; - $.extend(options, defaults); - this.addPrefix(); // only will add if needed - this.addSuffix(); // only will add if needed - // additional checks - $(this.el).attr('maxlength', 6); - if ($(this.el).val() != '') setTimeout(function () { $(obj.el).change(); }, 1); - $(this.el).attr('placeholder', options.placeholder); - break; - - case 'date': - defaults = { - format : w2utils.settings.date_format, // date format - placeholder : '', - keyboard : true, - silent : true, - start : '', // string or jquery object - end : '', // string or jquery object - blocked : {}, // { '4/11/2011': 'yes' } - colored : {} // { '4/11/2011': 'red:white' } - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - $(this.el).attr('placeholder', options.placeholder ? options.placeholder : options.format); - break; - - case 'time': - defaults = { - format : w2utils.settings.time_format, - placeholder : '', - keyboard : true, - silent : true, - start : '', - end : '' - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - $(this.el).attr('placeholder', options.placeholder ? options.placeholder : (options.format == 'h12' ? 'hh:mi pm' : 'hh:mi')); - break; - - case 'datetime': - break; - - case 'list': - case 'combo': - defaults = { - items : [], - selected : {}, - placeholder : '', - url : null, // url to pull data from - postData : {}, - minLength : 1, - cacheMax : 250, - maxDropHeight : 350, // max height for drop down menu - match : 'begins', // ['contains', 'is', 'begins', 'ends'] - silent : true, - icon : null, - iconStyle : '', - onSearch : null, // when search needs to be performed - onRequest : null, // when request is submitted - onLoad : null, // when data is received - onError : null, // when data fails to load due to server error or other failure modes - onIconClick : null, - renderDrop : null, // render function for drop down item - prefix : '', - suffix : '', - openOnFocus : false, // if to show overlay onclick or when typing - markSearch : false - }; - if (this.type == 'list') { - // defaults.search = (options.items && options.items.length >= 10 ? true : false); - defaults.openOnFocus = true; - defaults.suffix = '
'; - $(this.el).addClass('w2ui-select'); - // if simple value - look it up - if (!$.isPlainObject(options.selected)) { - for (var i in options.items) { - var item = options.items[i]; - if (item && item.id == options.selected) { - options.selected = $.extend(true, {}, item); - break; - } - } - } - } - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - altRows : true // alternate row color - }); - options.items = this.normMenu(options.items); - this.options = options; - if (!$.isPlainObject(options.selected)) options.selected = {}; - $(this.el).data('selected', options.selected); - if (options.url) this.request(0); - if (options.icon) { - options.prefix = ''+ - ''; - } - if (this.type == 'list') this.addFocus(); - this.addPrefix(); - this.addSuffix(); - setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh - $(this.el).attr('placeholder', options.placeholder).attr('autocomplete', 'off'); - if (typeof options.selected.text != 'undefined') $(this.el).val(options.selected.text); - break; - - case 'enum': - defaults = { - items : [], - selected : [], - placeholder : '', - max : 0, // max number of selected items, 0 - unlim - url : null, // not implemented - postData : {}, - minLength : 1, - cacheMax : 250, - maxWidth : 250, // max width for a single item - maxHeight : 350, // max height for input control to grow - maxDropHeight : 350, // max height for drop down menu - match : 'contains', // ['contains', 'is', 'begins', 'ends'] - silent : true, - openOnFocus : false, // if to show overlay onclick or when typing - markSearch : true, - renderDrop : null, // render function for drop down item - renderItem : null, // render selected item - style : '', // style for container div - onSearch : null, // when search needs to be performed - onRequest : null, // when request is submitted - onLoad : null, // when data is received - onError : null, // when data fails to load due to server error or other failure modes - onClick : null, // when an item is clicked - onAdd : null, // when an item is added - onNew : null, // when new item should be added - onRemove : null, // when an item is removed - onMouseOver : null, // when an item is mouse over - onMouseOut : null // when an item is mouse out - }; - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - suffix : '', - altRows : true // alternate row color - }); - options.items = this.normMenu(options.items); - options.selected = this.normMenu(options.selected); - this.options = options; - if (!$.isArray(options.selected)) options.selected = []; - $(this.el).data('selected', options.selected); - if (options.url) this.request(0); - this.addSuffix(); - this.addMulti(); - break; - - case 'file': - defaults = { - selected : [], - placeholder : w2utils.lang('Attach files by dragging and dropping or Click to Select'), - max : 0, - maxSize : 0, // max size of all files, 0 - unlim - maxFileSize : 0, // max size of a single file, 0 -unlim - maxWidth : 250, // max width for a single item - maxHeight : 350, // max height for input control to grow - maxDropHeight : 350, // max height for drop down menu - silent : true, - renderItem : null, // render selected item - style : '', // style for container div - onClick : null, // when an item is clicked - onAdd : null, // when an item is added - onRemove : null, // when an item is removed - onMouseOver : null, // when an item is mouse over - onMouseOut : null, // when an item is mouse out - }; - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - altRows : true // alternate row color - }); - this.options = options; - if (!$.isArray(options.selected)) options.selected = []; - $(this.el).data('selected', options.selected); - this.addMulti(); - break; - } - // attach events - this.tmp = { - onChange : function (event) { obj.change.call(obj, event) }, - onClick : function (event) { obj.click.call(obj, event) }, - onFocus : function (event) { obj.focus.call(obj, event) }, - onBlur : function (event) { obj.blur.call(obj, event) }, - onKeydown : function (event) { obj.keyDown.call(obj, event) }, - onKeyup : function (event) { obj.keyUp.call(obj, event) }, - onKeypress : function (event) { obj.keyPress.call(obj, event) } - } - $(this.el) - .addClass('w2field') - .data('w2field', this) - .on('change', this.tmp.onChange) - .on('click', this.tmp.onClick) // ignore click because it messes overlays - .on('focus', this.tmp.onFocus) - .on('blur', this.tmp.onBlur) - .on('keydown', this.tmp.onKeydown) - .on('keyup', this.tmp.onKeyup) - .on('keypress', this.tmp.onKeypress) - .css({ - 'box-sizing' : 'border-box', - '-webkit-box-sizing': 'border-box', - '-moz-box-sizing' : 'border-box', - '-ms-box-sizing' : 'border-box', - '-o-box-sizing' : 'border-box' - }); - // format initial value - this.change($.Event('change')); - }, - - clear: function () { - var obj = this; - var options = this.options; - // if money then clear value - if (['money', 'currency'].indexOf(this.type) != -1) { - $(this.el).val($(this.el).val().replace(options.moneyRE, '')); - } - if (this.type == 'percent') { - $(this.el).val($(this.el).val().replace(/%/g, '')); - } - if (this.type == 'color') { - $(this.el).removeAttr('maxlength'); - } - if (this.type == 'list') { - $(this.el).removeClass('w2ui-select'); - } - this.type = 'clear'; - var tmp = $(this.el).data('tmp'); - if (!this.tmp) return; - // restore paddings - if (typeof tmp != 'undefined') { - if (tmp && tmp['old-padding-left']) $(this.el).css('padding-left', tmp['old-padding-left']); - if (tmp && tmp['old-padding-right']) $(this.el).css('padding-right', tmp['old-padding-right']); - } - // remove events and data - $(this.el) - .val(this.clean($(this.el).val())) - .removeClass('w2field') - .removeData() // removes all attached data - .off('change', this.tmp.onChange) - .off('click', this.tmp.onClick) - .off('focus', this.tmp.onFocus) - .off('blur', this.tmp.onBlur) - .off('keydown', this.tmp.onKeydown) - .off('keyup', this.tmp.onKeyup) - .off('keypress',this.tmp.onKeypress); - // remove helpers - for (var h in this.helpers) $(this.helpers[h]).remove(); - this.helpers = {}; - }, - - refresh: function () { - var obj = this; - var options = this.options; - var selected = $(this.el).data('selected'); - var time = (new Date()).getTime(); - // enum - if (['list'].indexOf(this.type) != -1) { - $(obj.el).parent().css('white-space', 'nowrap'); // needs this for arrow alway to appear on the right side - // hide focus and show text - if (obj.helpers.prefix) obj.helpers.prefix.hide(); - setTimeout(function () { - var focus = obj.helpers.focus.find('input'); - if ($(focus).val() == '') { - $(focus).css('opacity', 0).prev().css('opacity', 0); - $(obj.el).val(selected && selected.text != null ? selected.text : ''); - $(obj.el).attr('placeholder', $(obj.el).attr('_placeholder')); - // if empty show no icon - if ($.isEmptyObject(selected)) { - if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); - } else { - if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.show(); - } - } else { - $(focus).css('opacity', 1).prev().css('opacity', 1); - if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); - $(obj.el).val(''); - $(obj.el).attr('_placeholder', $(obj.el).attr('placeholder')).removeAttr('placeholder'); - } - }, 1); - } - if (['enum', 'file'].indexOf(this.type) != -1) { - var html = ''; - for (var s in selected) { - var it = selected[s]; - var ren = ''; - if (typeof options.renderItem == 'function') { - ren = options.renderItem(it, s, '
  
'); - } else { - ren = '
  
'+ - (obj.type == 'enum' ? it.text : it.name + ' - '+ w2utils.size(it.size) +''); - } - html += '
  • '+ - ren +'
  • '; - } - var div = obj.helpers.multi; - var ul = div.find('ul'); - div.attr('style', div.attr('style') + ';' + options.style); - if ($(obj.el).attr('readonly')) div.addClass('w2ui-readonly'); else div.removeClass('w2ui-readonly'); - // celan - div.find('.w2ui-enum-placeholder').remove(); - ul.find('li').not('li.nomouse').remove(); - // add new list - if (html != '') { - ul.prepend(html); - } else if (typeof options.placeholder != 'undefined') { - var style = - 'padding-top: ' + $(this.el).css('padding-top') + ';'+ - 'padding-left: ' + $(this.el).css('padding-left') + '; ' + - 'box-sizing: ' + $(this.el).css('box-sizing') + '; ' + - 'line-height: ' + $(this.el).css('line-height') + '; ' + - 'font-size: ' + $(this.el).css('font-size') + '; ' + - 'font-family: ' + $(this.el).css('font-family') + '; '; - div.prepend('
    '+ options.placeholder + '
    '); - } - // ITEMS events - div.find('li') - .data('mouse', 'out') - .on('click', function (event) { - var item = selected[$(event.target).attr('index')]; - if ($(event.target).hasClass('nomouse')) return; - event.stopPropagation(); - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'click', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // default behavior - if ($(event.target).hasClass('w2ui-list-remove')) { - if ($(obj.el).attr('readonly')) return; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // default behavior - $().w2overlay(); - selected.splice($(event.target).attr('index'), 1); - $(obj.el).trigger('change'); - $(event.target).parent().fadeOut('fast'); - setTimeout(function () { - obj.refresh(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 300); - } - if (obj.type == 'file' && !$(event.target).hasClass('w2ui-list-remove')) { - var preview = ''; - if ((/image/i).test(item.type)) { // image - preview = '
    '+ - ' '+ - '
    '; - } - var td1 = 'style="padding: 3px; text-align: right; color: #777;"'; - var td2 = 'style="padding: 3px"'; - preview += '
    '+ - ' '+ - ' '+ - ' '+ - ' '+ - ' '+ - '
    Name:'+ item.name +'
    Size:'+ w2utils.size(item.size) +'
    Type:' + - ' '+ item.type +''+ - '
    Modified:'+ w2utils.date(item.modified) +'
    '+ - '
    '; - $(event.target).w2overlay(preview); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }) - .on('mouseover', function (event) { - var tmp = event.target; - if (tmp.tagName != 'LI') tmp = tmp.parentNode; - if ($(tmp).hasClass('nomouse')) return; - if ($(tmp).data('mouse') == 'out') { - var item = selected[$(tmp).attr('index')]; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'mouseOver', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - $(tmp).data('mouse', 'over'); - }) - .on('mouseout', function (event) { - var tmp = event.target; - if (tmp.tagName != 'LI') tmp = tmp.parentNode; - if ($(tmp).hasClass('nomouse')) return; - $(tmp).data('mouse', 'leaving'); - setTimeout(function () { - if ($(tmp).data('mouse') == 'leaving') { - $(tmp).data('mouse', 'out'); - var item = selected[$(tmp).attr('index')]; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'f', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - }, 0); - }); - // adjust height - $(this.el).height('auto'); - var cntHeight = $(div).find('> div').height() + w2utils.getSize(div, '+height') * 2; - if (cntHeight < 26) cntHeight = 26; - if (cntHeight > options.maxHeight) cntHeight = options.maxHeight; - if (div.length > 0) div[0].scrollTop = 1000; - var inpHeight = w2utils.getSize($(this.el), 'height') - 2; - if (inpHeight > cntHeight) cntHeight = inpHeight - $(div).css({ 'height': cntHeight + 'px', overflow: (cntHeight == options.maxHeight ? 'auto' : 'hidden') }); - if (cntHeight < options.maxHeight) $(div).prop('scrollTop', 0); - $(this.el).css({ 'height' : (cntHeight + 2) + 'px' }); - } - return (new Date()).getTime() - time; - }, - - reset: function () { - var obj = this; - var type = this.type; - this.clear(); - this.type = type; - this.init(); - }, - - clean: function (val) { - var options = this.options; - val = String(val).trim(); - // clean - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { - if (options.autoFormat && ['money', 'currency'].indexOf(this.type) != -1) val = String(val).replace(options.moneyRE, ''); - if (options.autoFormat && this.type == 'percent') val = String(val).replace(options.percentRE, ''); - if (options.autoFormat && ['int', 'float'].indexOf(this.type) != -1) val = String(val).replace(options.numberRE, ''); - if (parseFloat(val) == val) { - if (options.min !== null && val < options.min) { val = options.min; $(this.el).val(options.min); } - if (options.max !== null && val > options.max) { val = options.max; $(this.el).val(options.max); } - } - if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = ''; - } - return val; - }, - - format: function (val) { - var options = this.options; - // autoformat numbers or money - if (options.autoFormat && val != '') { - switch (this.type) { - case 'money': - case 'currency': - val = w2utils.formatNumber(Number(val).toFixed(options.currencyPrecision), options.groupSymbol); - if (val != '') val = options.currencyPrefix + val + options.currencySuffix; - break; - case 'percent': - val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); - if (val != '') val += '%'; - break; - case 'float': - val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); - break; - case 'int': - val = w2utils.formatNumber(val, options.groupSymbol); - break; - } - } - return val; - }, - - change: function (event) { - var obj = this; - var options = obj.options; - // numeric - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { - // check max/min - var val = $(this.el).val(); - var new_val = this.format(this.clean($(this.el).val())); - // if was modified - if (val != '' && val != new_val) { - $(this.el).val(new_val).change(); - // cancel event - event.stopPropagation(); - event.preventDefault(); - return false; - } - } - // color - if (this.type == 'color') { - var color = '#' + $(this.el).val(); - if ($(this.el).val().length != 6 && $(this.el).val().length != 3) color = ''; - $(this.el).next().find('div').css('background-color', color); - if ($(obj.el).is(':focus')) this.updateOverlay(); - } - }, - - click: function (event) { - event.stopPropagation(); - // lists - if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { - if (!$(this.el).is(':focus')) this.focus(event); - } - // other fields with drops - if (['date', 'time', 'color'].indexOf(this.type) != -1) { - this.updateOverlay(); - } - }, - - focus: function (event) { - var obj = this; - var options = this.options; - // color, date, time - if (['color', 'date', 'time'].indexOf(obj.type) !== -1) { - if ($(obj.el).attr('readonly')) return; - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - setTimeout(function () { obj.updateOverlay(); }, 150); - } - // menu - if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($(obj.el).attr('readonly')) return; - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - setTimeout(function () { - if (obj.type == 'list' && $(obj.el).is(':focus')) { - $(obj.helpers.focus).find('input').focus(); - return; - } - obj.search(); - setTimeout(function () { obj.updateOverlay(); }, 1); - }, 1); - } - // file - if (obj.type == 'file') { - $(obj.helpers.multi).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - } - }, - - blur: function (event) { - var obj = this; - var options = obj.options; - var val = $(obj.el).val().trim(); - // hide overlay - if (['color', 'date', 'time', 'list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - } - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { - if (val !== '' && !obj.checkType(val)) { - $(obj.el).val('').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid number'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - } - // date or time - if (['date', 'time'].indexOf(obj.type) != -1) { - if (w2utils.isInt(obj.el.value)) { - $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); - } - // check if in range - if (val !== '' && !obj.inRange(obj.el.value)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not in range'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } else { - if (obj.type == 'date' && val !== '' && !w2utils.isDate(obj.el.value, options.format)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid date'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - if (obj.type == 'time' && val !== '' && !w2utils.isTime(obj.el.value)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid time'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - } - } - // clear search input - if (obj.type == 'enum') { - $(obj.helpers.multi).find('input').val('').width(20); - } - // file - if (obj.type == 'file') { - $(obj.helpers.multi).css({ 'outline': 'none' }); - } - }, - - keyPress: function (event) { - var obj = this; - var options = obj.options; - // ignore wrong pressed key - if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'color', 'alphanumeric'].indexOf(obj.type) != -1) { - // keyCode & charCode differ in FireFox - if (event.metaKey || event.ctrlKey || event.altKey || (event.charCode != event.keyCode && event.keyCode > 0)) return; - var ch = String.fromCharCode(event.charCode); - if (!obj.checkType(ch, true) && event.keyCode != 13) { - event.preventDefault(); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; - } - } - // update date popup - if (['date', 'time'].indexOf(obj.type) != -1) { - setTimeout(function () { obj.updateOverlay(); }, 1); - } - }, - - keyDown: function (event, extra) { - var obj = this; - var options = obj.options; - var key = event.keyCode || (extra && extra.keyCode); - // numeric - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { - if (!options.keyboard || $(obj.el).attr('readonly')) return; - var cancel = false; - var val = parseFloat($(obj.el).val().replace(options.moneyRE, '')) || 0; - var inc = options.step; - if (event.ctrlKey || event.metaKey) inc = 10; - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - $(obj.el).val((val + inc <= options.max || options.max === null ? Number((val + inc).toFixed(12)) : options.max)).change(); - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - $(obj.el).val((val - inc >= options.min || options.min === null ? Number((val - inc).toFixed(12)) : options.min)).change(); - cancel = true; - break; - } - if (cancel) { - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - }, 0); - } - } - // date - if (obj.type == 'date') { - if (!options.keyboard || $(obj.el).attr('readonly')) return; - var cancel = false; - var daymil = 24*60*60*1000; - var inc = 1; - if (event.ctrlKey || event.metaKey) inc = 10; - if (w2utils.isInt(obj.el.value)) { - $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); - } - var dt = w2utils.isDate($(obj.el).val(), options.format, true); - if (!dt) { dt = new Date(); daymil = 0; } - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDate(dt.getTime() + daymil, options.format); - if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDate(dt.getTime() - daymil, options.format); - if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - } - if (cancel) { - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - obj.updateOverlay(); - }, 0); - } - } - // time - if (obj.type == 'time') { - if (!options.keyboard || $(obj.el).attr('readonly')) return; - var cancel = false; - var inc = 1; - if (event.ctrlKey || event.metaKey) inc = 60; - if (w2utils.isInt(obj.el.value)) { - $(obj.el).val(w2utils.formatTime(new Date(parseInt(obj.el.value)), options.format)).change(); - } - var val = $(obj.el).val(); - var time = obj.toMin(val) || obj.toMin((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)); - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - time += inc; - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - time -= inc; - cancel = true; - break; - } - if (cancel) { - $(obj.el).val(obj.fromMin(time)).change(); - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - }, 0); - } - } - // color - if (obj.type == 'color') { - if ($(obj.el).attr('readonly')) return; - // paste - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { - $(obj.el).prop('maxlength', 7); - setTimeout(function () { - var val = $(obj).val(); - if (val.substr(0, 1) == '#') val = val.substr(1); - if (!w2utils.isHex(val)) val = ''; - $(obj).val(val).prop('maxlength', 6).change(); - }, 20); - } - if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { - if (typeof obj.tmp.cind1 == 'undefined') { - obj.tmp.cind1 = -1; - obj.tmp.cind2 = -1; - } else { - switch (key) { - case 38: // up - obj.tmp.cind1--; - break; - case 40: // down - obj.tmp.cind1++; - break; - case 39: // right - obj.tmp.cind2++; - break; - case 37: // left - obj.tmp.cind2--; - break; - } - if (obj.tmp.cind1 < 0) obj.tmp.cind1 = 0; - if (obj.tmp.cind1 > this.pallete.length - 1) obj.tmp.cind1 = this.pallete.length - 1; - if (obj.tmp.cind2 < 0) obj.tmp.cind2 = 0; - if (obj.tmp.cind2 > this.pallete[0].length - 1) obj.tmp.cind2 = this.pallete[0].length - 1; - } - if ([37, 38, 39, 40].indexOf(key) != -1) { - $(obj.el).val(this.pallete[obj.tmp.cind1][obj.tmp.cind2]).change(); - event.preventDefault(); - } - } - } - // list/select/combo - if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($(obj.el).attr('readonly')) return; - var cancel = false; - var selected = $(obj.el).data('selected'); - var focus = $(obj.helpers.focus).find('input'); - if (obj.type == 'list') { - if ([37, 38, 39, 40].indexOf(key) == -1) obj.refresh(); // arrows - } - // apply arrows - switch (key) { - case 27: // escape - if (obj.type == 'list') { - if ($(focus).val() == '') { - $(obj.el).data('selected', {}); - } else { - $(focus).val(''); - } - obj.refresh(); - event.stopPropagation(); // escape in field should not close popup - } - break; - case 37: // left - case 39: // right - // cancel = true; - break; - case 13: // enter - if ($('#w2ui-overlay').length == 0) break; // no action if overlay not open - var item = options.items[options.index]; - var multi = $(obj.helpers.multi).find('input'); - if (obj.type == 'enum') { - if (item != null) { - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - item = eventData.item; // need to reassign because it could be recreated by user - // default behavior - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete item.hidden; - delete obj.tmp.force_open; - selected.push(item); - $(obj.el).change(); - multi.val('').width(20); - obj.refresh(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } else { - // trigger event - item = { id: multi.val(), text: multi.val() } - var eventData = obj.trigger({ phase: 'before', type: 'new', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - item = eventData.item; // need to reassign because it could be recreated by user - // default behavior - if (typeof obj.onNew == 'function') { - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete obj.tmp.force_open; - selected.push(item); - $(obj.el).change(); - multi.val('').width(20); - obj.refresh(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - } else { - if (item) $(obj.el).data('selected', item).val(item.text).change(); - if ($(obj.el).val() == '' && $(obj.el).data('selected')) $(obj.el).removeData('selected').val('').change(); - if (obj.type == 'list') { - focus.val(''); - obj.refresh(); - } - // hide overlay - obj.tmp.force_hide = true; - } - break; - case 8: // delete - if (['enum'].indexOf(obj.type) != -1) { - if ($(obj.helpers.multi).find('input').val() == '' && selected.length > 0) { - var item = selected[selected.length - 1]; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // default behavior - selected.pop(); - $(obj.el).trigger('change'); - obj.refresh(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - } - break; - case 38: // up - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index--; - while (options.index > 0 && options.items[options.index].hidden) options.index--; - if (options.index == 0 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } - cancel = true; - break; - case 40: // down - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : -1; - options.index++; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (options.index == options.items.length-1 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index--; - } - // show overlay if not shown - var input = obj.el; - if (['enum'].indexOf(obj.type) != -1) input = obj.helpers.multi.find('input'); - if ($(input).val() == '' && $('#w2ui-overlay').length == 0) { - obj.tmp.force_open = true; - } else { - cancel = true; - } - break; - } - if (cancel) { - if (options.index < 0) options.index = 0; - if (options.index >= options.items.length) options.index = options.items.length -1; - obj.updateOverlay(); - // cancel event - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - if (obj.type == 'enum') { - var tmp = obj.helpers.multi.find('input').get(0); - tmp.setSelectionRange(tmp.value.length, tmp.value.length); - } else if (obj.type == 'list') { - var tmp = obj.helpers.focus.find('input').get(0); - tmp.setSelectionRange(tmp.value.length, tmp.value.length); - } else { - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - } - }, 0); - return; - } - // expand input - if (obj.type == 'enum') { - var input = obj.helpers.multi.find('input'); - var search = input.val(); - input.width(((search.length + 2) * 8) + 'px'); - } - // run search - if ([16, 17, 18, 20, 37, 39, 91].indexOf(key) == -1) { // no refreah on crtl, shift, left/right arrows, etc - setTimeout(function () { - if (!obj.tmp.force_hide) obj.request(); - obj.search(); - }, 1); - } - } - }, - - keyUp: function (event) { - if (this.type == 'color') { - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) $(this).prop('maxlength', 6); - } - }, - - clearCache: function () { - var options = this.options; - options.items = []; - this.tmp.xhr_loading = false; - this.tmp.xhr_search = ''; - this.tmp.xhr_total = -1; - this.search(); - }, - - request: function (interval) { - var obj = this; - var options = this.options; - var search = $(obj.el).val() || ''; - // if no url - do nothing - if (!options.url) return; - // -- - if (obj.type == 'enum') { - var tmp = $(obj.helpers.multi).find('input'); - if (tmp.length == 0) search = ''; else search = tmp.val(); - } - if (obj.type == 'list') { - var tmp = $(obj.helpers.focus).find('input'); - if (tmp.length == 0) search = ''; else search = tmp.val(); - } - if (options.minLength != 0 && search.length < options.minLength) { - options.items = []; // need to empty the list - this.updateOverlay(); - return; - } - if (typeof interval == 'undefined') interval = 350; - if (typeof obj.tmp.xhr_search == 'undefined') obj.tmp.xhr_search = ''; - if (typeof obj.tmp.xhr_total == 'undefined') obj.tmp.xhr_total = -1; - // check if need to search - if (options.url && ( - (options.items.length === 0 && obj.tmp.xhr_total !== 0) || - (obj.tmp.xhr_total == options.cacheMax && search.length > obj.tmp.xhr_search.length) || - (search.length >= obj.tmp.xhr_search.length && search.substr(0, obj.tmp.xhr_search.length) != obj.tmp.xhr_search) || - (search.length < obj.tmp.xhr_search.length) - )) { - // empty list - obj.tmp.xhr_loading = true; - obj.search(); - // timeout - clearTimeout(obj.tmp.timeout); - obj.tmp.timeout = setTimeout(function () { - // trigger event - var url = options.url; - var postData = { - search : search, - max : options.cacheMax - }; - $.extend(postData, options.postData); - var eventData = obj.trigger({ phase: 'before', type: 'request', target: obj.el, url: url, postData: postData }); - if (eventData.isCancelled === true) return; - url = eventData.url; - postData = eventData.postData; - // console.log('REMOTE SEARCH:', search); - if (obj.tmp.xhr) obj.tmp.xhr.abort(); - obj.tmp.xhr = $.ajax({ - type : 'POST', - url : url, - data : postData - }) - .done(function (data, status, xhr) { - // trigger event - var eventData2 = obj.trigger({ phase: 'before', type: 'load', target: obj.el, search: postData.search, data: data, xhr: xhr }); - if (eventData2.isCancelled === true) return; - // default behavior - data = eventData2.data; - if (typeof data == 'string') data = JSON.parse(data); - if (data.status != 'success') { - console.log('ERROR: server did not return proper structure. It should return', { status: 'success', items: [{ id: 1, text: 'item' }] }); - return; - } - // remove all extra items if more then needed for cache - if (data.items.length > options.cacheMax) data.items.splice(options.cacheMax, 100000); - // remember stats - obj.tmp.xhr_loading = false; - obj.tmp.xhr_search = search; - obj.tmp.xhr_total = data.items.length; - options.items = data.items; - if (search == '' && data.items.length == 0) obj.tmp.emptySet = true; else obj.tmp.emptySet = false; - obj.search(); - // console.log('-->', 'retrieved:', obj.tmp.xhr_total); - // event after - obj.trigger($.extend(eventData2, { phase: 'after' })); - }) - .error(function (xhr, status, exceptionThrown) { - // trigger event - var errorObj = { status: status, exceptionThrown: exceptionThrown, rawResponseText: xhr.responseText }; - var eventData2 = obj.trigger({ phase: 'before', type: 'error', target: obj.el, search: search, error: errorObj, xhr: xhr }); - if (eventData2.isCancelled === true) return; - // default behavior - console.log('ERROR: server communication failed. The server should return', { status: 'success', items: [{ id: 1, text: 'item' }] }, ', instead the AJAX request produced this: ', errorObj); - // reset stats - obj.clearCache(); - // event after - obj.trigger($.extend(eventData2, { phase: 'after' })); - }); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, interval); - } - }, - - search: function () { - var obj = this; - var options = this.options; - var search = $(obj.el).val(); - var target = obj.el; - var ids = []; - var selected= $(obj.el).data('selected'); - if (obj.type == 'enum') { - target = $(obj.helpers.multi).find('input'); - search = target.val(); - for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } - } - if (obj.type == 'list') { - target = $(obj.helpers.focus).find('input'); - search = target.val(); - for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } - } - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'search', target: target, search: search }); - if (eventData.isCancelled === true) return; - if (obj.tmp.xhr_loading !== true) { - var shown = 0; - for (var i in options.items) { - var item = options.items[i]; - var prefix = ''; - var suffix = ''; - if (['is', 'begins'].indexOf(options.match) != -1) prefix = '^'; - if (['is', 'ends'].indexOf(options.match) != -1) suffix = '$'; - try { - var re = new RegExp(prefix + search + suffix, 'i'); - if (re.test(item.text) || item.text == '...') item.hidden = false; else item.hidden = true; - } catch (e) {} - // do not show selected items - if (obj.type == 'enum' && $.inArray(item.id, ids) != -1) item.hidden = true; - if (item.hidden !== true) shown++; - } - if (obj.type != 'combo') { // don't preselect first for combo - options.index = 0; - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } else { - options.index = -1; - } - if (shown <= 0) options.index = -1; - options.spinner = false; - obj.updateOverlay(); - setTimeout(function () { - var html = $('#w2ui-overlay').html() || ''; - if (options.markSearch && html.indexOf('$.fn.w2menuHandler') != -1) { // do not highlight when no items - $('#w2ui-overlay').w2marker(search); - } - }, 1); - } else { - options.items.splice(0, options.cacheMax); - options.spinner = true; - obj.updateOverlay(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - updateOverlay: function () { - var obj = this; - var options = this.options; - // color - if (this.type == 'color') { - if ($(obj.el).attr('readonly')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay(obj.getColorHTML()); - } else { - $('#w2ui-overlay').html(obj.getColorHTML()); - } - // bind events - $('#w2ui-overlay .color') - .on('mousedown', function (event) { - var color = $(event.originalEvent.target).attr('name'); - var index = $(event.originalEvent.target).attr('index').split(':'); - obj.tmp.cind1 = index[0]; - obj.tmp.cind2 = index[1]; - $(obj.el).val(color).change(); - $(this).html('•'); - }) - .on('mouseup', function () { - setTimeout(function () { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); - }, 10); - }); - } - // date - if (this.type == 'date') { - if ($(obj.el).attr('readonly')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay('
    ', { - css: { "background-color": "#f5f5f5" } - }); - } - var month, year; - var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true); - if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } - (function refreshCalendar(month, year) { - $('#w2ui-overlay > div > div').html(obj.getMonthHTML(month, year)); - $('#w2ui-overlay .w2ui-calendar-title') - .on('mousedown', function () { - if ($(this).next().hasClass('w2ui-calendar-jump')) { - $(this).next().remove(); - } else { - var selYear, selMonth; - $(this).after('
    '); - $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); - setTimeout(function () { - $('#w2ui-overlay .w2ui-calendar-jump') - .find('.w2ui-jump-month, .w2ui-jump-year') - .on('click', function () { - if ($(this).hasClass('w2ui-jump-month')) { - $(this).parent().find('.w2ui-jump-month').removeClass('selected'); - $(this).addClass('selected'); - selMonth = $(this).attr('name'); - } - if ($(this).hasClass('w2ui-jump-year')) { - $(this).parent().find('.w2ui-jump-year').removeClass('selected'); - $(this).addClass('selected'); - selYear = $(this).attr('name'); - } - if (selYear != null && selMonth != null) { - $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); - setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); - } - }); - $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); - }, 1); - } - }); - $('#w2ui-overlay .w2ui-date') - .on('mousedown', function () { - var day = $(this).attr('date'); - $(obj.el).val(day).change(); - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - }) - .on('mouseup', function () { - setTimeout(function () { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); - }, 10); - }); - $('#w2ui-overlay .previous').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) - 1; - refreshCalendar(tmp[0], tmp[1]); - }); - $('#w2ui-overlay .next').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) + 1; - refreshCalendar(tmp[0], tmp[1]); - }); - }) (month, year); - } - // date - if (this.type == 'time') { - if ($(obj.el).attr('readonly')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay('
    ', { - css: { "background-color": "#fff" } - }); - } - var h24 = (this.options.format == 'h24' ? true : false); - $('#w2ui-overlay > div').html(obj.getHourHTML()); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function (event) { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - var hour = $(this).attr('hour'); - $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }) - .on('mouseup', function () { - var hour = $(this).attr('hour'); - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); - $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function () { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - var min = $(this).attr('min'); - $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }) - .on('mouseup', function () { - setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); - }); - }); - } - // list - if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { - var el = this.el; - var input = this.el; - if (this.type == 'enum') { - el = $(this.helpers.multi); - input = $(el).find('input'); - } - if (this.type == 'list') { - input = $(this.helpers.focus).find('input'); - } - if ($(input).is(':focus')) { - if (options.openOnFocus === false && $(input).val() == '' && obj.tmp.force_open !== true) { - $().w2overlay(); - return; - } - if (obj.tmp.force_hide) { - $().w2overlay(); - setTimeout(function () { - delete obj.tmp.force_hide; - }, 1); - return; - } - if ($(input).val() != '') delete obj.tmp.force_open; - if ($('#w2ui-overlay').length == 0) options.index = 0; - var msgNoItems = w2utils.lang('No matches'); - if (options.url != null && $(input).val().length < options.minLength && obj.tmp.emptySet !== true) msgNoItems = options.minLength + ' ' + w2utils.lang('letters or more...'); - if (options.url != null && $(input).val() == '' && obj.tmp.emptySet !== true) msgNoItems = w2utils.lang('Type to search....'); - $(el).w2menu('refresh', $.extend(true, {}, options, { - search : false, - render : options.renderDrop, - maxHeight : options.maxDropHeight, - msgNoItems : msgNoItems, - // selected with mouse - onSelect: function (event) { - if (obj.type == 'enum') { - var selected = $(obj.el).data('selected'); - if (event.item) { - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: event.item }); - if (eventData.isCancelled === true) return; - // default behavior - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete event.item.hidden; - selected.push(event.item); - $(obj.el).data('selected', selected).change(); - $(obj.helpers.multi).find('input').val('').width(20); - obj.refresh(); - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - } else { - $(obj.el).data('selected', event.item).val(event.item.text).change(); - if (obj.helpers.focus) { - obj.helpers.focus.find('input').val(''); - obj.refresh(); - } - } - } - })); - } - } - }, - - inRange: function (str) { - var inRange = false; - if (this.type == 'date') { - var dt = w2utils.isDate(str, this.options.format, true); - if (dt) { - // enable range - if (this.options.start || this.options.end) { - var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); - var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); - var start = w2utils.isDate(st, this.options.format, true); - var end = w2utils.isDate(en, this.options.format, true); - var current = new Date(dt); - if (!start) start = current; - if (!end) end = current; - if (current >= start && current <= end) inRange = true; - } else { - inRange = true; - } - // block predefined dates - if (this.options.blocked && $.inArray(str, this.options.blocked) != -1) inRange = false; - } - } - if (this.type == 'time') { - if (this.options.start || this.options.end) { - var tm = this.toMin(str); - var tm1 = this.toMin(this.options.start); - var tm2 = this.toMin(this.options.end); - if (!tm1) tm1 = tm; - if (!tm2) tm2 = tm; - if (tm >= tm1 && tm <= tm2) inRange = true; - } else { - inRange = true; - } - } - return inRange; - }, - - /* - * INTERNAL FUNCTIONS - */ - - checkType: function (ch, loose) { - var obj = this; - switch (obj.type) { - case 'int': - if (loose && ['-'].indexOf(ch) != -1) return true; - return w2utils.isInt(ch.replace(obj.options.numberRE, '')); - case 'percent': - ch = ch.replace(/%/g, ''); - case 'float': - if (loose && ['-','.'].indexOf(ch) != -1) return true; - return w2utils.isFloat(ch.replace(obj.options.numberRE, '')); - case 'money': - case 'currency': - if (loose && ['-', '.', obj.options.groupSymbol, obj.options.currencyPrefix, obj.options.currencySuffix].indexOf(ch) != -1) return true; - return w2utils.isFloat(ch.replace(obj.options.moneyRE, '')); - case 'hex': - case 'color': - return w2utils.isHex(ch); - case 'alphanumeric': - return w2utils.isAlphaNumeric(ch); - } - return true; - }, - - addPrefix: function () { - var obj = this; - setTimeout(function () { - if (obj.type === 'clear') return; - var helper; - var tmp = $(obj.el).data('tmp') || {}; - if (tmp['old-padding-left']) $(obj.el).css('padding-left', tmp['old-padding-left']); - tmp['old-padding-left'] = $(obj.el).css('padding-left'); - $(obj.el).data('tmp', tmp); - if (obj.options.prefix !== '') { - // remove if already displaed - if (obj.helpers.prefix) $(obj.helpers.prefix).remove(); - // add fresh - $(obj.el).before( - '
    '+ - obj.options.prefix + - '
    ' - ); - helper = $(obj.el).prev(); - helper - .css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'padding-top' : $(obj.el).css('padding-top'), - 'padding-bottom' : $(obj.el).css('padding-bottom'), - 'padding-left' : $(obj.el).css('padding-left'), - 'padding-right' : 0, - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', - 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px', - 'margin-left' : $(obj.el).css('margin-left'), - 'margin-right' : 0 - }) - .on('click', function (event) { - if (obj.options.icon && typeof obj.onIconClick == 'function') { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'iconClick', target: obj.el, el: $(this).find('span.w2ui-icon')[0] }); - if (eventData.isCancelled === true) return; - - // intentionally empty - - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } else { - if (obj.type == 'list') { - $(obj.helpers.focus).find('input').focus(); - } else { - $(obj.el).focus(); - } - } - }); - $(obj.el).css('padding-left', (helper.width() + parseInt($(obj.el).css('padding-left'), 10)) + 'px'); - // remember helper - obj.helpers.prefix = helper; - } - }, 1); - }, - - addSuffix: function () { - var obj = this; - var helper, pr; - setTimeout(function () { - if (obj.type === 'clear') return; - var tmp = $(obj.el).data('tmp') || {}; - if (tmp['old-padding-right']) $(obj.el).css('padding-right', tmp['old-padding-right']); - tmp['old-padding-right'] = $(obj.el).css('padding-right'); - $(obj.el).data('tmp', tmp); - pr = parseInt($(obj.el).css('padding-right'), 10); - if (obj.options.arrows) { - // remove if already displaed - if (obj.helpers.arrows) $(obj.helpers.arrows).remove(); - // add fresh - $(obj.el).after( - '
     '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '); - var height = w2utils.getSize(obj.el, 'height'); - helper = $(obj.el).next(); - helper.css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'height' : ($(obj.el).height() + parseInt($(obj.el).css('padding-top'), 10) + parseInt($(obj.el).css('padding-bottom'), 10) ) + 'px', - 'padding' : 0, - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', - 'margin-bottom' : 0, - 'border-left' : '1px solid silver' - }) - .css('margin-left', '-'+ (helper.width() + parseInt($(obj.el).css('margin-right'), 10) + 12) + 'px') - .on('mousedown', function (event) { - $('body').on('mouseup', tmp); - $('body').data('_field_update_timer', setTimeout(update, 700)); - update(false); - // timer function - function tmp() { - clearTimeout($('body').data('_field_update_timer')); - $('body').off('mouseup', tmp); - } - // update function - function update(notimer) { - $(obj.el).focus(); - obj.keyDown($.Event("keydown"), { - keyCode : ($(event.target).attr('type') == 'up' ? 38 : 40) - }); - if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60)); - } - }); - pr += helper.width() + 12; - $(obj.el).css('padding-right', pr + 'px'); - // remember helper - obj.helpers.arrows = helper; - } - if (obj.options.suffix !== '') { - // remove if already displaed - if (obj.helpers.suffix) $(obj.helpers.suffix).remove(); - // add fresh - $(obj.el).after( - '
    '+ - obj.options.suffix + - '
    '); - helper = $(obj.el).next(); - helper - .css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'padding-top' : $(obj.el).css('padding-top'), - 'padding-bottom' : $(obj.el).css('padding-bottom'), - 'padding-left' : '3px', - 'padding-right' : $(obj.el).css('padding-right'), - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', - 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px' - }) - .on('click', function (event) { - if (obj.type == 'list') { - $(obj.helpers.focus).find('input').focus(); - } else { - $(obj.el).focus(); - } - }); - - helper.css('margin-left', '-'+ (w2utils.getSize(helper, 'width') + parseInt($(obj.el).css('margin-right'), 10) + 2) + 'px'); - pr += helper.width() + 3; - $(obj.el).css('padding-right', pr + 'px'); - // remember helper - obj.helpers.suffix = helper; - } - }, 1); - }, - - addFocus: function () { - var obj = this; - var options = this.options; - var width = 0; // 11 - show search icon, 0 do not show - if (options.icon) width = 11; - // clean up & init - $(obj.helpers.focus).remove(); - // build helper - var html = - '
    '+ - ' '+ - ' '+ - '
    '; - $(obj.el).attr('tabindex', -1).before(html); - var helper = $(obj.el).prev(); - obj.helpers.focus = helper; - helper.css({ - width : $(obj.el).width(), - "margin-top" : $(obj.el).css('margin-top'), - "margin-left" : (parseInt($(obj.el).css('margin-left')) + parseInt($(obj.el).css('padding-left'))) + 'px', - "margin-bottom" : $(obj.el).css('margin-bottom'), - "margin-right" : $(obj.el).css('margin-right'), - }) - .find('input') - .css({ - cursor : 'default', - width : '100%', - outline : 'none', - opacity : 1, - margin : 0, - border : '1px solid transparent', - padding : $(obj.el).css('padding-top'), - "padding-left" : 0, - "margin-left" : width + (width > 0 ? 6 : 0), - "background-color" : 'transparent' - }); - // INPUT events - helper.find('input') - .on('click', function (event) { - if ($('#w2ui-overlay').length == 0) obj.focus(event); - event.stopPropagation(); - }) - .on('focus', function (event) { - $(obj.el).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - $(this).val(''); - $(obj.el).triggerHandler('focus'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('blur', function (event) { - $(obj.el).css('outline', 'none'); - $(this).val(''); - obj.refresh(); - $(obj.el).triggerHandler('blur'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('keyup', function (event) { obj.keyUp(event) }) - .on('keydown', function (event) { obj.keyDown(event) }) - .on('keypress', function (event) { obj.keyPress(event); }); - // MAIN div - helper.on('click', function (event) { $(this).find('input').focus(); }); - obj.refresh(); - }, - - addMulti: function () { - var obj = this; - var options = this.options; - // clean up & init - $(obj.helpers.multi).remove(); - // build helper - var html = ''; - var margin = - 'margin-top : 0px; ' + - 'margin-bottom : 0px; ' + - 'margin-left : ' + $(obj.el).css('margin-left') + '; ' + - 'margin-right : ' + $(obj.el).css('margin-right') + '; '+ - 'width : ' + (w2utils.getSize(obj.el, 'width') - - parseInt($(obj.el).css('margin-left'), 10) - - parseInt($(obj.el).css('margin-right'), 10)) - + 'px;'; - if (obj.type == 'enum') { - html = '
    '+ - '
    '+ - '
      '+ - '
    • '+ - ' '+ - '
    • ' - '
    '+ - '
    '+ - '
    '; - } - if (obj.type == 'file') { - html = '
    '+ - '
    '+ - '
    '+ - ' ' - '
    '+ - '
    '; - } - $(obj.el) - .before(html) - .css({ - 'background-color' : 'transparent', - 'border-color' : 'transparent' - }); - - var div = $(obj.el).prev(); - obj.helpers.multi = div; - if (obj.type == 'enum') { - $(obj.el).attr('tabindex', -1); - // INPUT events - div.find('input') - .on('click', function (event) { - if ($('#w2ui-overlay').length == 0) obj.focus(event); - $(obj.el).triggerHandler('click'); - }) - .on('focus', function (event) { - $(div).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - $(obj.el).triggerHandler('focus'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('blur', function (event) { - $(div).css('outline', 'none'); - $(obj.el).triggerHandler('blur'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('keyup', function (event) { obj.keyUp(event) }) - .on('keydown', function (event) { obj.keyDown(event) }) - .on('keypress', function (event) { div.find('.w2ui-enum-placeholder').remove(); obj.keyPress(event); }); - // MAIN div - div.on('click', function (event) { $(this).find('input').focus(); }); - } - if (obj.type == 'file') { - $(obj.el).css('outline', 'none'); - div.on('click', function (event) { - $(obj.el).focus(); - if ($(obj.el).attr('readonly')) return; - obj.blur(event); - div.find('input').click(); - }) - .on('dragenter', function (event) { - if ($(obj.el).attr('readonly')) return; - $(div).addClass('w2ui-file-dragover'); - }) - .on('dragleave', function (event) { - if ($(obj.el).attr('readonly')) return; - var tmp = $(event.target).parents('.w2ui-field-helper'); - if (tmp.length == 0) $(div).removeClass('w2ui-file-dragover'); - }) - .on('drop', function (event) { - if ($(obj.el).attr('readonly')) return; - $(div).removeClass('w2ui-file-dragover'); - var files = event.originalEvent.dataTransfer.files; - for (var i=0, l=files.length; i options.maxFileSize) { - err = 'Maximum file size is '+ w2utils.size(options.maxFileSize); - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { - err = 'Maximum total size is '+ w2utils.size(options.maxSize); - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (options.max !== 0 && cnt >= options.max) { - err = 'Maximum number of files is '+ options.max; - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - selected.push(newItem); - // read file as base64 - if (typeof FileReader !== "undefined") { - var reader = new FileReader(); - // need a closure - reader.onload = (function () { - return function (event) { - var fl = event.target.result; - var ind = fl.indexOf(','); - newItem.content = fl.substr(ind+1); - obj.refresh(); - $(obj.el).trigger('change'); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }; - })(); - reader.readAsDataURL(file); - } else { - obj.refresh(); - $(obj.el).trigger('change'); - } - }, - - normMenu: function (menu) { - if ($.isArray(menu)) { - for (var m = 0; m < menu.length; m++) { - if (typeof menu[m] == 'string') { - menu[m] = { id: menu[m], text: menu[m] }; - } else { - if (typeof menu[m].text != 'undefined' && typeof menu[m].id == 'undefined') menu[m].id = menu[m].text; - if (typeof menu[m].text == 'undefined' && typeof menu[m].id != 'undefined') menu[m].text = menu[m].id; - if (typeof menu[m].caption != 'undefined') menu[m].text = menu[m].caption; - } - } - return menu; - } else if (typeof menu == 'object') { - var tmp = [] - for (var m in menu) tmp.push({ id: m, text: menu[m] }); - return tmp; - } - }, - - getColorHTML: function () { - var html = '
    '+ - ''; - for (var i = 0; i < 8; i++) { - html += ''; - for (var j = 0; j < 8; j++) { - html += ''; - } - html += ''; - if (i < 2) html += ''; - } - html += '
    '+ - '
    '+ - ' '+ ($(this.el).val() == this.pallete[i][j] ? '•' : ' ')+ - '
    '+ - '
    '; - return html; - }, - - getMonthHTML: function (month, year) { - var td = new Date(); - var months = w2utils.settings.fullmonths; - var days = w2utils.settings.fulldays; - var daysCount = ['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31']; - var today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate(); - // normalize date - year = w2utils.isInt(year) ? parseInt(year) : td.getFullYear(); - month = w2utils.isInt(month) ? parseInt(month) : td.getMonth() + 1; - if (month > 12) { month -= 12; year++; } - if (month < 1 || month === 0) { month += 12; year--; } - if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; } - this.options.current = month + '/' + year; - - // start with the required date - td = new Date(year, month-1, 1); - var weekDay = td.getDay(); - var tabDays = w2utils.settings.shortdays; - var dayTitle = ''; - for ( var i = 0, len = tabDays.length; i < len; i++) { - dayTitle += '' + tabDays[i] + ''; - } - var html = - '
    '+ - ' '+ - ' '+ - months[month-1] +', '+ year + - '
    '+ - ''+ - ' ' + dayTitle + ''+ - ' '; - - var day = 1; - for (var ci=1; ci<43; ci++) { - if (weekDay === 0 && ci == 1) { - for (var ti=0; ti<6; ti++) html += ''; - ci += 6; - } else { - if (ci < weekDay || day > daysCount[month-1]) { - html += ''; - if ((ci) % 7 === 0) html += ''; - continue; - } - } - var dt = year + '/' + month + '/' + day; - - var className = ''; - if (ci % 7 == 6) className = ' w2ui-saturday'; - if (ci % 7 === 0) className = ' w2ui-sunday'; - if (dt == today) className += ' w2ui-today'; - - var dspDay = day; - var col = ''; - var bgcol = ''; - var tmp_dt = w2utils.formatDate(dt, this.options.format); - if (this.options.colored && this.options.colored[tmp_dt] !== undefined) { // if there is predefined colors for dates - tmp = this.options.colored[tmp_dt].split(':'); - bgcol = 'background-color: ' + tmp[0] + ';'; - col = 'color: ' + tmp[1] + ';'; - } - html += ''; - if (ci % 7 === 0 || (weekDay === 0 && ci == 1)) html += ''; - day++; - } - html += '
      
    '+ - dspDay + - '
    '; - return html; - }, - - getYearHTML: function () { - var months = w2utils.settings.shortmonths; - var mhtml = ''; - var yhtml = ''; - for (var m in months) { - mhtml += '
    '+ months[m] + '
    '; - } - for (var y = 1950; y <= 2020; y++) { - yhtml += '
    '+ y + '
    ' - } - return '
    '+ mhtml +'
    '+ yhtml +'
    '; - }, - - getHourHTML: function () { - var tmp = []; - var h24 = (this.options.format == 'h24' ? true : false); - for (var a=0; a<24; a++) { - var time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : ''); - if (a == 12 && !h24) time = '12:00 pm'; - if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = ''; - var tm1 = this.fromMin(this.toMin(time)); - var tm2 = this.fromMin(this.toMin(time) + 59); - tmp[Math.floor(a/8)] += '
    '+ time +'
    '; - } - var html = - '
    '+ - ' ' + - ' ' + - ' ' + - '
    '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
    '; - return html; - }, - - getMinHTML: function (hour) { - if (typeof hour == 'undefined') hour = 0; - var h24 = (this.options.format == 'h24' ? true : false); - var tmp = []; - for (var a=0; a<60; a+=5) { - var time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : ''); - var ind = a < 20 ? 0 : (a < 40 ? 1 : 2); - if (!tmp[ind]) tmp[ind] = ''; - tmp[ind] += '
    '+ time +'
    '; - } - var html = - '
    '+ - ' ' + - ' ' + - ' ' + - '
    '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
    '; - return html; - }, - - toMin: function (str) { - if (typeof str != 'string') return null; - var tmp = str.split(':'); - if (tmp.length == 2) { - tmp[0] = parseInt(tmp[0]); - tmp[1] = parseInt(tmp[1]); - if (str.indexOf('pm') != -1 && tmp[0] != 12) tmp[0] += 12; - } else { - return null; - } - return tmp[0] * 60 + tmp[1]; - }, - - fromMin: function (time) { - var ret = ''; - if (time >= 24 * 60) time = time % (24 * 60); - if (time < 0) time = 24 * 60 + time; - var hour = Math.floor(time/60); - var min = ((time % 60) < 10 ? '0' : '') + (time % 60); - if (this.options.format.indexOf('h24') != -1) { - ret = hour + ':' + min; - } else { - ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am'); - } - return ret; - } - } - - $.extend(w2field.prototype, w2utils.event); - w2obj.field = w2field; + var w2field = function (options) { + // public properties + this.el = null + this.helpers = {}; // object or helper elements + this.type = options.type || 'text'; + this.options = $.extend(true, {}, options); + this.onSearch = options.onSearch || null; + this.onRequest = options.onRequest || null; + this.onLoad = options.onLoad || null; + this.onError = options.onError || null; + this.onClick = options.onClick || null; + this.onAdd = options.onAdd || null; + this.onNew = options.onNew || null; + this.onRemove = options.onRemove || null; + this.onMouseOver = options.onMouseOver || null; + this.onMouseOut = options.onMouseOut || null; + this.onIconClick = options.onIconClick || null; + this.tmp = {}; // temp object + // clean up some options + delete this.options.type; + delete this.options.onSearch; + delete this.options.onRequest; + delete this.options.onLoad; + delete this.options.onError; + delete this.options.onClick; + delete this.options.onMouseOver; + delete this.options.onMouseOut; + delete this.options.onIconClick; + // extend with defaults + $.extend(true, this, w2obj.field); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2field = function (method, options) { + // call direct + if (this.length == 0) { + var pr = w2field.prototype; + if (pr[method]) { + return pr[method].apply(pr, Array.prototype.slice.call(arguments, 1)); + } + } else { + if (typeof method == 'string' && typeof options == 'object') { + method = $.extend(true, {}, options, { type: method }); + } + if (typeof method == 'string' && typeof options == 'undefined') { + method = { type: method }; + } + method.type = String(method.type).toLowerCase(); + return this.each(function (index, el) { + var obj = $(el).data('w2field'); + // if object is not defined, define it + if (typeof obj == 'undefined') { + var obj = new w2field(method); + $.extend(obj, { handlers: [] }); + if (el) obj.el = $(el)[0]; + obj.init(); + $(el).data('w2field', obj); + return obj; + } else { // fully re-init + obj.clear(); + if (method.type == 'clear') return; + var obj = new w2field(method); + $.extend(obj, { handlers: [] }); + if (el) obj.el = $(el)[0]; + obj.init(); + $(el).data('w2field', obj); + return obj; + } + return null; + }); + } + } + + // ==================================================== + // -- Implementation of core functionality + + /* To add custom types + $().w2field('addType', 'myType', function (options) { + $(this.el).on('keypress', function (event) { + if (event.metaKey || event.ctrlKey || event.altKey + || (event.charCode != event.keyCode && event.keyCode > 0)) return; + var ch = String.fromCharCode(event.charCode); + if (ch != 'a' && ch != 'b' && ch != 'c') { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + return false; + } + }); + $(this.el).on('blur', function (event) { // keyCode & charCode differ in FireFox + var ch = this.value; + if (ch != 'a' && ch != 'b' && ch != 'c') { + $(this).w2tag(w2utils.lang("Not a single charecter from the set of 'abc'")); + } + }); + }); + */ + + w2field.prototype = { + + custom: {}, // map of custom types + + pallete: [ + ['000000', '444444', '666666', '999999', 'CCCCCC', 'EEEEEE', 'F3F3F3', 'FFFFFF'], + ['FF011B', 'FF9838', 'FFFD59', '01FD55', '00FFFE', '0424F3', '9B24F4', 'FF21F5'], + ['F4CCCC', 'FCE5CD', 'FFF2CC', 'D9EAD3', 'D0E0E3', 'CFE2F3', 'D9D1E9', 'EAD1DC'], + ['EA9899', 'F9CB9C', 'FEE599', 'B6D7A8', 'A2C4C9', '9FC5E8', 'B4A7D6', 'D5A6BD'], + ['E06666', 'F6B26B', 'FED966', '93C47D', '76A5AF', '6FA8DC', '8E7CC3', 'C27BA0'], + ['CC0814', 'E69138', 'F1C232', '6AA84F', '45818E', '3D85C6', '674EA7', 'A54D79'], + ['99050C', 'B45F17', 'BF901F', '37761D', '124F5C', '0A5394', '351C75', '741B47'], + ['660205', '783F0B', '7F6011', '274E12', '0C343D', '063762', '20124D', '4C1030'] + ], + + addType: function (type, handler) { + type = String(type).toLowerCase(); + this.custom[type] = handler; + return true; + }, + + removeType: function (type) { + type = String(type).toLowerCase(); + if (!this.custom[type]) return false; + delete this.custom[type]; + return true + }, + + init: function () { + var obj = this; + var options = this.options; + var defaults; + + // Custom Types + if (typeof this.custom[this.type] == 'function') { + this.custom[this.type].call(this, options); + return; + } + // only for INPUT or TEXTAREA + if (['INPUT', 'TEXTAREA'].indexOf(this.el.tagName) == -1) { + console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el); + return; + } + + switch (this.type) { + case 'text': + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'alphanumeric': + case 'hex': + defaults = { + min : null, + max : null, + step : 1, + placeholder : '', + autoFormat : true, + currencyPrefix : w2utils.settings.currencyPrefix, + currencySuffix : w2utils.settings.currencySuffix, + currencyPrecision : w2utils.settings.currencyPrecision, + groupSymbol : w2utils.settings.groupSymbol, + arrows : false, + keyboard : true, + precision : null, + silent : true, + prefix : '', + suffix : '' + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g'); + options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol + ']', 'g'); + options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g'); + // no keyboard support needed + if (['text', 'alphanumeric', 'hex'].indexOf(this.type) != -1) { + options.arrows = false; + options.keyboard = false; + } + this.addPrefix(); // only will add if needed + this.addSuffix(); + $(this.el).attr('placeholder', options.placeholder); + break; + + case 'color': + defaults = { + prefix : '#', + suffix : '
     
    ', + placeholder : '', + arrows : false, + keyboard : false + }; + $.extend(options, defaults); + this.addPrefix(); // only will add if needed + this.addSuffix(); // only will add if needed + // additional checks + $(this.el).attr('maxlength', 6); + if ($(this.el).val() != '') setTimeout(function () { $(obj.el).change(); }, 1); + $(this.el).attr('placeholder', options.placeholder); + break; + + case 'date': + defaults = { + format : w2utils.settings.date_format, // date format + placeholder : '', + keyboard : true, + silent : true, + start : '', // string or jquery object + end : '', // string or jquery object + blocked : {}, // { '4/11/2011': 'yes' } + colored : {} // { '4/11/2011': 'red:white' } + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + $(this.el).attr('placeholder', options.placeholder ? options.placeholder : options.format); + break; + + case 'time': + defaults = { + format : w2utils.settings.time_format, + placeholder : '', + keyboard : true, + silent : true, + start : '', + end : '' + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + $(this.el).attr('placeholder', options.placeholder ? options.placeholder : (options.format == 'h12' ? 'hh:mi pm' : 'hh:mi')); + break; + + case 'datetime': + break; + + case 'list': + case 'combo': + defaults = { + items : [], + selected : {}, + placeholder : '', + url : null, // url to pull data from + postData : {}, + minLength : 1, + cacheMax : 250, + maxDropHeight : 350, // max height for drop down menu + match : 'begins', // ['contains', 'is', 'begins', 'ends'] + silent : true, + icon : null, + iconStyle : '', + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onIconClick : null, + renderDrop : null, // render function for drop down item + prefix : '', + suffix : '', + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : false + }; + if (this.type == 'list') { + // defaults.search = (options.items && options.items.length >= 10 ? true : false); + defaults.openOnFocus = true; + defaults.suffix = '
    '; + $(this.el).addClass('w2ui-select'); + // if simple value - look it up + if (!$.isPlainObject(options.selected)) { + for (var i in options.items) { + var item = options.items[i]; + if (item && item.id == options.selected) { + options.selected = $.extend(true, {}, item); + break; + } + } + } + } + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + altRows : true // alternate row color + }); + options.items = this.normMenu(options.items); + this.options = options; + if (!$.isPlainObject(options.selected)) options.selected = {}; + $(this.el).data('selected', options.selected); + if (options.url) this.request(0); + if (options.icon) { + options.prefix = ''+ + ''; + } + if (this.type == 'list') this.addFocus(); + this.addPrefix(); + this.addSuffix(); + setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh + $(this.el).attr('placeholder', options.placeholder).attr('autocomplete', 'off'); + if (typeof options.selected.text != 'undefined') $(this.el).val(options.selected.text); + break; + + case 'enum': + defaults = { + items : [], + selected : [], + placeholder : '', + max : 0, // max number of selected items, 0 - unlim + url : null, // not implemented + postData : {}, + minLength : 1, + cacheMax : 250, + maxWidth : 250, // max width for a single item + maxHeight : 350, // max height for input control to grow + maxDropHeight : 350, // max height for drop down menu + match : 'contains', // ['contains', 'is', 'begins', 'ends'] + silent : true, + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : true, + renderDrop : null, // render function for drop down item + renderItem : null, // render selected item + style : '', // style for container div + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onNew : null, // when new item should be added + onRemove : null, // when an item is removed + onMouseOver : null, // when an item is mouse over + onMouseOut : null // when an item is mouse out + }; + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + suffix : '', + altRows : true // alternate row color + }); + options.items = this.normMenu(options.items); + options.selected = this.normMenu(options.selected); + this.options = options; + if (!$.isArray(options.selected)) options.selected = []; + $(this.el).data('selected', options.selected); + if (options.url) this.request(0); + this.addSuffix(); + this.addMulti(); + break; + + case 'file': + defaults = { + selected : [], + placeholder : w2utils.lang('Attach files by dragging and dropping or Click to Select'), + max : 0, + maxSize : 0, // max size of all files, 0 - unlim + maxFileSize : 0, // max size of a single file, 0 -unlim + maxWidth : 250, // max width for a single item + maxHeight : 350, // max height for input control to grow + maxDropHeight : 350, // max height for drop down menu + silent : true, + renderItem : null, // render selected item + style : '', // style for container div + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onRemove : null, // when an item is removed + onMouseOver : null, // when an item is mouse over + onMouseOut : null, // when an item is mouse out + }; + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + altRows : true // alternate row color + }); + this.options = options; + if (!$.isArray(options.selected)) options.selected = []; + $(this.el).data('selected', options.selected); + this.addMulti(); + break; + } + // attach events + this.tmp = { + onChange : function (event) { obj.change.call(obj, event) }, + onClick : function (event) { obj.click.call(obj, event) }, + onFocus : function (event) { obj.focus.call(obj, event) }, + onBlur : function (event) { obj.blur.call(obj, event) }, + onKeydown : function (event) { obj.keyDown.call(obj, event) }, + onKeyup : function (event) { obj.keyUp.call(obj, event) }, + onKeypress : function (event) { obj.keyPress.call(obj, event) } + } + $(this.el) + .addClass('w2field') + .data('w2field', this) + .on('change', this.tmp.onChange) + .on('click', this.tmp.onClick) // ignore click because it messes overlays + .on('focus', this.tmp.onFocus) + .on('blur', this.tmp.onBlur) + .on('keydown', this.tmp.onKeydown) + .on('keyup', this.tmp.onKeyup) + .on('keypress', this.tmp.onKeypress) + .css({ + 'box-sizing' : 'border-box', + '-webkit-box-sizing' : 'border-box', + '-moz-box-sizing' : 'border-box', + '-ms-box-sizing' : 'border-box', + '-o-box-sizing' : 'border-box' + }); + // format initial value + this.change($.Event('change')); + }, + + clear: function () { + var obj = this; + var options = this.options; + // if money then clear value + if (['money', 'currency'].indexOf(this.type) != -1) { + $(this.el).val($(this.el).val().replace(options.moneyRE, '')); + } + if (this.type == 'percent') { + $(this.el).val($(this.el).val().replace(/%/g, '')); + } + if (this.type == 'color') { + $(this.el).removeAttr('maxlength'); + } + if (this.type == 'list') { + $(this.el).removeClass('w2ui-select'); + } + this.type = 'clear'; + var tmp = $(this.el).data('tmp'); + if (!this.tmp) return; + // restore paddings + if (typeof tmp != 'undefined') { + if (tmp && tmp['old-padding-left']) $(this.el).css('padding-left', tmp['old-padding-left']); + if (tmp && tmp['old-padding-right']) $(this.el).css('padding-right', tmp['old-padding-right']); + } + // remove events and data + $(this.el) + .val(this.clean($(this.el).val())) + .removeClass('w2field') + .removeData() // removes all attached data + .off('change', this.tmp.onChange) + .off('click', this.tmp.onClick) + .off('focus', this.tmp.onFocus) + .off('blur', this.tmp.onBlur) + .off('keydown', this.tmp.onKeydown) + .off('keyup', this.tmp.onKeyup) + .off('keypress', this.tmp.onKeypress); + // remove helpers + for (var h in this.helpers) $(this.helpers[h]).remove(); + this.helpers = {}; + }, + + refresh: function () { + var obj = this; + var options = this.options; + var selected = $(this.el).data('selected'); + var time = (new Date()).getTime(); + // enum + if (['list'].indexOf(this.type) != -1) { + $(obj.el).parent().css('white-space', 'nowrap'); // needs this for arrow alway to appear on the right side + // hide focus and show text + if (obj.helpers.prefix) obj.helpers.prefix.hide(); + setTimeout(function () { + var focus = obj.helpers.focus.find('input'); + if ($(focus).val() == '') { + $(focus).css('opacity', 0).prev().css('opacity', 0); + $(obj.el).val(selected && selected.text != null ? selected.text : ''); + $(obj.el).attr('placeholder', $(obj.el).attr('_placeholder')); + // if empty show no icon + if ($.isEmptyObject(selected)) { + if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); + } else { + if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.show(); + } + } else { + $(focus).css('opacity', 1).prev().css('opacity', 1); + if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); + $(obj.el).val(''); + $(obj.el).attr('_placeholder', $(obj.el).attr('placeholder')).removeAttr('placeholder'); + } + }, 1); + } + if (['enum', 'file'].indexOf(this.type) != -1) { + var html = ''; + for (var s in selected) { + var it = selected[s]; + var ren = ''; + if (typeof options.renderItem == 'function') { + ren = options.renderItem(it, s, '
      
    '); + } else { + ren = '
      
    '+ + (obj.type == 'enum' ? it.text : it.name + ' - '+ w2utils.size(it.size) +''); + } + html += '
  • '+ + ren +'
  • '; + } + var div = obj.helpers.multi; + var ul = div.find('ul'); + div.attr('style', div.attr('style') + ';' + options.style); + if ($(obj.el).attr('readonly')) div.addClass('w2ui-readonly'); else div.removeClass('w2ui-readonly'); + // celan + div.find('.w2ui-enum-placeholder').remove(); + ul.find('li').not('li.nomouse').remove(); + // add new list + if (html != '') { + ul.prepend(html); + } else if (typeof options.placeholder != 'undefined') { + var style = + 'padding-top: ' + $(this.el).css('padding-top') + ';'+ + 'padding-left: ' + $(this.el).css('padding-left') + '; ' + + 'box-sizing: ' + $(this.el).css('box-sizing') + '; ' + + 'line-height: ' + $(this.el).css('line-height') + '; ' + + 'font-size: ' + $(this.el).css('font-size') + '; ' + + 'font-family: ' + $(this.el).css('font-family') + '; '; + div.prepend('
    '+ options.placeholder + '
    '); + } + // ITEMS events + div.find('li') + .data('mouse', 'out') + .on('click', function (event) { + var item = selected[$(event.target).attr('index')]; + if ($(event.target).hasClass('nomouse')) return; + event.stopPropagation(); + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'click', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // default behavior + if ($(event.target).hasClass('w2ui-list-remove')) { + if ($(obj.el).attr('readonly')) return; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // default behavior + $().w2overlay(); + selected.splice($(event.target).attr('index'), 1); + $(obj.el).trigger('change'); + $(event.target).parent().fadeOut('fast'); + setTimeout(function () { + obj.refresh(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 300); + } + if (obj.type == 'file' && !$(event.target).hasClass('w2ui-list-remove')) { + var preview = ''; + if ((/image/i).test(item.type)) { // image + preview = '
    '+ + ' '+ + '
    '; + } + var td1 = 'style="padding: 3px; text-align: right; color: #777;"'; + var td2 = 'style="padding: 3px"'; + preview += '
    '+ + ' '+ + ' '+ + ' '+ + ' '+ + ' '+ + '
    Name:'+ item.name +'
    Size:'+ w2utils.size(item.size) +'
    Type:' + + ' '+ item.type +''+ + '
    Modified:'+ w2utils.date(item.modified) +'
    '+ + '
    '; + $(event.target).w2overlay(preview); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }) + .on('mouseover', function (event) { + var tmp = event.target; + if (tmp.tagName != 'LI') tmp = tmp.parentNode; + if ($(tmp).hasClass('nomouse')) return; + if ($(tmp).data('mouse') == 'out') { + var item = selected[$(tmp).attr('index')]; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'mouseOver', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + $(tmp).data('mouse', 'over'); + }) + .on('mouseout', function (event) { + var tmp = event.target; + if (tmp.tagName != 'LI') tmp = tmp.parentNode; + if ($(tmp).hasClass('nomouse')) return; + $(tmp).data('mouse', 'leaving'); + setTimeout(function () { + if ($(tmp).data('mouse') == 'leaving') { + $(tmp).data('mouse', 'out'); + var item = selected[$(tmp).attr('index')]; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'f', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + }, 0); + }); + // adjust height + $(this.el).height('auto'); + var cntHeight = $(div).find('> div').height() + w2utils.getSize(div, '+height') * 2; + if (cntHeight < 26) cntHeight = 26; + if (cntHeight > options.maxHeight) cntHeight = options.maxHeight; + if (div.length > 0) div[0].scrollTop = 1000; + var inpHeight = w2utils.getSize($(this.el), 'height') - 2; + if (inpHeight > cntHeight) cntHeight = inpHeight + $(div).css({ 'height': cntHeight + 'px', overflow: (cntHeight == options.maxHeight ? 'auto' : 'hidden') }); + if (cntHeight < options.maxHeight) $(div).prop('scrollTop', 0); + $(this.el).css({ 'height' : (cntHeight + 2) + 'px' }); + } + return (new Date()).getTime() - time; + }, + + reset: function () { + var obj = this; + var type = this.type; + this.clear(); + this.type = type; + this.init(); + }, + + clean: function (val) { + var options = this.options; + val = String(val).trim(); + // clean + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { + if (options.autoFormat && ['money', 'currency'].indexOf(this.type) != -1) val = String(val).replace(options.moneyRE, ''); + if (options.autoFormat && this.type == 'percent') val = String(val).replace(options.percentRE, ''); + if (options.autoFormat && ['int', 'float'].indexOf(this.type) != -1) val = String(val).replace(options.numberRE, ''); + if (parseFloat(val) == val) { + if (options.min !== null && val < options.min) { val = options.min; $(this.el).val(options.min); } + if (options.max !== null && val > options.max) { val = options.max; $(this.el).val(options.max); } + } + if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = ''; + } + return val; + }, + + format: function (val) { + var options = this.options; + // autoformat numbers or money + if (options.autoFormat && val != '') { + switch (this.type) { + case 'money': + case 'currency': + val = w2utils.formatNumber(Number(val).toFixed(options.currencyPrecision), options.groupSymbol); + if (val != '') val = options.currencyPrefix + val + options.currencySuffix; + break; + case 'percent': + val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); + if (val != '') val += '%'; + break; + case 'float': + val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); + break; + case 'int': + val = w2utils.formatNumber(val, options.groupSymbol); + break; + } + } + return val; + }, + + change: function (event) { + var obj = this; + var options = obj.options; + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { + // check max/min + var val = $(this.el).val(); + var new_val = this.format(this.clean($(this.el).val())); + // if was modified + if (val != '' && val != new_val) { + $(this.el).val(new_val).change(); + // cancel event + event.stopPropagation(); + event.preventDefault(); + return false; + } + } + // color + if (this.type == 'color') { + var color = '#' + $(this.el).val(); + if ($(this.el).val().length != 6 && $(this.el).val().length != 3) color = ''; + $(this.el).next().find('div').css('background-color', color); + if ($(obj.el).is(':focus')) this.updateOverlay(); + } + }, + + click: function (event) { + event.stopPropagation(); + // lists + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + if (!$(this.el).is(':focus')) this.focus(event); + } + // other fields with drops + if (['date', 'time', 'color'].indexOf(this.type) != -1) { + this.updateOverlay(); + } + }, + + focus: function (event) { + var obj = this; + var options = this.options; + // color, date, time + if (['color', 'date', 'time'].indexOf(obj.type) !== -1) { + if ($(obj.el).attr('readonly')) return; + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + setTimeout(function () { obj.updateOverlay(); }, 150); + } + // menu + if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($(obj.el).attr('readonly')) return; + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + setTimeout(function () { + if (obj.type == 'list' && $(obj.el).is(':focus')) { + $(obj.helpers.focus).find('input').focus(); + return; + } + obj.search(); + setTimeout(function () { obj.updateOverlay(); }, 1); + }, 1); + } + // file + if (obj.type == 'file') { + $(obj.helpers.multi).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); + } + }, + + blur: function (event) { + var obj = this; + var options = obj.options; + var val = $(obj.el).val().trim(); + // hide overlay + if (['color', 'date', 'time', 'list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + } + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { + if (val !== '' && !obj.checkType(val)) { + $(obj.el).val('').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid number'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + } + // date or time + if (['date', 'time'].indexOf(obj.type) != -1) { + if (w2utils.isInt(obj.el.value)) { + $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); + } + // check if in range + if (val !== '' && !obj.inRange(obj.el.value)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not in range'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } else { + if (obj.type == 'date' && val !== '' && !w2utils.isDate(obj.el.value, options.format)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid date'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + if (obj.type == 'time' && val !== '' && !w2utils.isTime(obj.el.value)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid time'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + } + } + // clear search input + if (obj.type == 'enum') { + $(obj.helpers.multi).find('input').val('').width(20); + } + // file + if (obj.type == 'file') { + $(obj.helpers.multi).css({ 'outline': 'none' }); + } + }, + + keyPress: function (event) { + var obj = this; + var options = obj.options; + // ignore wrong pressed key + if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'color', 'alphanumeric'].indexOf(obj.type) != -1) { + // keyCode & charCode differ in FireFox + if (event.metaKey || event.ctrlKey || event.altKey || (event.charCode != event.keyCode && event.keyCode > 0)) return; + var ch = String.fromCharCode(event.charCode); + if (!obj.checkType(ch, true) && event.keyCode != 13) { + event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + return false; + } + } + // update date popup + if (['date', 'time'].indexOf(obj.type) != -1) { + setTimeout(function () { obj.updateOverlay(); }, 1); + } + }, + + keyDown: function (event, extra) { + var obj = this; + var options = obj.options; + var key = event.keyCode || (extra && extra.keyCode); + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { + if (!options.keyboard || $(obj.el).attr('readonly')) return; + var cancel = false; + var val = parseFloat($(obj.el).val().replace(options.moneyRE, '')) || 0; + var inc = options.step; + if (event.ctrlKey || event.metaKey) inc = 10; + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + $(obj.el).val((val + inc <= options.max || options.max === null ? Number((val + inc).toFixed(12)) : options.max)).change(); + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + $(obj.el).val((val - inc >= options.min || options.min === null ? Number((val - inc).toFixed(12)) : options.min)).change(); + cancel = true; + break; + } + if (cancel) { + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + }, 0); + } + } + // date + if (obj.type == 'date') { + if (!options.keyboard || $(obj.el).attr('readonly')) return; + var cancel = false; + var daymil = 24*60*60*1000; + var inc = 1; + if (event.ctrlKey || event.metaKey) inc = 10; + if (w2utils.isInt(obj.el.value)) { + $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); + } + var dt = w2utils.isDate($(obj.el).val(), options.format, true); + if (!dt) { dt = new Date(); daymil = 0; } + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDate(dt.getTime() + daymil, options.format); + if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDate(dt.getTime() - daymil, options.format); + if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + } + if (cancel) { + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + obj.updateOverlay(); + }, 0); + } + } + // time + if (obj.type == 'time') { + if (!options.keyboard || $(obj.el).attr('readonly')) return; + var cancel = false; + var inc = 1; + if (event.ctrlKey || event.metaKey) inc = 60; + if (w2utils.isInt(obj.el.value)) { + $(obj.el).val(w2utils.formatTime(new Date(parseInt(obj.el.value)), options.format)).change(); + } + var val = $(obj.el).val(); + var time = obj.toMin(val) || obj.toMin((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)); + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + time += inc; + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + time -= inc; + cancel = true; + break; + } + if (cancel) { + $(obj.el).val(obj.fromMin(time)).change(); + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + }, 0); + } + } + // color + if (obj.type == 'color') { + if ($(obj.el).attr('readonly')) return; + // paste + if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { + $(obj.el).prop('maxlength', 7); + setTimeout(function () { + var val = $(obj).val(); + if (val.substr(0, 1) == '#') val = val.substr(1); + if (!w2utils.isHex(val)) val = ''; + $(obj).val(val).prop('maxlength', 6).change(); + }, 20); + } + if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { + if (typeof obj.tmp.cind1 == 'undefined') { + obj.tmp.cind1 = -1; + obj.tmp.cind2 = -1; + } else { + switch (key) { + case 38: // up + obj.tmp.cind1--; + break; + case 40: // down + obj.tmp.cind1++; + break; + case 39: // right + obj.tmp.cind2++; + break; + case 37: // left + obj.tmp.cind2--; + break; + } + if (obj.tmp.cind1 < 0) obj.tmp.cind1 = 0; + if (obj.tmp.cind1 > this.pallete.length - 1) obj.tmp.cind1 = this.pallete.length - 1; + if (obj.tmp.cind2 < 0) obj.tmp.cind2 = 0; + if (obj.tmp.cind2 > this.pallete[0].length - 1) obj.tmp.cind2 = this.pallete[0].length - 1; + } + if ([37, 38, 39, 40].indexOf(key) != -1) { + $(obj.el).val(this.pallete[obj.tmp.cind1][obj.tmp.cind2]).change(); + event.preventDefault(); + } + } + } + // list/select/combo + if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($(obj.el).attr('readonly')) return; + var cancel = false; + var selected = $(obj.el).data('selected'); + var focus = $(obj.helpers.focus).find('input'); + if (obj.type == 'list') { + if ([37, 38, 39, 40].indexOf(key) == -1) obj.refresh(); // arrows + } + // apply arrows + switch (key) { + case 27: // escape + if (obj.type == 'list') { + if ($(focus).val() == '') { + $(obj.el).data('selected', {}); + } else { + $(focus).val(''); + } + obj.refresh(); + event.stopPropagation(); // escape in field should not close popup + } + break; + case 37: // left + case 39: // right + // cancel = true; + break; + case 13: // enter + if ($('#w2ui-overlay').length == 0) break; // no action if overlay not open + var item = options.items[options.index]; + var multi = $(obj.helpers.multi).find('input'); + if (obj.type == 'enum') { + if (item != null) { + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + item = eventData.item; // need to reassign because it could be recreated by user + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete item.hidden; + delete obj.tmp.force_open; + selected.push(item); + $(obj.el).change(); + multi.val('').width(20); + obj.refresh(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } else { + // trigger event + item = { id: multi.val(), text: multi.val() } + var eventData = obj.trigger({ phase: 'before', type: 'new', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + item = eventData.item; // need to reassign because it could be recreated by user + // default behavior + if (typeof obj.onNew == 'function') { + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete obj.tmp.force_open; + selected.push(item); + $(obj.el).change(); + multi.val('').width(20); + obj.refresh(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + } else { + if (item) $(obj.el).data('selected', item).val(item.text).change(); + if ($(obj.el).val() == '' && $(obj.el).data('selected')) $(obj.el).removeData('selected').val('').change(); + if (obj.type == 'list') { + focus.val(''); + obj.refresh(); + } + // hide overlay + obj.tmp.force_hide = true; + } + break; + case 8: // delete + if (['enum'].indexOf(obj.type) != -1) { + if ($(obj.helpers.multi).find('input').val() == '' && selected.length > 0) { + var item = selected[selected.length - 1]; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // default behavior + selected.pop(); + $(obj.el).trigger('change'); + obj.refresh(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + } + break; + case 38: // up + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index--; + while (options.index > 0 && options.items[options.index].hidden) options.index--; + if (options.index == 0 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } + cancel = true; + break; + case 40: // down + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : -1; + options.index++; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (options.index == options.items.length-1 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index--; + } + // show overlay if not shown + var input = obj.el; + if (['enum'].indexOf(obj.type) != -1) input = obj.helpers.multi.find('input'); + if ($(input).val() == '' && $('#w2ui-overlay').length == 0) { + obj.tmp.force_open = true; + } else { + cancel = true; + } + break; + } + if (cancel) { + if (options.index < 0) options.index = 0; + if (options.index >= options.items.length) options.index = options.items.length -1; + obj.updateOverlay(); + // cancel event + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + if (obj.type == 'enum') { + var tmp = obj.helpers.multi.find('input').get(0); + tmp.setSelectionRange(tmp.value.length, tmp.value.length); + } else if (obj.type == 'list') { + var tmp = obj.helpers.focus.find('input').get(0); + tmp.setSelectionRange(tmp.value.length, tmp.value.length); + } else { + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + } + }, 0); + return; + } + // expand input + if (obj.type == 'enum') { + var input = obj.helpers.multi.find('input'); + var search = input.val(); + input.width(((search.length + 2) * 8) + 'px'); + } + // run search + if ([16, 17, 18, 20, 37, 39, 91].indexOf(key) == -1) { // no refreah on crtl, shift, left/right arrows, etc + setTimeout(function () { + if (!obj.tmp.force_hide) obj.request(); + obj.search(); + }, 1); + } + } + }, + + keyUp: function (event) { + if (this.type == 'color') { + if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) $(this).prop('maxlength', 6); + } + }, + + clearCache: function () { + var options = this.options; + options.items = []; + this.tmp.xhr_loading = false; + this.tmp.xhr_search = ''; + this.tmp.xhr_total = -1; + this.search(); + }, + + request: function (interval) { + var obj = this; + var options = this.options; + var search = $(obj.el).val() || ''; + // if no url - do nothing + if (!options.url) return; + // -- + if (obj.type == 'enum') { + var tmp = $(obj.helpers.multi).find('input'); + if (tmp.length == 0) search = ''; else search = tmp.val(); + } + if (obj.type == 'list') { + var tmp = $(obj.helpers.focus).find('input'); + if (tmp.length == 0) search = ''; else search = tmp.val(); + } + if (options.minLength != 0 && search.length < options.minLength) { + options.items = []; // need to empty the list + this.updateOverlay(); + return; + } + if (typeof interval == 'undefined') interval = 350; + if (typeof obj.tmp.xhr_search == 'undefined') obj.tmp.xhr_search = ''; + if (typeof obj.tmp.xhr_total == 'undefined') obj.tmp.xhr_total = -1; + // check if need to search + if (options.url && ( + (options.items.length === 0 && obj.tmp.xhr_total !== 0) || + (obj.tmp.xhr_total == options.cacheMax && search.length > obj.tmp.xhr_search.length) || + (search.length >= obj.tmp.xhr_search.length && search.substr(0, obj.tmp.xhr_search.length) != obj.tmp.xhr_search) || + (search.length < obj.tmp.xhr_search.length) + )) { + // empty list + obj.tmp.xhr_loading = true; + obj.search(); + // timeout + clearTimeout(obj.tmp.timeout); + obj.tmp.timeout = setTimeout(function () { + // trigger event + var url = options.url; + var postData = { + search : search, + max : options.cacheMax + }; + $.extend(postData, options.postData); + var eventData = obj.trigger({ phase: 'before', type: 'request', target: obj.el, url: url, postData: postData }); + if (eventData.isCancelled === true) return; + url = eventData.url; + postData = eventData.postData; + // console.log('REMOTE SEARCH:', search); + if (obj.tmp.xhr) obj.tmp.xhr.abort(); + obj.tmp.xhr = $.ajax({ + type : 'POST', + url : url, + data : postData + }) + .done(function (data, status, xhr) { + // trigger event + var eventData2 = obj.trigger({ phase: 'before', type: 'load', target: obj.el, search: postData.search, data: data, xhr: xhr }); + if (eventData2.isCancelled === true) return; + // default behavior + data = eventData2.data; + if (typeof data == 'string') data = JSON.parse(data); + if (data.status != 'success') { + console.log('ERROR: server did not return proper structure. It should return', { status: 'success', items: [{ id: 1, text: 'item' }] }); + return; + } + // remove all extra items if more then needed for cache + if (data.items.length > options.cacheMax) data.items.splice(options.cacheMax, 100000); + // remember stats + obj.tmp.xhr_loading = false; + obj.tmp.xhr_search = search; + obj.tmp.xhr_total = data.items.length; + options.items = data.items; + if (search == '' && data.items.length == 0) obj.tmp.emptySet = true; else obj.tmp.emptySet = false; + obj.search(); + // console.log('-->', 'retrieved:', obj.tmp.xhr_total); + // event after + obj.trigger($.extend(eventData2, { phase: 'after' })); + }) + .error(function (xhr, status, exceptionThrown) { + // trigger event + var errorObj = { status: status, exceptionThrown: exceptionThrown, rawResponseText: xhr.responseText }; + var eventData2 = obj.trigger({ phase: 'before', type: 'error', target: obj.el, search: search, error: errorObj, xhr: xhr }); + if (eventData2.isCancelled === true) return; + // default behavior + console.log('ERROR: server communication failed. The server should return', { status: 'success', items: [{ id: 1, text: 'item' }] }, ', instead the AJAX request produced this: ', errorObj); + // reset stats + obj.clearCache(); + // event after + obj.trigger($.extend(eventData2, { phase: 'after' })); + }); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, interval); + } + }, + + search: function () { + var obj = this; + var options = this.options; + var search = $(obj.el).val(); + var target = obj.el; + var ids = []; + var selected= $(obj.el).data('selected'); + if (obj.type == 'enum') { + target = $(obj.helpers.multi).find('input'); + search = target.val(); + for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } + } + if (obj.type == 'list') { + target = $(obj.helpers.focus).find('input'); + search = target.val(); + for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } + } + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'search', target: target, search: search }); + if (eventData.isCancelled === true) return; + if (obj.tmp.xhr_loading !== true) { + var shown = 0; + for (var i in options.items) { + var item = options.items[i]; + var prefix = ''; + var suffix = ''; + if (['is', 'begins'].indexOf(options.match) != -1) prefix = '^'; + if (['is', 'ends'].indexOf(options.match) != -1) suffix = '$'; + try { + var re = new RegExp(prefix + search + suffix, 'i'); + if (re.test(item.text) || item.text == '...') item.hidden = false; else item.hidden = true; + } catch (e) {} + // do not show selected items + if (obj.type == 'enum' && $.inArray(item.id, ids) != -1) item.hidden = true; + if (item.hidden !== true) shown++; + } + if (obj.type != 'combo') { // don't preselect first for combo + options.index = 0; + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } else { + options.index = -1; + } + if (shown <= 0) options.index = -1; + options.spinner = false; + obj.updateOverlay(); + setTimeout(function () { + var html = $('#w2ui-overlay').html() || ''; + if (options.markSearch && html.indexOf('$.fn.w2menuHandler') != -1) { // do not highlight when no items + $('#w2ui-overlay').w2marker(search); + } + }, 1); + } else { + options.items.splice(0, options.cacheMax); + options.spinner = true; + obj.updateOverlay(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + updateOverlay: function () { + var obj = this; + var options = this.options; + // color + if (this.type == 'color') { + if ($(obj.el).attr('readonly')) return; + if ($('#w2ui-overlay').length == 0) { + $(obj.el).w2overlay(obj.getColorHTML()); + } else { + $('#w2ui-overlay').html(obj.getColorHTML()); + } + // bind events + $('#w2ui-overlay .color') + .on('mousedown', function (event) { + var color = $(event.originalEvent.target).attr('name'); + var index = $(event.originalEvent.target).attr('index').split(':'); + obj.tmp.cind1 = index[0]; + obj.tmp.cind2 = index[1]; + $(obj.el).val(color).change(); + $(this).html('•'); + }) + .on('mouseup', function () { + setTimeout(function () { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); + }, 10); + }); + } + // date + if (this.type == 'date') { + if ($(obj.el).attr('readonly')) return; + if ($('#w2ui-overlay').length == 0) { + $(obj.el).w2overlay('
    ', { + css: { "background-color": "#f5f5f5" } + }); + } + var month, year; + var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true); + if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } + (function refreshCalendar(month, year) { + $('#w2ui-overlay > div > div').html(obj.getMonthHTML(month, year)); + $('#w2ui-overlay .w2ui-calendar-title') + .on('mousedown', function () { + if ($(this).next().hasClass('w2ui-calendar-jump')) { + $(this).next().remove(); + } else { + var selYear, selMonth; + $(this).after('
    '); + $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); + setTimeout(function () { + $('#w2ui-overlay .w2ui-calendar-jump') + .find('.w2ui-jump-month, .w2ui-jump-year') + .on('click', function () { + if ($(this).hasClass('w2ui-jump-month')) { + $(this).parent().find('.w2ui-jump-month').removeClass('selected'); + $(this).addClass('selected'); + selMonth = $(this).attr('name'); + } + if ($(this).hasClass('w2ui-jump-year')) { + $(this).parent().find('.w2ui-jump-year').removeClass('selected'); + $(this).addClass('selected'); + selYear = $(this).attr('name'); + } + if (selYear != null && selMonth != null) { + $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); + setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); + } + }); + $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); + }, 1); + } + }); + $('#w2ui-overlay .w2ui-date') + .on('mousedown', function () { + var day = $(this).attr('date'); + $(obj.el).val(day).change(); + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + }) + .on('mouseup', function () { + setTimeout(function () { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); + }, 10); + }); + $('#w2ui-overlay .previous').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) - 1; + refreshCalendar(tmp[0], tmp[1]); + }); + $('#w2ui-overlay .next').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) + 1; + refreshCalendar(tmp[0], tmp[1]); + }); + }) (month, year); + } + // date + if (this.type == 'time') { + if ($(obj.el).attr('readonly')) return; + if ($('#w2ui-overlay').length == 0) { + $(obj.el).w2overlay('
    ', { + css: { "background-color": "#fff" } + }); + } + var h24 = (this.options.format == 'h24' ? true : false); + $('#w2ui-overlay > div').html(obj.getHourHTML()); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function (event) { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + var hour = $(this).attr('hour'); + $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }) + .on('mouseup', function () { + var hour = $(this).attr('hour'); + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); + $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function () { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + var min = $(this).attr('min'); + $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }) + .on('mouseup', function () { + setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); + }); + }); + } + // list + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + var el = this.el; + var input = this.el; + if (this.type == 'enum') { + el = $(this.helpers.multi); + input = $(el).find('input'); + } + if (this.type == 'list') { + input = $(this.helpers.focus).find('input'); + } + if ($(input).is(':focus')) { + if (options.openOnFocus === false && $(input).val() == '' && obj.tmp.force_open !== true) { + $().w2overlay(); + return; + } + if (obj.tmp.force_hide) { + $().w2overlay(); + setTimeout(function () { + delete obj.tmp.force_hide; + }, 1); + return; + } + if ($(input).val() != '') delete obj.tmp.force_open; + if ($('#w2ui-overlay').length == 0) options.index = 0; + var msgNoItems = w2utils.lang('No matches'); + if (options.url != null && $(input).val().length < options.minLength && obj.tmp.emptySet !== true) msgNoItems = options.minLength + ' ' + w2utils.lang('letters or more...'); + if (options.url != null && $(input).val() == '' && obj.tmp.emptySet !== true) msgNoItems = w2utils.lang('Type to search....'); + $(el).w2menu('refresh', $.extend(true, {}, options, { + search : false, + render : options.renderDrop, + maxHeight : options.maxDropHeight, + msgNoItems : msgNoItems, + // selected with mouse + onSelect: function (event) { + if (obj.type == 'enum') { + var selected = $(obj.el).data('selected'); + if (event.item) { + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: event.item }); + if (eventData.isCancelled === true) return; + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete event.item.hidden; + selected.push(event.item); + $(obj.el).data('selected', selected).change(); + $(obj.helpers.multi).find('input').val('').width(20); + obj.refresh(); + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + } else { + $(obj.el).data('selected', event.item).val(event.item.text).change(); + if (obj.helpers.focus) { + obj.helpers.focus.find('input').val(''); + obj.refresh(); + } + } + } + })); + } + } + }, + + inRange: function (str) { + var inRange = false; + if (this.type == 'date') { + var dt = w2utils.isDate(str, this.options.format, true); + if (dt) { + // enable range + if (this.options.start || this.options.end) { + var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); + var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); + var start = w2utils.isDate(st, this.options.format, true); + var end = w2utils.isDate(en, this.options.format, true); + var current = new Date(dt); + if (!start) start = current; + if (!end) end = current; + if (current >= start && current <= end) inRange = true; + } else { + inRange = true; + } + // block predefined dates + if (this.options.blocked && $.inArray(str, this.options.blocked) != -1) inRange = false; + } + } + if (this.type == 'time') { + if (this.options.start || this.options.end) { + var tm = this.toMin(str); + var tm1 = this.toMin(this.options.start); + var tm2 = this.toMin(this.options.end); + if (!tm1) tm1 = tm; + if (!tm2) tm2 = tm; + if (tm >= tm1 && tm <= tm2) inRange = true; + } else { + inRange = true; + } + } + return inRange; + }, + + /* + * INTERNAL FUNCTIONS + */ + + checkType: function (ch, loose) { + var obj = this; + switch (obj.type) { + case 'int': + if (loose && ['-'].indexOf(ch) != -1) return true; + return w2utils.isInt(ch.replace(obj.options.numberRE, '')); + case 'percent': + ch = ch.replace(/%/g, ''); + case 'float': + if (loose && ['-','.'].indexOf(ch) != -1) return true; + return w2utils.isFloat(ch.replace(obj.options.numberRE, '')); + case 'money': + case 'currency': + if (loose && ['-', '.', obj.options.groupSymbol, obj.options.currencyPrefix, obj.options.currencySuffix].indexOf(ch) != -1) return true; + return w2utils.isFloat(ch.replace(obj.options.moneyRE, '')); + case 'hex': + case 'color': + return w2utils.isHex(ch); + case 'alphanumeric': + return w2utils.isAlphaNumeric(ch); + } + return true; + }, + + addPrefix: function () { + var obj = this; + setTimeout(function () { + if (obj.type === 'clear') return; + var helper; + var tmp = $(obj.el).data('tmp') || {}; + if (tmp['old-padding-left']) $(obj.el).css('padding-left', tmp['old-padding-left']); + tmp['old-padding-left'] = $(obj.el).css('padding-left'); + $(obj.el).data('tmp', tmp); + if (obj.options.prefix !== '') { + // remove if already displaed + if (obj.helpers.prefix) $(obj.helpers.prefix).remove(); + // add fresh + $(obj.el).before( + '
    '+ + obj.options.prefix + + '
    ' + ); + helper = $(obj.el).prev(); + helper + .css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'padding-top' : $(obj.el).css('padding-top'), + 'padding-bottom' : $(obj.el).css('padding-bottom'), + 'padding-left' : $(obj.el).css('padding-left'), + 'padding-right' : 0, + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', + 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px', + 'margin-left' : $(obj.el).css('margin-left'), + 'margin-right' : 0 + }) + .on('click', function (event) { + if (obj.options.icon && typeof obj.onIconClick == 'function') { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'iconClick', target: obj.el, el: $(this).find('span.w2ui-icon')[0] }); + if (eventData.isCancelled === true) return; + + // intentionally empty + + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } else { + if (obj.type == 'list') { + $(obj.helpers.focus).find('input').focus(); + } else { + $(obj.el).focus(); + } + } + }); + $(obj.el).css('padding-left', (helper.width() + parseInt($(obj.el).css('padding-left'), 10)) + 'px'); + // remember helper + obj.helpers.prefix = helper; + } + }, 1); + }, + + addSuffix: function () { + var obj = this; + var helper, pr; + setTimeout(function () { + if (obj.type === 'clear') return; + var tmp = $(obj.el).data('tmp') || {}; + if (tmp['old-padding-right']) $(obj.el).css('padding-right', tmp['old-padding-right']); + tmp['old-padding-right'] = $(obj.el).css('padding-right'); + $(obj.el).data('tmp', tmp); + pr = parseInt($(obj.el).css('padding-right'), 10); + if (obj.options.arrows) { + // remove if already displaed + if (obj.helpers.arrows) $(obj.helpers.arrows).remove(); + // add fresh + $(obj.el).after( + '
     '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '); + var height = w2utils.getSize(obj.el, 'height'); + helper = $(obj.el).next(); + helper.css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'height' : ($(obj.el).height() + parseInt($(obj.el).css('padding-top'), 10) + parseInt($(obj.el).css('padding-bottom'), 10) ) + 'px', + 'padding' : 0, + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', + 'margin-bottom' : 0, + 'border-left' : '1px solid silver' + }) + .css('margin-left', '-'+ (helper.width() + parseInt($(obj.el).css('margin-right'), 10) + 12) + 'px') + .on('mousedown', function (event) { + $('body').on('mouseup', tmp); + $('body').data('_field_update_timer', setTimeout(update, 700)); + update(false); + // timer function + function tmp() { + clearTimeout($('body').data('_field_update_timer')); + $('body').off('mouseup', tmp); + } + // update function + function update(notimer) { + $(obj.el).focus(); + obj.keyDown($.Event("keydown"), { + keyCode : ($(event.target).attr('type') == 'up' ? 38 : 40) + }); + if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60)); + } + }); + pr += helper.width() + 12; + $(obj.el).css('padding-right', pr + 'px'); + // remember helper + obj.helpers.arrows = helper; + } + if (obj.options.suffix !== '') { + // remove if already displaed + if (obj.helpers.suffix) $(obj.helpers.suffix).remove(); + // add fresh + $(obj.el).after( + '
    '+ + obj.options.suffix + + '
    '); + helper = $(obj.el).next(); + helper + .css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'padding-top' : $(obj.el).css('padding-top'), + 'padding-bottom' : $(obj.el).css('padding-bottom'), + 'padding-left' : '3px', + 'padding-right' : $(obj.el).css('padding-right'), + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', + 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px' + }) + .on('click', function (event) { + if (obj.type == 'list') { + $(obj.helpers.focus).find('input').focus(); + } else { + $(obj.el).focus(); + } + }); + + helper.css('margin-left', '-'+ (w2utils.getSize(helper, 'width') + parseInt($(obj.el).css('margin-right'), 10) + 2) + 'px'); + pr += helper.width() + 3; + $(obj.el).css('padding-right', pr + 'px'); + // remember helper + obj.helpers.suffix = helper; + } + }, 1); + }, + + addFocus: function () { + var obj = this; + var options = this.options; + var width = 0; // 11 - show search icon, 0 do not show + if (options.icon) width = 11; + // clean up & init + $(obj.helpers.focus).remove(); + // build helper + var html = + '
    '+ + ' '+ + ' '+ + '
    '; + $(obj.el).attr('tabindex', -1).before(html); + var helper = $(obj.el).prev(); + obj.helpers.focus = helper; + helper.css({ + width : $(obj.el).width(), + "margin-top" : $(obj.el).css('margin-top'), + "margin-left" : (parseInt($(obj.el).css('margin-left')) + parseInt($(obj.el).css('padding-left'))) + 'px', + "margin-bottom" : $(obj.el).css('margin-bottom'), + "margin-right" : $(obj.el).css('margin-right'), + }) + .find('input') + .css({ + cursor : 'default', + width : '100%', + outline : 'none', + opacity : 1, + margin : 0, + border : '1px solid transparent', + padding : $(obj.el).css('padding-top'), + "padding-left" : 0, + "margin-left" : width + (width > 0 ? 6 : 0), + "background-color" : 'transparent' + }); + // INPUT events + helper.find('input') + .on('click', function (event) { + if ($('#w2ui-overlay').length == 0) obj.focus(event); + event.stopPropagation(); + }) + .on('focus', function (event) { + $(obj.el).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); + $(this).val(''); + $(obj.el).triggerHandler('focus'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('blur', function (event) { + $(obj.el).css('outline', 'none'); + $(this).val(''); + obj.refresh(); + $(obj.el).triggerHandler('blur'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('keyup', function (event) { obj.keyUp(event) }) + .on('keydown', function (event) { obj.keyDown(event) }) + .on('keypress', function (event) { obj.keyPress(event); }); + // MAIN div + helper.on('click', function (event) { $(this).find('input').focus(); }); + obj.refresh(); + }, + + addMulti: function () { + var obj = this; + var options = this.options; + // clean up & init + $(obj.helpers.multi).remove(); + // build helper + var html = ''; + var margin = + 'margin-top : 0px; ' + + 'margin-bottom : 0px; ' + + 'margin-left : ' + $(obj.el).css('margin-left') + '; ' + + 'margin-right : ' + $(obj.el).css('margin-right') + '; '+ + 'width : ' + (w2utils.getSize(obj.el, 'width') + - parseInt($(obj.el).css('margin-left'), 10) + - parseInt($(obj.el).css('margin-right'), 10)) + + 'px;'; + if (obj.type == 'enum') { + html = '
    '+ + '
    '+ + '
      '+ + '
    • '+ + ' '+ + '
    • ' + '
    '+ + '
    '+ + '
    '; + } + if (obj.type == 'file') { + html = '
    '+ + '
    '+ + '
    '+ + ' ' + '
    '+ + '
    '; + } + $(obj.el) + .before(html) + .css({ + 'background-color' : 'transparent', + 'border-color' : 'transparent' + }); + + var div = $(obj.el).prev(); + obj.helpers.multi = div; + if (obj.type == 'enum') { + $(obj.el).attr('tabindex', -1); + // INPUT events + div.find('input') + .on('click', function (event) { + if ($('#w2ui-overlay').length == 0) obj.focus(event); + $(obj.el).triggerHandler('click'); + }) + .on('focus', function (event) { + $(div).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); + $(obj.el).triggerHandler('focus'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('blur', function (event) { + $(div).css('outline', 'none'); + $(obj.el).triggerHandler('blur'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('keyup', function (event) { obj.keyUp(event) }) + .on('keydown', function (event) { obj.keyDown(event) }) + .on('keypress', function (event) { div.find('.w2ui-enum-placeholder').remove(); obj.keyPress(event); }); + // MAIN div + div.on('click', function (event) { $(this).find('input').focus(); }); + } + if (obj.type == 'file') { + $(obj.el).css('outline', 'none'); + div.on('click', function (event) { + $(obj.el).focus(); + if ($(obj.el).attr('readonly')) return; + obj.blur(event); + div.find('input').click(); + }) + .on('dragenter', function (event) { + if ($(obj.el).attr('readonly')) return; + $(div).addClass('w2ui-file-dragover'); + }) + .on('dragleave', function (event) { + if ($(obj.el).attr('readonly')) return; + var tmp = $(event.target).parents('.w2ui-field-helper'); + if (tmp.length == 0) $(div).removeClass('w2ui-file-dragover'); + }) + .on('drop', function (event) { + if ($(obj.el).attr('readonly')) return; + $(div).removeClass('w2ui-file-dragover'); + var files = event.originalEvent.dataTransfer.files; + for (var i=0, l=files.length; i options.maxFileSize) { + err = 'Maximum file size is '+ w2utils.size(options.maxFileSize); + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { + err = 'Maximum total size is '+ w2utils.size(options.maxSize); + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + if (options.max !== 0 && cnt >= options.max) { + err = 'Maximum number of files is '+ options.max; + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + selected.push(newItem); + // read file as base64 + if (typeof FileReader !== "undefined") { + var reader = new FileReader(); + // need a closure + reader.onload = (function () { + return function (event) { + var fl = event.target.result; + var ind = fl.indexOf(','); + newItem.content = fl.substr(ind+1); + obj.refresh(); + $(obj.el).trigger('change'); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }; + })(); + reader.readAsDataURL(file); + } else { + obj.refresh(); + $(obj.el).trigger('change'); + } + }, + + normMenu: function (menu) { + if ($.isArray(menu)) { + for (var m = 0; m < menu.length; m++) { + if (typeof menu[m] == 'string') { + menu[m] = { id: menu[m], text: menu[m] }; + } else { + if (typeof menu[m].text != 'undefined' && typeof menu[m].id == 'undefined') menu[m].id = menu[m].text; + if (typeof menu[m].text == 'undefined' && typeof menu[m].id != 'undefined') menu[m].text = menu[m].id; + if (typeof menu[m].caption != 'undefined') menu[m].text = menu[m].caption; + } + } + return menu; + } else if (typeof menu == 'object') { + var tmp = [] + for (var m in menu) tmp.push({ id: m, text: menu[m] }); + return tmp; + } + }, + + getColorHTML: function () { + var html = '
    '+ + ''; + for (var i = 0; i < 8; i++) { + html += ''; + for (var j = 0; j < 8; j++) { + html += ''; + } + html += ''; + if (i < 2) html += ''; + } + html += '
    '+ + '
    '+ + ' '+ ($(this.el).val() == this.pallete[i][j] ? '•' : ' ')+ + '
    '+ + '
    '; + return html; + }, + + getMonthHTML: function (month, year) { + var td = new Date(); + var months = w2utils.settings.fullmonths; + var days = w2utils.settings.fulldays; + var daysCount = ['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31']; + var today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate(); + // normalize date + year = w2utils.isInt(year) ? parseInt(year) : td.getFullYear(); + month = w2utils.isInt(month) ? parseInt(month) : td.getMonth() + 1; + if (month > 12) { month -= 12; year++; } + if (month < 1 || month === 0) { month += 12; year--; } + if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; } + this.options.current = month + '/' + year; + + // start with the required date + td = new Date(year, month-1, 1); + var weekDay = td.getDay(); + var tabDays = w2utils.settings.shortdays; + var dayTitle = ''; + for ( var i = 0, len = tabDays.length; i < len; i++) { + dayTitle += '' + tabDays[i] + ''; + } + var html = + '
    '+ + ' '+ + ' '+ + months[month-1] +', '+ year + + '
    '+ + ''+ + ' ' + dayTitle + ''+ + ' '; + + var day = 1; + for (var ci=1; ci<43; ci++) { + if (weekDay === 0 && ci == 1) { + for (var ti=0; ti<6; ti++) html += ''; + ci += 6; + } else { + if (ci < weekDay || day > daysCount[month-1]) { + html += ''; + if ((ci) % 7 === 0) html += ''; + continue; + } + } + var dt = year + '/' + month + '/' + day; + + var className = ''; + if (ci % 7 == 6) className = ' w2ui-saturday'; + if (ci % 7 === 0) className = ' w2ui-sunday'; + if (dt == today) className += ' w2ui-today'; + + var dspDay = day; + var col = ''; + var bgcol = ''; + var tmp_dt = w2utils.formatDate(dt, this.options.format); + if (this.options.colored && this.options.colored[tmp_dt] !== undefined) { // if there is predefined colors for dates + tmp = this.options.colored[tmp_dt].split(':'); + bgcol = 'background-color: ' + tmp[0] + ';'; + col = 'color: ' + tmp[1] + ';'; + } + html += ''; + if (ci % 7 === 0 || (weekDay === 0 && ci == 1)) html += ''; + day++; + } + html += '
      
    '+ + dspDay + + '
    '; + return html; + }, + + getYearHTML: function () { + var months = w2utils.settings.shortmonths; + var mhtml = ''; + var yhtml = ''; + for (var m in months) { + mhtml += '
    '+ months[m] + '
    '; + } + for (var y = 1950; y <= 2020; y++) { + yhtml += '
    '+ y + '
    ' + } + return '
    '+ mhtml +'
    '+ yhtml +'
    '; + }, + + getHourHTML: function () { + var tmp = []; + var h24 = (this.options.format == 'h24' ? true : false); + for (var a=0; a<24; a++) { + var time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : ''); + if (a == 12 && !h24) time = '12:00 pm'; + if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = ''; + var tm1 = this.fromMin(this.toMin(time)); + var tm2 = this.fromMin(this.toMin(time) + 59); + tmp[Math.floor(a/8)] += '
    '+ time +'
    '; + } + var html = + '
    '+ + ' ' + + ' ' + + ' ' + + '
    '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
    '; + return html; + }, + + getMinHTML: function (hour) { + if (typeof hour == 'undefined') hour = 0; + var h24 = (this.options.format == 'h24' ? true : false); + var tmp = []; + for (var a=0; a<60; a+=5) { + var time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : ''); + var ind = a < 20 ? 0 : (a < 40 ? 1 : 2); + if (!tmp[ind]) tmp[ind] = ''; + tmp[ind] += '
    '+ time +'
    '; + } + var html = + '
    '+ + ' ' + + ' ' + + ' ' + + '
    '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
    '; + return html; + }, + + toMin: function (str) { + if (typeof str != 'string') return null; + var tmp = str.split(':'); + if (tmp.length == 2) { + tmp[0] = parseInt(tmp[0]); + tmp[1] = parseInt(tmp[1]); + if (str.indexOf('pm') != -1 && tmp[0] != 12) tmp[0] += 12; + } else { + return null; + } + return tmp[0] * 60 + tmp[1]; + }, + + fromMin: function (time) { + var ret = ''; + if (time >= 24 * 60) time = time % (24 * 60); + if (time < 0) time = 24 * 60 + time; + var hour = Math.floor(time/60); + var min = ((time % 60) < 10 ? '0' : '') + (time % 60); + if (this.options.format.indexOf('h24') != -1) { + ret = hour + ':' + min; + } else { + ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am'); + } + return ret; + } + } + + $.extend(w2field.prototype, w2utils.event); + w2obj.field = w2field; }) (jQuery); diff --git a/dist/w2ui-fields.min.js b/dist/w2ui-fields.min.js index 86608e7ac..63c71255e 100644 --- a/dist/w2ui-fields.min.js +++ b/dist/w2ui-fields.min.js @@ -1,4 +1,4 @@ /* w2ui-fields.js 1.4.x (nightly), part of w2ui (c) http://w2ui.com, vitmalina@gmail.com */ -var w2ui=w2ui||{},w2obj=w2obj||{},w2utils=function(){function a(a){var b=/^[-+]?[0-9]+$/;return b.test(a)}function b(a){return("number"==typeof a||"string"==typeof a&&""!==a)&&!isNaN(Number(a))}function c(a){var b=w2utils.settings,c=new RegExp("^"+(b.currencyPrefix?"\\"+b.currencyPrefix+"?":"")+"[-+]?[0-9]*[.]?[0-9]+"+(b.currencySuffix?"\\"+b.currencySuffix+"?":"")+"$","i");return"string"==typeof a&&(a=a.replace(new RegExp(b.groupSymbol,"g"),"")),"object"==typeof a||""===a?!1:c.test(a)}function d(a){var b=/^[a-fA-F0-9]+$/;return b.test(a)}function e(a){var b=/^[a-zA-Z0-9_-]+$/;return b.test(a)}function f(a){var b=/^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;return b.test(a)}function g(b,c,d){if(!b)return!1;var e,f,g,h="Invalid Date";if(null==c&&(c=w2utils.settings.date_format),"function"==typeof b.getUTCFullYear&&"function"==typeof b.getUTCMonth&&"function"==typeof b.getUTCDate)g=b.getUTCFullYear(),e=b.getUTCMonth(),f=b.getUTCDate();else if("function"==typeof b.getFullYear&&"function"==typeof b.getMonth&&"function"==typeof b.getDate)g=b.getFullYear(),e=b.getMonth(),f=b.getDate();else{if(b=String(b),RegExp("mon","ig").test(c)){c=c.replace(/month/gi,"m").replace(/mon/gi,"m").replace(/dd/gi,"d").replace(/[, ]/gi,"/").replace(/\/\//g,"/").toLowerCase(),b=b.replace(/[, ]/gi,"/").replace(/\/\//g,"/").toLowerCase();for(var i=0,j=w2utils.settings.fullmonths.length;j>i;i++){var k=w2utils.settings.fullmonths[i];b=b.replace(RegExp(k,"ig"),parseInt(i)+1).replace(RegExp(k.substr(0,3),"ig"),parseInt(i)+1)}}var l=b.replace(/-/g,"/").replace(/\./g,"/").toLowerCase().split("/"),m=c.replace(/-/g,"/").replace(/\./g,"/").toLowerCase();"mm/dd/yyyy"===m&&(e=l[0],f=l[1],g=l[2]),"m/d/yyyy"===m&&(e=l[0],f=l[1],g=l[2]),"dd/mm/yyyy"===m&&(e=l[1],f=l[0],g=l[2]),"d/m/yyyy"===m&&(e=l[1],f=l[0],g=l[2]),"yyyy/dd/mm"===m&&(e=l[2],f=l[1],g=l[0]),"yyyy/d/m"===m&&(e=l[2],f=l[1],g=l[0]),"yyyy/mm/dd"===m&&(e=l[1],f=l[2],g=l[0]),"yyyy/m/d"===m&&(e=l[1],f=l[2],g=l[0]),"mm/dd/yy"===m&&(e=l[0],f=l[1],g=l[2]),"m/d/yy"===m&&(e=l[0],f=l[1],g=parseInt(l[2])+1900),"dd/mm/yy"===m&&(e=l[1],f=l[0],g=parseInt(l[2])+1900),"d/m/yy"===m&&(e=l[1],f=l[0],g=parseInt(l[2])+1900),"yy/dd/mm"===m&&(e=l[2],f=l[1],g=parseInt(l[0])+1900),"yy/d/m"===m&&(e=l[2],f=l[1],g=parseInt(l[0])+1900),"yy/mm/dd"===m&&(e=l[1],f=l[2],g=parseInt(l[0])+1900),"yy/m/d"===m&&(e=l[1],f=l[2],g=parseInt(l[0])+1900)}return a(g)&&a(e)&&a(f)?(g=+g,e=+e,f=+f,h=new Date(g,e-1,f),null==e?!1:"Invalid Date"===h?!1:h.getMonth()+1!==e||h.getDate()!==f||h.getFullYear()!==g?!1:d===!0?h:!0):!1}function h(a,b){if(null==a)return!1;var c,d;a=String(a),a=a.toUpperCase(),d=a.indexOf("PM")>=0;var e=d||a.indexOf("AM")>=0;c=e?12:24,a=a.replace("AM","").replace("PM",""),a=$.trim(a);var f=a.split(":"),g=parseInt(f[0]||0),h=parseInt(f[1]||0);return e&&1===f.length||2===f.length?""===f[0]||0>g||g>c||!this.isInt(f[0])||f[0].length>2?!1:2===f.length&&(""===f[1]||0>h||h>59||!this.isInt(f[1])||2!==f[1].length)?!1:e||c!==g||0===h?e&&1===f.length&&0===g?!1:b===!0?(d&&(g+=12),{hours:g,minutes:h}):!0:!1:!1}function i(a){if(""===a||null==a)return"";var b=new Date(a);if(w2utils.isInt(a)&&(b=new Date(Number(a))),"Invalid Date"===b)return"";var c=new Date,d=(c.getTime()-b.getTime())/1e3,e="",f="";return 0>d?(e='future',f=""):60>d?(e=Math.floor(d),f="sec",0>d&&(e=0,f="sec")):3600>d?(e=Math.floor(d/60),f="min"):86400>d?(e=Math.floor(d/60/60),f="hour"):2592e3>d?(e=Math.floor(d/24/60/60),f="day"):31104e3>d?(e=Math.floor(d/30/24/60/60*10)/10,f="month"):d>=31104e3&&(e=Math.floor(d/12/30/24/60/60*10)/10,f="year"),e+" "+f+(e>1?"s":"")}function j(a){if(""===a||null==a)return"";var b=new Date(a);if(w2utils.isInt(a)&&(b=new Date(Number(a))),"Invalid Date"===b)return"";var c=w2utils.settings.shortmonths,d=new Date,e=new Date;e.setTime(e.getTime()-864e5);var f=c[b.getMonth()]+" "+b.getDate()+", "+b.getFullYear(),g=c[d.getMonth()]+" "+d.getDate()+", "+d.getFullYear(),h=c[e.getMonth()]+" "+e.getDate()+", "+e.getFullYear(),i=b.getHours()-(b.getHours()>12?12:0)+":"+(b.getMinutes()<10?"0":"")+b.getMinutes()+" "+(b.getHours()>=12?"pm":"am"),j=b.getHours()-(b.getHours()>12?12:0)+":"+(b.getMinutes()<10?"0":"")+b.getMinutes()+":"+(b.getSeconds()<10?"0":"")+b.getSeconds()+" "+(b.getHours()>=12?"pm":"am"),k=f;return f===g&&(k=i),f===h&&(k=w2utils.lang("Yesterday")),''+k+""}function k(a){if(!w2utils.isFloat(a)||""===a)return"";if(a=parseFloat(a),0===a)return 0;var b=["Bt","KB","MB","GB","TB"],c=parseInt(Math.floor(Math.log(a)/Math.log(1024)));return(Math.floor(a/Math.pow(1024,c)*10)/10).toFixed(0===c?0:1)+" "+b[c]}function l(a,b){var c="";return null==b&&(b=w2utils.settings.groupSymbol||","),(w2utils.isFloat(a)||w2utils.isInt(a)||w2utils.isMoney(a))&&(D=String(a).split("."),c=String(D[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1"+b),null!=D[1]&&(c+="."+D[1])),c}function m(a,b){w2utils.settings.shortmonths,w2utils.settings.fullmonths;if(b||(b=this.settings.date_format),""===a||null==a)return"";var c=new Date(a);if(w2utils.isInt(a)&&(c=new Date(Number(a))),"Invalid Date"===c)return"";var d=c.getFullYear(),e=c.getMonth(),f=c.getDate();return b.toLowerCase().replace("month",w2utils.settings.fullmonths[e]).replace("mon",w2utils.settings.shortmonths[e]).replace(/yyyy/g,d).replace(/yyy/g,d).replace(/yy/g,d>2e3?100+parseInt(String(d).substr(2)):String(d).substr(2)).replace(/(^|[^a-z$])y/g,"$1"+d).replace(/mm/g,(10>e+1?"0":"")+(e+1)).replace(/dd/g,(10>f?"0":"")+f).replace(/(^|[^a-z$])m/g,"$1"+(e+1)).replace(/(^|[^a-z$])d/g,"$1"+f)}function n(a,b){w2utils.settings.shortmonths,w2utils.settings.fullmonths;if(b||(b="h12"===this.settings.time_format?"hh:mi pm":"h24:mi"),""===a||null==a)return"";var c=new Date(a);if(w2utils.isInt(a)&&(c=new Date(Number(a))),w2utils.isTime(a)){var d=w2utils.isTime(a,!0);c=new Date,c.setHours(d.hours),c.setMinutes(d.minutes)}if("Invalid Date"===c)return"";var e="am",f=c.getHours(),g=c.getHours(),h=c.getMinutes(),i=c.getSeconds();return 10>h&&(h="0"+h),10>i&&(i="0"+i),(-1!==b.indexOf("am")||-1!==b.indexOf("pm"))&&(f>=12&&(e="pm"),f>12&&(f-=12)),b.toLowerCase().replace("am",e).replace("pm",e).replace("hh",f).replace("h24",g).replace("mm",h).replace("mi",h).replace("ss",i).replace(/(^|[^a-z$])h/g,"$1"+f).replace(/(^|[^a-z$])m/g,"$1"+h).replace(/(^|[^a-z$])s/g,"$1"+i)}function o(a,b){var c;return c="string"!=typeof b?[this.settings.date_format,this.settings.time_format]:b.split("|"),this.formatDate(a,c[0])+" "+this.formatTime(a,c[1])}function p(a){if(null===a)return a;switch(typeof a){case"number":break;case"string":a=$.trim(String(a).replace(/(<([^>]+)>)/gi,""));break;case"object":for(var b in a)a[b]=this.stripTags(a[b])}return a}function q(a){if(null===a)return a;switch(typeof a){case"number":break;case"string":a=String(a).replace(/&/g,"&").replace(/>/g,">").replace(/\|\/? {}\\])/g,"\\$1")}function s(a){function b(a){for(var a=String(a).replace(/\r\n/g,"\n"),b="",c=0;cd?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b}var c,d,e,f,g,h,i,j="",k=0,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";for(a=b(a);k>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,isNaN(d)?h=i=64:isNaN(e)&&(i=64),j=j+l.charAt(f)+l.charAt(g)+l.charAt(h)+l.charAt(i);return j}function t(a){function b(a){for(var b,c,d="",e=0,f=0;ef?(d+=String.fromCharCode(f),e++):f>191&&224>f?(b=a.charCodeAt(e+1),d+=String.fromCharCode((31&f)<<6|63&b),e+=2):(b=a.charCodeAt(e+1),c=a.charCodeAt(e+2),d+=String.fromCharCode((15&f)<<12|(63&b)<<6|63&c),e+=3);return d}var c,d,e,f,g,h,i,j="",k=0,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(c),64!==h&&(j+=String.fromCharCode(d)),64!==i&&(j+=String.fromCharCode(e));return j=b(j)}function u(a,b,c,d){function e(a,b,c){var d=!!window.webkitURL;return d||"undefined"==typeof c||(b=c),";"+a+": "+b+"; -webkit-"+a+": "+b+"; -moz-"+a+": "+b+"; -ms-"+a+": "+b+"; -o-"+a+": "+b+";"}var f=$(a).width(),g=$(a).height(),h=.5;if(!a||!b)return void console.log("ERROR: Cannot do transition when one of the divs is null");switch(a.parentNode.style.cssText+=e("perspective","700px")+"; overflow: hidden;",a.style.cssText+="; position: absolute; z-index: 1019; "+e("backface-visibility","hidden"),b.style.cssText+="; position: absolute; z-index: 1020; "+e("backface-visibility","hidden"),c){case"slide-left":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d("+f+"px, 0, 0)","translate("+f+"px, 0)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+";"+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),a.style.cssText+=e("transition",h+"s")+";"+e("transform","translate3d(-"+f+"px, 0, 0)","translate(-"+f+"px, 0)")},1);break;case"slide-right":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(-"+f+"px, 0, 0)","translate(-"+f+"px, 0)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0px, 0, 0)","translate(0px, 0)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d("+f+"px, 0, 0)","translate("+f+"px, 0)")},1);break;case"slide-down":a.style.cssText+="overflow: hidden; z-index: 1; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; z-index: 0; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, "+g+"px, 0)","translate(0, "+g+"px)")},1);break;case"slide-up":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, "+g+"px, 0)","translate(0, "+g+"px)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")},1);break;case"flip-left":a.style.cssText+="overflow: hidden; "+e("transform","rotateY(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateY(-180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(180deg)")},1);break;case"flip-right":a.style.cssText+="overflow: hidden; "+e("transform","rotateY(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateY(180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(-180deg)")},1);break;case"flip-down":a.style.cssText+="overflow: hidden; "+e("transform","rotateX(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateX(180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(-180deg)")},1);break;case"flip-up":a.style.cssText+="overflow: hidden; "+e("transform","rotateX(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateX(-180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(180deg)")},1);break;case"pop-in":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; "+e("transform","scale(.8)")+"; opacity: 0;",$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","scale(1)")+"; opacity: 1;",a.style.cssText+=e("transition",h+"s")+";"},1);break;case"pop-out":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; "+e("transform","scale(1)")+"; opacity: 1;",b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; opacity: 0;",$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; opacity: 1;",a.style.cssText+=e("transition",h+"s")+"; "+e("transform","scale(1.7)")+"; opacity: 0;"},1);break;default:a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; opacity: 0;",$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; opacity: 1;",a.style.cssText+=e("transition",h+"s")},1)}setTimeout(function(){"slide-down"===c&&($(a).css("z-index","1019"),$(b).css("z-index","1020")),b&&$(b).css({opacity:"1","-webkit-transition":"","-moz-transition":"","-ms-transition":"","-o-transition":"","-webkit-transform":"","-moz-transform":"","-ms-transform":"","-o-transform":"","-webkit-backface-visibility":"","-moz-backface-visibility":"","-ms-backface-visibility":"","-o-backface-visibility":""}),a&&($(a).css({opacity:"1","-webkit-transition":"","-moz-transition":"","-ms-transition":"","-o-transition":"","-webkit-transform":"","-moz-transform":"","-ms-transform":"","-o-transform":"","-webkit-backface-visibility":"","-moz-backface-visibility":"","-ms-backface-visibility":"","-o-backface-visibility":""}),a.parentNode&&$(a.parentNode).css({"-webkit-perspective":"","-moz-perspective":"","-ms-perspective":"","-o-perspective":""})),"function"==typeof d&&d()},1e3*h)}function v(a,b,c){var d={};"object"==typeof b?d=b:(d.msg=b,d.spinner=c),d.msg||0===d.msg||(d.msg=""),w2utils.unlock(a),$(a).prepend('
    ');var e=$(a).find(".w2ui-lock"),f=$(a).find(".w2ui-lock-msg");d.msg||f.css({"background-color":"transparent",border:"0px"}),d.spinner===!0&&(d.msg='
    "+d.msg),null!=d.opacity&&e.css("opacity",d.opacity),"function"==typeof e.fadeIn?(e.fadeIn(200),f.html(d.msg).fadeIn(200)):(e.show(),f.html(d.msg).show(0)),$().w2tag()}function w(a){$(a).find(".w2ui-lock").remove(),$(a).find(".w2ui-lock-msg").remove()}function x(a,b){var c=$(a),d={left:parseInt(c.css("border-left-width"))||0,right:parseInt(c.css("border-right-width"))||0,top:parseInt(c.css("border-top-width"))||0,bottom:parseInt(c.css("border-bottom-width"))||0},e={left:parseInt(c.css("margin-left"))||0,right:parseInt(c.css("margin-right"))||0,top:parseInt(c.css("margin-top"))||0,bottom:parseInt(c.css("margin-bottom"))||0},f={left:parseInt(c.css("padding-left"))||0,right:parseInt(c.css("padding-right"))||0,top:parseInt(c.css("padding-top"))||0,bottom:parseInt(c.css("padding-bottom"))||0};switch(b){case"top":return d.top+e.top+f.top;case"bottom":return d.bottom+e.bottom+f.bottom;case"left":return d.left+e.left+f.left;case"right":return d.right+e.right+f.right;case"width":return d.left+d.right+e.left+e.right+f.left+f.right+parseInt(c.width());case"height":return d.top+d.bottom+e.top+e.bottom+f.top+f.bottom+parseInt(c.height());case"+width":return d.left+d.right+e.left+e.right+f.left+f.right;case"+height":return d.top+d.bottom+e.top+e.bottom+f.top+f.bottom}return 0}function y(a){var b=this.settings.phrases[a];return null==b?a:b}function z(a){a||(a="en-us"),5===a.length&&(a="locale/"+a+".json"),$.ajax({url:a,type:"GET",dataType:"JSON",async:!1,cache:!1,success:function(a){w2utils.settings=$.extend(!0,w2utils.settings,a);var b=w2obj.grid.prototype;for(var c in b.buttons)b.buttons[c].caption=w2utils.lang(b.buttons[c].caption),b.buttons[c].hint=w2utils.lang(b.buttons[c].hint);b.msgDelete=w2utils.lang(b.msgDelete),b.msgNotJSON=w2utils.lang(b.msgNotJSON),b.msgRefresh=w2utils.lang(b.msgRefresh)},error:function(){console.log("ERROR: Cannot load locale "+a)}})}function A(){if(D.scrollBarSize)return D.scrollBarSize;var a='
    1
    ';return $("body").append(a),D.scrollBarSize=100-$("#_scrollbar_width > div").width(),$("#_scrollbar_width").remove(),String(navigator.userAgent).indexOf("MSIE")>=0&&(D.scrollBarSize=D.scrollBarSize/2),D.scrollBarSize}function B(a,b){return a&&"undefined"!=typeof a.name?"undefined"!=typeof w2ui[a.name]?(console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+a.name+")."),!1):w2utils.isAlphaNumeric(a.name)?!0:(console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '),!1):(console.log('ERROR: The parameter "name" is required but not supplied in $().'+b+"()."),!1)}function C(a,b,c,d){$.isArray(b)||(b=[b]);for(var e=0;ed;d++){var f=this.handlers[d];(f.event.type!==a.type&&"*"!==a.type||f.event.target!==a.target&&null!==a.target||f.handler!==b&&null!==b)&&c.push(f)}this.handlers=c},trigger:function(a){var a=$.extend({type:null,phase:"before",target:null},a,{isStopped:!1,isCancelled:!1,preventDefault:function(){this.isCancelled=!0},stopPropagation:function(){this.isStopped=!0}});"before"===a.phase&&(a.onComplete=null);var b,c,d;null==a.target&&(a.target=null);for(var e=this.handlers.length-1;e>=0;e--){var f=this.handlers[e];if(!(f.event.type!==a.type&&"*"!==f.event.type||f.event.target!==a.target&&null!==f.event.target||f.event.execute!==a.phase&&"*"!==f.event.execute&&"*"!==f.event.phase)&&(a=$.extend({},f.event,a),b=[],d=RegExp(/\((.*?)\)/).exec(f.handler),d&&(b=d[1].split(/\s*,\s*/)),2===b.length?f.handler.call(this,a.target,a):f.handler.call(this,a),a.isStopped===!0||a.stop===!0))return a}var g="on"+a.type.substr(0,1).toUpperCase()+a.type.substr(1);return"before"===a.phase&&"function"==typeof this[g]&&(c=this[g],b=[],d=RegExp(/\((.*?)\)/).exec(c),d&&(b=d[1].split(/\s*,\s*/)),2===b.length?c.call(this,a.target,a):c.call(this,a),a.isStopped===!0||a.stop===!0)?a:null!=a.object&&"before"===a.phase&&"function"==typeof a.object[g]&&(c=a.object[g],b=[],d=RegExp(/\((.*?)\)/).exec(c),d&&(b=d[1].split(/\s*,\s*/)),2===b.length?c.call(this,a.target,a):c.call(this,a),a.isStopped===!0||a.stop===!0)?a:("after"===a.phase&&"function"==typeof a.onComplete&&a.onComplete.call(this,a),a)}},w2utils.keyboard=function(a){function b(){$(document).on("keydown",c),$(document).on("mousedown",d)}function c(a){var b=a.target.tagName;-1===$.inArray(b,["INPUT","SELECT","TEXTAREA"])&&"true"!==$(a.target).prop("contenteditable")&&h&&w2ui[h]&&"function"==typeof w2ui[h].keydown&&w2ui[h].keydown.call(w2ui[h],a)}function d(a){var b=(a.target.tagName,$(a.target).parents(".w2ui-reset"));if(b.length>0){var c=b.attr("name");w2ui[c]&&w2ui[c].keyboard&&(h=c)}}function e(a){return"undefined"!=typeof a&&(h=a),h}function f(){h=null}function g(){}var h=null;return a.active=e,a.clear=f,a.register=g,b(),a}({}),function(){$.fn.w2render=function(a){$(this).length>0&&("string"==typeof a&&w2ui[a]&&w2ui[a].render($(this)[0]),"object"==typeof a&&a.render($(this)[0]))},$.fn.w2destroy=function(a){!a&&this.length>0&&(a=this.attr("name")),"string"==typeof a&&w2ui[a]&&w2ui[a].destroy(),"object"==typeof a&&a.destroy()},$.fn.w2marker=function(a){return $(this).each(""===a||null==a?function(a,b){b.innerHTML=b.innerHTML.replace(/\(.*)\<\/span\>/gi,"$1")}:function(b,c){function d(a){return''+a+""}"string"==typeof a&&(a=[a]),c.innerHTML=c.innerHTML.replace(/\(.*)\<\/span\>/gi,"$1");for(var e in a){var f=a[e];"string"!=typeof f&&(f=String(f)),f=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&").replace(/&/g,"&").replace(//g,"<");var g=new RegExp(f+"(?!([^<]+)?>)","gi");c.innerHTML=c.innerHTML.replace(g,d)}})},$.fn.w2tag=function(a,b){return $.isPlainObject(b)||(b={}),$.isPlainObject(b.css)||(b.css={}),"undefined"==typeof b["class"]&&(b["class"]=""),0===$(this).length?void $(".w2ui-tag").each(function(a,b){var c=$(b).data("options");null==c&&(c={}),$($(b).data("taged-el")).removeClass(c["class"]),clearInterval($(b).data("timer")),$(b).remove()}):$(this).each(function(c,d){function e(){$tag=$("#w2ui-tag-"+g),$tag.length<=0||(clearInterval($tag.data("timer")),$tag.remove(),$(d).off("keypress",e).removeClass(b["class"]),$(d).length>0&&($(d)[0].style.cssText=i),"function"==typeof b.onHide&&b.onHide())}var f=d.id,g=w2utils.escapeId(d.id);if(""===a||null==a)$("#w2ui-tag-"+g).css("opacity",0),setTimeout(function(){clearInterval($("#w2ui-tag-"+g).data("timer")),$("#w2ui-tag-"+g).remove()},300);else{clearInterval($("#w2ui-tag-"+g).data("timer")),$("#w2ui-tag-"+g).remove(),$("body").append('
    0?"w2ui-tag-popup":"")+'" style="">
    ');var h=setInterval(function(){return 0===$(d).length||0===$(d).offset().left&&0===$(d).offset().top?(clearInterval($("#w2ui-tag-"+g).data("timer")),void e()):void($("#w2ui-tag-"+g).data("position")!==$(d).offset().left+d.offsetWidth+"x"+$(d).offset().top&&$("#w2ui-tag-"+g).css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s",left:$(d).offset().left+d.offsetWidth+"px",top:$(d).offset().top+"px"}).data("position",$(d).offset().left+d.offsetWidth+"x"+$(d).offset().top))},100);setTimeout(function(){$(d).offset()&&($("#w2ui-tag-"+g).css({opacity:"1",left:$(d).offset().left+d.offsetWidth+"px",top:$(d).offset().top+"px"}).html('
    '+a+"
    ").data("text",a).data("taged-el",d).data("options",b).data("position",$(d).offset().left+d.offsetWidth+"x"+$(d).offset().top).data("timer",h),$(d).off("keypress",e).on("keypress",e).off("change",e).on("change",e).css(b.css).addClass(b["class"]),"function"==typeof b.onShow&&b.onShow())},1);var i="";$(d).length>0&&(i=$(d)[0].style.cssText)}})},$.fn.w2overlay=function(a,b){function c(){var a=$("#w2ui-overlay"+g);if(a.data("element")===f[0]&&0!==a.length){var b=$(f).offset().left+"x"+$(f).offset().top;a.data("position")!==b?d():setTimeout(c,250)}}function d(){var a=$("#w2ui-overlay"+g);if(a.data("keepOpen")===!0)return void a.removeData("keepOpen");var c;"function"==typeof b.onHide&&(c=b.onHide()),c!==!1&&(a.remove(),$(document).off("click",d),clearInterval(a.data("timer")))}function e(){var a=$("#w2ui-overlay"+g),c=a.find(" > div");if(a.length>0){c.height("auto").width("auto");var d=!1,h=!1,i=c.height(),j=c.width();switch(b.width&&b.widthj&&(j=30),b.tmp.contentHeight&&(i=b.tmp.contentHeight,c.height(i),setTimeout(function(){c.height()>c.find("div.menu > table").height()&&c.find("div.menu").css("overflow-y","hidden")},1),setTimeout(function(){c.find("div.menu").css("overflow-y","auto")},10)),b.tmp.contentWidth&&(j=b.tmp.contentWidth,c.width(j),setTimeout(function(){c.width()>c.find("div.menu > table").width()&&c.find("div.menu").css("overflow-x","hidden")},1),setTimeout(function(){c.find("div.menu").css("overflow-y","auto")},10)),b.align){case"both":b.left=17,0===b.width&&(b.width=w2utils.getSize($(f),"width"));break;case"left":b.left=17;break;case"right":b.tipLeft=j-45,b.left=w2utils.getSize($(f),"width")-j+10}var k=(j-17)/2,l=b.left,m=b.width,n=b.tipLeft;m=30!==j||m?b.width?b.width:"auto":30,25>k&&(l=25-k,n=Math.floor(k)),a.css({top:f.offset().top+w2utils.getSize(f,"height")+b.top+7+"px",left:(f.offset().left>25?f.offset().left:25)+l+"px","min-width":m,"min-height":b.height?b.height:"auto"});var o=window.innerHeight+$(document).scrollTop()-c.offset().top-7,p=window.innerWidth+$(document).scrollLeft()-c.offset().left-7;o>-50&&210>o||b.openAbove===!0?(o=c.offset().top-$(document).scrollTop()-7,b.maxHeight&&o>b.maxHeight&&(o=b.maxHeight),i>o&&(h=!0,c.height(o).width(j).css({"overflow-y":"auto"}),i=o),a.css("top",$(f).offset().top-i-24+b.top+"px"),a.find(">style").html("#w2ui-overlay"+g+":before { display: none; margin-left: "+parseInt(n)+"px; }#w2ui-overlay"+g+":after { display: block; margin-left: "+parseInt(n)+"px; }")):(b.maxHeight&&o>b.maxHeight&&(o=b.maxHeight),i>o&&(h=!0,c.height(o).width(j).css({"overflow-y":"auto"})),a.find(">style").html("#w2ui-overlay"+g+":before { display: block; margin-left: "+parseInt(n)+"px; }#w2ui-overlay"+g+":after { display: none; margin-left: "+parseInt(n)+"px; }")),j=c.width(),p=window.innerWidth+$(document).scrollLeft()-c.offset().left-7,b.maxWidth&&p>b.maxWidth&&(p=b.maxWidth),j>p&&"both"!==b.align&&(b.align="right",setTimeout(function(){e()},1)),h&&d&&c.width(j+w2utils.scrollBarSize()+2)}}var f=this,g="",h={name:null,align:"none",left:0,top:0,tipLeft:30,width:0,height:0,maxWidth:null,maxHeight:null,style:"","class":"",onShow:null,onHide:null,openAbove:!1,tmp:{}};$.isPlainObject(b)||(b={}),b=$.extend({},h,b),b.name&&(g="-"+b.name);var i;if(0===this.length||""===a||null==a)return $("#w2ui-overlay"+g).length>0?(i=$("#w2ui-overlay"+g)[0].hide,"function"==typeof i&&i()):$("#w2ui-overlay"+g).remove(),$(this);$("#w2ui-overlay"+g).length>0&&(i=$("#w2ui-overlay"+g)[0].hide,$(document).off("click",i),"function"==typeof i&&i()),$("body").append('');var j=$("#w2ui-overlay"+g),k=j.find(" > div");k.html(a);var l=k.css("background-color");return null!=l&&"rgba(0, 0, 0, 0)"!==l&&"transparent"!==l&&j.css("background-color",l),j.data("element",f.length>0?f[0]:null).data("options",b).data("position",$(f).offset().left+"x"+$(f).offset().top).fadeIn("fast").on("mousedown",function(a){$("#w2ui-overlay"+g).data("keepOpen",!0),-1===["INPUT","TEXTAREA","SELECT"].indexOf(a.target.tagName)&&a.preventDefault()}),j[0].hide=d,j[0].resize=e,e(),setTimeout(function(){e(),$(document).off("click",d).on("click",d),"function"==typeof b.onShow&&b.onShow()},10),c(),$(this)},$.fn.w2menu=function(a,b){function c(){setTimeout(function(){$("#w2ui-overlay"+h+" tr.w2ui-selected").removeClass("w2ui-selected");var a=$("#w2ui-overlay"+h+" tr[index="+b.index+"]"),c=$("#w2ui-overlay"+h+" div.menu").scrollTop();if(a.addClass("w2ui-selected"),b.tmp&&(b.tmp.contentHeight=$("#w2ui-overlay"+h+" table").height()+(b.search?50:10)),b.tmp&&(b.tmp.contentWidth=$("#w2ui-overlay"+h+" table").width()),$("#w2ui-overlay"+h)[0].resize(),a.length>0){var d=a[0].offsetTop-5,e=$("#w2ui-overlay"+h+" div.menu"),f=e.height();$("#w2ui-overlay"+h+" div.menu").scrollTop(c),(c>d||d+a.height()>c+f)&&$("#w2ui-overlay"+h+" div.menu").animate({scrollTop:d-(f-2*a.height())/2},200,"linear")}},1)}function d(a){var d=this.value,e=a.keyCode,f=!1;switch(e){case 13:$("#w2ui-overlay"+h).remove(),$.fn.w2menuHandler(a,b.index);break;case 9:case 27:$("#w2ui-overlay"+h).remove(),$.fn.w2menuHandler(a,-1);break;case 38:for(b.index=w2utils.isInt(b.index)?parseInt(b.index):0,b.index--;b.index>0&&b.items[b.index].hidden;)b.index--;if(0===b.index&&b.items[b.index].hidden)for(;b.items[b.index]&&b.items[b.index].hidden;)b.index++;b.index<0&&(b.index=0),f=!0;break;case 40:for(b.index=w2utils.isInt(b.index)?parseInt(b.index):0,b.index++;b.index=b.items.length&&(b.index=b.items.length-1),f=!0}if(!f){var i=0;for(var j in b.items){var k=b.items[j],l="",m="";-1!==["is","begins with"].indexOf(b.match)&&(l="^"),-1!==["is","ends with"].indexOf(b.match)&&(m="$");try{var n=new RegExp(l+d+m,"i");k.hidden=n.test(k.text)||"..."===k.text?!1:!0,b.applyFilter!==!0&&(k.hidden=!1)}catch(o){}"enum"===g.type&&-1!==$.inArray(k.id,ids)&&(k.hidden=!0),k.hidden!==!0&&i++}for(b.index=0;b.index=i&&(b.index=-1)}$(g).w2menu("refresh",b),c()}function e(){if(b.spinner)return'
    Loading...
    ';for(var a=0,c='',d=null,e=null,f=0;f
    '),e&&(i='
    '),"undefined"==typeof j||""===j||/^-+$/.test(j))c+='';else{var k=a%2===0?"w2ui-item-even":"w2ui-item-odd";b.altRows!==!0&&(k=""),c+='"+i+" ",a++ -}}b.items[f]=g}return 0===a&&(c+='"),c+="
    "+j+"
    '+b.msgNoItems+"
    "}var f={index:null,items:[],render:null,msgNoItems:"No items",onSelect:null,tmp:{}},g=this,h="";if("refresh"!==a){1===arguments.length?b=a:b.items=a,"object"!=typeof b&&(b={}),b=$.extend({},f,b),$.fn.w2menuOptions=b,b.name&&(h="-"+b.name),"function"==typeof b.select&&"function"!=typeof b.onSelect&&(b.onSelect=b.select),"function"==typeof b.onRender&&"function"!=typeof b.render&&(b.render=b.onRender),$.fn.w2menuHandler=function(a,c){"function"==typeof b.onSelect&&setTimeout(function(){b.onSelect({index:c,item:b.items[c],originalEvent:a})},10)};var i="";if(b.search){i+='
    ',b.style+=";background-color: #ECECEC",b.index=0;for(var j in b.items)b.items[j].hidden=!1}i+='";var k=$(this).w2overlay(i,b);return setTimeout(function(){$("#w2ui-overlay"+h+" #menu-search").on("keyup",d).on("keydown",function(a){9===a.keyCode&&(a.stopPropagation(),a.preventDefault())})},200),c(),k}if($("#w2ui-overlay"+h).length>0){b=$.extend($.fn.w2menuOptions,b);var l=$("#w2ui-overlay"+h+" div.menu").scrollTop();$("#w2ui-overlay"+h+" div.menu").html(e()),$("#w2ui-overlay"+h+" div.menu").scrollTop(l),c()}else $(this).w2menu(b)}}(),function(a){var b=function(b){this.el=null,this.helpers={},this.type=b.type||"text",this.options=a.extend(!0,{},b),this.onSearch=b.onSearch||null,this.onRequest=b.onRequest||null,this.onLoad=b.onLoad||null,this.onError=b.onError||null,this.onClick=b.onClick||null,this.onAdd=b.onAdd||null,this.onNew=b.onNew||null,this.onRemove=b.onRemove||null,this.onMouseOver=b.onMouseOver||null,this.onMouseOut=b.onMouseOut||null,this.onIconClick=b.onIconClick||null,this.tmp={},delete this.options.type,delete this.options.onSearch,delete this.options.onRequest,delete this.options.onLoad,delete this.options.onError,delete this.options.onClick,delete this.options.onMouseOver,delete this.options.onMouseOut,delete this.options.onIconClick,a.extend(!0,this,w2obj.field)};a.fn.w2field=function(c,d){if(0!=this.length)return"string"==typeof c&&"object"==typeof d&&(c=a.extend(!0,{},d,{type:c})),"string"==typeof c&&"undefined"==typeof d&&(c={type:c}),c.type=String(c.type).toLowerCase(),this.each(function(d,e){var f=a(e).data("w2field");if("undefined"==typeof f){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}if(f.clear(),"clear"!=c.type){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}});var e=b.prototype;return e[c]?e[c].apply(e,Array.prototype.slice.call(arguments,1)):void 0},b.prototype={custom:{},pallete:[["000000","444444","666666","999999","CCCCCC","EEEEEE","F3F3F3","FFFFFF"],["FF011B","FF9838","FFFD59","01FD55","00FFFE","0424F3","9B24F4","FF21F5"],["F4CCCC","FCE5CD","FFF2CC","D9EAD3","D0E0E3","CFE2F3","D9D1E9","EAD1DC"],["EA9899","F9CB9C","FEE599","B6D7A8","A2C4C9","9FC5E8","B4A7D6","D5A6BD"],["E06666","F6B26B","FED966","93C47D","76A5AF","6FA8DC","8E7CC3","C27BA0"],["CC0814","E69138","F1C232","6AA84F","45818E","3D85C6","674EA7","A54D79"],["99050C","B45F17","BF901F","37761D","124F5C","0A5394","351C75","741B47"],["660205","783F0B","7F6011","274E12","0C343D","063762","20124D","4C1030"]],addType:function(a,b){return a=String(a).toLowerCase(),this.custom[a]=b,!0},removeType:function(a){return a=String(a).toLowerCase(),this.custom[a]?(delete this.custom[a],!0):!1},init:function(){var b,c=this,d=this.options;if("function"==typeof this.custom[this.type])return void this.custom[this.type].call(this,d);if(-1==["INPUT","TEXTAREA"].indexOf(this.el.tagName))return void console.log("ERROR: w2field could only be applied to INPUT or TEXTAREA.",this.el);switch(this.type){case"text":case"int":case"float":case"money":case"currency":case"percent":case"alphanumeric":case"hex":b={min:null,max:null,step:1,placeholder:"",autoFormat:!0,currencyPrefix:w2utils.settings.currencyPrefix,currencySuffix:w2utils.settings.currencySuffix,currencyPrecision:w2utils.settings.currencyPrecision,groupSymbol:w2utils.settings.groupSymbol,arrows:!1,keyboard:!0,precision:null,silent:!0,prefix:"",suffix:""},this.options=a.extend(!0,{},b,d),d=this.options,d.numberRE=new RegExp("["+d.groupSymbol+"]","g"),d.moneyRE=new RegExp("["+d.currencyPrefix+d.currencySuffix+d.groupSymbol+"]","g"),d.percentRE=new RegExp("["+d.groupSymbol+"%]","g"),-1!=["text","alphanumeric","hex"].indexOf(this.type)&&(d.arrows=!1,d.keyboard=!1),this.addPrefix(),this.addSuffix(),a(this.el).attr("placeholder",d.placeholder);break;case"color":b={prefix:"#",suffix:'
     
    ',placeholder:"",arrows:!1,keyboard:!1},a.extend(d,b),this.addPrefix(),this.addSuffix(),a(this.el).attr("maxlength",6),""!=a(this.el).val()&&setTimeout(function(){a(c.el).change()},1),a(this.el).attr("placeholder",d.placeholder);break;case"date":b={format:w2utils.settings.date_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:"",blocked:{},colored:{}},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:d.format);break;case"time":b={format:w2utils.settings.time_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:""},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:"h12"==d.format?"hh:mi pm":"hh:mi");break;case"datetime":break;case"list":case"combo":if(b={items:[],selected:{},placeholder:"",url:null,postData:{},minLength:1,cacheMax:250,maxDropHeight:350,match:"begins",silent:!0,icon:null,iconStyle:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onIconClick:null,renderDrop:null,prefix:"",suffix:"",openOnFocus:!1,markSearch:!1},"list"==this.type&&(b.openOnFocus=!0,b.suffix='
    ',a(this.el).addClass("w2ui-select"),!a.isPlainObject(d.selected)))for(var e in d.items){var f=d.items[e];if(f&&f.id==d.selected){d.selected=a.extend(!0,{},f);break}}d=a.extend({},b,d,{align:"both",altRows:!0}),d.items=this.normMenu(d.items),this.options=d,a.isPlainObject(d.selected)||(d.selected={}),a(this.el).data("selected",d.selected),d.url&&this.request(0),d.icon&&(d.prefix=''),"list"==this.type&&this.addFocus(),this.addPrefix(),this.addSuffix(),setTimeout(function(){c.refresh()},10),a(this.el).attr("placeholder",d.placeholder).attr("autocomplete","off"),"undefined"!=typeof d.selected.text&&a(this.el).val(d.selected.text);break;case"enum":b={items:[],selected:[],placeholder:"",max:0,url:null,postData:{},minLength:1,cacheMax:250,maxWidth:250,maxHeight:350,maxDropHeight:350,match:"contains",silent:!0,openOnFocus:!1,markSearch:!0,renderDrop:null,renderItem:null,style:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onClick:null,onAdd:null,onNew:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",suffix:"",altRows:!0}),d.items=this.normMenu(d.items),d.selected=this.normMenu(d.selected),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),d.url&&this.request(0),this.addSuffix(),this.addMulti();break;case"file":b={selected:[],placeholder:w2utils.lang("Attach files by dragging and dropping or Click to Select"),max:0,maxSize:0,maxFileSize:0,maxWidth:250,maxHeight:350,maxDropHeight:350,silent:!0,renderItem:null,style:"",onClick:null,onAdd:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",altRows:!0}),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),this.addMulti()}this.tmp={onChange:function(a){c.change.call(c,a)},onClick:function(a){c.click.call(c,a)},onFocus:function(a){c.focus.call(c,a)},onBlur:function(a){c.blur.call(c,a)},onKeydown:function(a){c.keyDown.call(c,a)},onKeyup:function(a){c.keyUp.call(c,a)},onKeypress:function(a){c.keyPress.call(c,a)}},a(this.el).addClass("w2field").data("w2field",this).on("change",this.tmp.onChange).on("click",this.tmp.onClick).on("focus",this.tmp.onFocus).on("blur",this.tmp.onBlur).on("keydown",this.tmp.onKeydown).on("keyup",this.tmp.onKeyup).on("keypress",this.tmp.onKeypress).css({"box-sizing":"border-box","-webkit-box-sizing":"border-box","-moz-box-sizing":"border-box","-ms-box-sizing":"border-box","-o-box-sizing":"border-box"}),this.change(a.Event("change"))},clear:function(){var b=this.options;-1!=["money","currency"].indexOf(this.type)&&a(this.el).val(a(this.el).val().replace(b.moneyRE,"")),"percent"==this.type&&a(this.el).val(a(this.el).val().replace(/%/g,"")),"color"==this.type&&a(this.el).removeAttr("maxlength"),"list"==this.type&&a(this.el).removeClass("w2ui-select"),this.type="clear";var c=a(this.el).data("tmp");if(this.tmp){"undefined"!=typeof c&&(c&&c["old-padding-left"]&&a(this.el).css("padding-left",c["old-padding-left"]),c&&c["old-padding-right"]&&a(this.el).css("padding-right",c["old-padding-right"])),a(this.el).val(this.clean(a(this.el).val())).removeClass("w2field").removeData().off("change",this.tmp.onChange).off("click",this.tmp.onClick).off("focus",this.tmp.onFocus).off("blur",this.tmp.onBlur).off("keydown",this.tmp.onKeydown).off("keyup",this.tmp.onKeyup).off("keypress",this.tmp.onKeypress);for(var d in this.helpers)a(this.helpers[d]).remove();this.helpers={}}},refresh:function(){var b=this,c=this.options,d=a(this.el).data("selected"),e=(new Date).getTime();if(-1!=["list"].indexOf(this.type)&&(a(b.el).parent().css("white-space","nowrap"),b.helpers.prefix&&b.helpers.prefix.hide(),setTimeout(function(){var c=b.helpers.focus.find("input");""==a(c).val()?(a(c).css("opacity",0).prev().css("opacity",0),a(b.el).val(d&&null!=d.text?d.text:""),a(b.el).attr("placeholder",a(b.el).attr("_placeholder")),a.isEmptyObject(d)?b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide():b.helpers&&b.helpers.prefix&&b.helpers.prefix.show()):(a(c).css("opacity",1).prev().css("opacity",1),b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide(),a(b.el).val(""),a(b.el).attr("_placeholder",a(b.el).attr("placeholder")).removeAttr("placeholder"))},1)),-1!=["enum","file"].indexOf(this.type)){var f="";for(var g in d){var h=d[g],i="";i="function"==typeof c.renderItem?c.renderItem(h,g,'
      
    '):'
      
    '+("enum"==b.type?h.text:h.name+' - '+w2utils.size(h.size)+""),f+='
  • '+i+"
  • "}var j=b.helpers.multi,k=j.find("ul");if(j.attr("style",j.attr("style")+";"+c.style),a(b.el).attr("readonly")?j.addClass("w2ui-readonly"):j.removeClass("w2ui-readonly"),j.find(".w2ui-enum-placeholder").remove(),k.find("li").not("li.nomouse").remove(),""!=f)k.prepend(f);else if("undefined"!=typeof c.placeholder){var l="padding-top: "+a(this.el).css("padding-top")+";padding-left: "+a(this.el).css("padding-left")+"; box-sizing: "+a(this.el).css("box-sizing")+"; line-height: "+a(this.el).css("line-height")+"; font-size: "+a(this.el).css("font-size")+"; font-family: "+a(this.el).css("font-family")+"; ";j.prepend('
    '+c.placeholder+"
    ")}j.find("li").data("mouse","out").on("click",function(c){var e=d[a(c.target).attr("index")];if(!a(c.target).hasClass("nomouse")){c.stopPropagation();var f=b.trigger({phase:"before",type:"click",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled!==!0){if(a(c.target).hasClass("w2ui-list-remove")){if(a(b.el).attr("readonly"))return;var f=b.trigger({phase:"before",type:"remove",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled===!0)return;a().w2overlay(),d.splice(a(c.target).attr("index"),1),a(b.el).trigger("change"),a(c.target).parent().fadeOut("fast"),setTimeout(function(){b.refresh(),b.trigger(a.extend(f,{phase:"after"}))},300)}if("file"==b.type&&!a(c.target).hasClass("w2ui-list-remove")){var g="";/image/i.test(e.type)&&(g='
    ');var h='style="padding: 3px; text-align: right; color: #777;"',i='style="padding: 3px"';g+='
    Name:"+e.name+"
    Size:"+w2utils.size(e.size)+"
    Type: '+e.type+"
    Modified:"+w2utils.date(e.modified)+"
    ",a(c.target).w2overlay(g)}b.trigger(a.extend(f,{phase:"after"}))}}}).on("mouseover",function(c){var e=c.target;if("LI"!=e.tagName&&(e=e.parentNode),!a(e).hasClass("nomouse")){if("out"==a(e).data("mouse")){var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"mouseOver",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}a(e).data("mouse","over")}}).on("mouseout",function(c){var e=c.target;"LI"!=e.tagName&&(e=e.parentNode),a(e).hasClass("nomouse")||(a(e).data("mouse","leaving"),setTimeout(function(){if("leaving"==a(e).data("mouse")){a(e).data("mouse","out");var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"f",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}},0))}),a(this.el).height("auto");var m=a(j).find("> div").height()+2*w2utils.getSize(j,"+height");26>m&&(m=26),m>c.maxHeight&&(m=c.maxHeight),j.length>0&&(j[0].scrollTop=1e3);var n=w2utils.getSize(a(this.el),"height")-2;n>m&&(m=n),a(j).css({height:m+"px",overflow:m==c.maxHeight?"auto":"hidden"}),mc.max&&(b=c.max,a(this.el).val(c.max))),b=""!==b&&w2utils.isFloat(b)?Number(b):""),b},format:function(a){var b=this.options;if(b.autoFormat&&""!=a)switch(this.type){case"money":case"currency":a=w2utils.formatNumber(Number(a).toFixed(b.currencyPrecision),b.groupSymbol),""!=a&&(a=b.currencyPrefix+a+b.currencySuffix);break;case"percent":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol),""!=a&&(a+="%");break;case"float":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol);break;case"int":a=w2utils.formatNumber(a,b.groupSymbol)}return a},change:function(b){{var c=this;c.options}if(-1!=["int","float","money","currency","percent"].indexOf(this.type)){var d=a(this.el).val(),e=this.format(this.clean(a(this.el).val()));if(""!=d&&d!=e)return a(this.el).val(e).change(),b.stopPropagation(),b.preventDefault(),!1}if("color"==this.type){var f="#"+a(this.el).val();6!=a(this.el).val().length&&3!=a(this.el).val().length&&(f=""),a(this.el).next().find("div").css("background-color",f),a(c.el).is(":focus")&&this.updateOverlay()}},click:function(b){b.stopPropagation(),-1!=["list","combo","enum"].indexOf(this.type)&&(a(this.el).is(":focus")||this.focus(b)),-1!=["date","time","color"].indexOf(this.type)&&this.updateOverlay()},focus:function(){{var b=this;this.options}if(-1!==["color","date","time"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){b.updateOverlay()},150)}if(-1!=["list","combo","enum"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){return"list"==b.type&&a(b.el).is(":focus")?void a(b.helpers.focus).find("input").focus():(b.search(),void setTimeout(function(){b.updateOverlay()},1))},1)}"file"==b.type&&a(b.helpers.multi).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"})},blur:function(){var b=this,c=b.options,d=a(b.el).val().trim();-1!=["color","date","time","list","combo","enum"].indexOf(b.type)&&a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),-1!=["int","float","money","currency","percent"].indexOf(b.type)&&(""===d||b.checkType(d)||(a(b.el).val("").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid number"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),-1!=["date","time"].indexOf(b.type)&&(w2utils.isInt(b.el.value)&&a(b.el).val(w2utils.formatDate(new Date(parseInt(b.el.value)),c.format)).change(),""===d||b.inRange(b.el.value)?("date"!=b.type||""===d||w2utils.isDate(b.el.value,c.format)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid date"),setTimeout(function(){a(b.el).w2tag("")},3e3))),"time"!=b.type||""===d||w2utils.isTime(b.el.value)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid time"),setTimeout(function(){a(b.el).w2tag("")},3e3)))):(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not in range"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),"enum"==b.type&&a(b.helpers.multi).find("input").val("").width(20),"file"==b.type&&a(b.helpers.multi).css({outline:"none"})},keyPress:function(a){{var b=this;b.options}if(-1!=["int","float","money","currency","percent","hex","color","alphanumeric"].indexOf(b.type)){if(a.metaKey||a.ctrlKey||a.altKey||a.charCode!=a.keyCode&&a.keyCode>0)return;var c=String.fromCharCode(a.charCode);if(!b.checkType(c,!0)&&13!=a.keyCode)return a.preventDefault(),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,!1}-1!=["date","time"].indexOf(b.type)&&setTimeout(function(){b.updateOverlay()},1)},keyDown:function(b,c){var d=this,e=d.options,f=b.keyCode||c&&c.keyCode;if(-1!=["int","float","money","currency","percent"].indexOf(d.type)){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,h=parseFloat(a(d.el).val().replace(e.moneyRE,""))||0,i=e.step;switch((b.ctrlKey||b.metaKey)&&(i=10),f){case 38:if(b.shiftKey)break;a(d.el).val(h+i<=e.max||null===e.max?Number((h+i).toFixed(12)):e.max).change(),g=!0;break;case 40:if(b.shiftKey)break;a(d.el).val(h-i>=e.min||null===e.min?Number((h-i).toFixed(12)):e.min).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("date"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,j=864e5,i=1;(b.ctrlKey||b.metaKey)&&(i=10),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatDate(new Date(parseInt(d.el.value)),e.format)).change();var k=w2utils.isDate(a(d.el).val(),e.format,!0);switch(k||(k=new Date,j=0),f){case 38:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()+j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()+1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0;break;case 40:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()-j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()-1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length),d.updateOverlay()},0))}if("time"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,i=1;(b.ctrlKey||b.metaKey)&&(i=60),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatTime(new Date(parseInt(d.el.value)),e.format)).change();var h=a(d.el).val(),m=d.toMin(h)||d.toMin((new Date).getHours()+":"+((new Date).getMinutes()-1));switch(f){case 38:if(b.shiftKey)break;m+=i,g=!0;break;case 40:if(b.shiftKey)break;m-=i,g=!0}g&&(a(d.el).val(d.fromMin(m)).change(),b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("color"==d.type){if(a(d.el).attr("readonly"))return;if(86==b.keyCode&&(b.ctrlKey||b.metaKey)&&(a(d.el).prop("maxlength",7),setTimeout(function(){var b=a(d).val();"#"==b.substr(0,1)&&(b=b.substr(1)),w2utils.isHex(b)||(b=""),a(d).val(b).prop("maxlength",6).change()},20)),(b.ctrlKey||b.metaKey)&&!b.shiftKey){if("undefined"==typeof d.tmp.cind1)d.tmp.cind1=-1,d.tmp.cind2=-1;else{switch(f){case 38:d.tmp.cind1--;break;case 40:d.tmp.cind1++;break;case 39:d.tmp.cind2++;break;case 37:d.tmp.cind2--}d.tmp.cind1<0&&(d.tmp.cind1=0),d.tmp.cind1>this.pallete.length-1&&(d.tmp.cind1=this.pallete.length-1),d.tmp.cind2<0&&(d.tmp.cind2=0),d.tmp.cind2>this.pallete[0].length-1&&(d.tmp.cind2=this.pallete[0].length-1)}-1!=[37,38,39,40].indexOf(f)&&(a(d.el).val(this.pallete[d.tmp.cind1][d.tmp.cind2]).change(),b.preventDefault())}}if(-1!=["list","combo","enum"].indexOf(d.type)){if(a(d.el).attr("readonly"))return;var g=!1,n=a(d.el).data("selected"),o=a(d.helpers.focus).find("input");switch("list"==d.type&&-1==[37,38,39,40].indexOf(f)&&d.refresh(),f){case 27:"list"==d.type&&(""==a(o).val()?a(d.el).data("selected",{}):a(o).val(""),d.refresh(),b.stopPropagation());break;case 37:case 39:break;case 13:if(0==a("#w2ui-overlay").length)break;var p=e.items[e.index],q=a(d.helpers.multi).find("input");if("enum"==d.type)if(null!=p){var r=d.trigger({phase:"before",type:"add",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,n.length>=e.max&&e.max>0&&n.pop(),delete p.hidden,delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}else{p={id:q.val(),text:q.val()};var r=d.trigger({phase:"before",type:"new",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,"function"==typeof d.onNew&&(n.length>=e.max&&e.max>0&&n.pop(),delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh()),d.trigger(a.extend(r,{phase:"after"}))}else p&&a(d.el).data("selected",p).val(p.text).change(),""==a(d.el).val()&&a(d.el).data("selected")&&a(d.el).removeData("selected").val("").change(),"list"==d.type&&(o.val(""),d.refresh()),d.tmp.force_hide=!0;break;case 8:if(-1!=["enum"].indexOf(d.type)&&""==a(d.helpers.multi).find("input").val()&&n.length>0){var p=n[n.length-1],r=d.trigger({phase:"before",type:"remove",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;n.pop(),a(d.el).trigger("change"),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}break;case 38:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):0,e.index--;e.index>0&&e.items[e.index].hidden;)e.index--;if(0==e.index&&e.items[e.index].hidden)for(;e.items[e.index]&&e.items[e.index].hidden;)e.index++;g=!0;break;case 40:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):-1,e.index++;e.index=e.items.length&&(e.index=e.items.length-1),d.updateOverlay(),b.preventDefault(),void setTimeout(function(){if("enum"==d.type){var a=d.helpers.multi.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else if("list"==d.type){var a=d.helpers.focus.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0);if("enum"==d.type){var s=d.helpers.multi.find("input"),t=s.val();s.width(8*(t.length+2)+"px")}-1==[16,17,18,20,37,39,91].indexOf(f)&&setTimeout(function(){d.tmp.force_hide||d.request(),d.search()},1)}},keyUp:function(b){"color"==this.type&&86==b.keyCode&&(b.ctrlKey||b.metaKey)&&a(this).prop("maxlength",6)},clearCache:function(){var a=this.options;a.items=[],this.tmp.xhr_loading=!1,this.tmp.xhr_search="",this.tmp.xhr_total=-1,this.search()},request:function(b){var c=this,d=this.options,e=a(c.el).val()||"";if(d.url){if("enum"==c.type){var f=a(c.helpers.multi).find("input");e=0==f.length?"":f.val()}if("list"==c.type){var f=a(c.helpers.focus).find("input");e=0==f.length?"":f.val()}if(0!=d.minLength&&e.lengthc.tmp.xhr_search.length||e.length>=c.tmp.xhr_search.length&&e.substr(0,c.tmp.xhr_search.length)!=c.tmp.xhr_search||e.lengthd.cacheMax&&b.items.splice(d.cacheMax,1e5),c.tmp.xhr_loading=!1,c.tmp.xhr_search=e,c.tmp.xhr_total=b.items.length,d.items=b.items,c.tmp.emptySet=""==e&&0==b.items.length?!0:!1,c.search(),c.trigger(a.extend(i,{phase:"after"}))}}).error(function(b,d,f){var g={status:d,exceptionThrown:f,rawResponseText:b.responseText},h=c.trigger({phase:"before",type:"error",target:c.el,search:e,error:g,xhr:b});h.isCancelled!==!0&&(console.log("ERROR: server communication failed. The server should return",{status:"success",items:[{id:1,text:"item"}]},", instead the AJAX request produced this: ",g),c.clearCache(),c.trigger(a.extend(h,{phase:"after"})))}),c.trigger(a.extend(g,{phase:"after"})))},b))}},search:function(){var b=this,c=this.options,d=a(b.el).val(),e=b.el,f=[],g=a(b.el).data("selected");if("enum"==b.type){e=a(b.helpers.multi).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}if("list"==b.type){e=a(b.helpers.focus).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}var i=b.trigger({phase:"before",type:"search",target:e,search:d});if(i.isCancelled!==!0){if(b.tmp.xhr_loading!==!0){var j=0;for(var k in c.items){var l=c.items[k],m="",n="";-1!=["is","begins"].indexOf(c.match)&&(m="^"),-1!=["is","ends"].indexOf(c.match)&&(n="$");try{var o=new RegExp(m+d+n,"i");l.hidden=o.test(l.text)||"..."==l.text?!1:!0}catch(p){}"enum"==b.type&&-1!=a.inArray(l.id,f)&&(l.hidden=!0),l.hidden!==!0&&j++}if("combo"!=b.type)for(c.index=0;c.items[c.index]&&c.items[c.index].hidden;)c.index++;else c.index=-1;0>=j&&(c.index=-1),c.spinner=!1,b.updateOverlay(),setTimeout(function(){var b=a("#w2ui-overlay").html()||"";c.markSearch&&-1!=b.indexOf("$.fn.w2menuHandler")&&a("#w2ui-overlay").w2marker(d)},1)}else c.items.splice(0,c.cacheMax),c.spinner=!0,b.updateOverlay();b.trigger(a.extend(i,{phase:"after"}))}},updateOverlay:function(){var b=this,c=this.options;if("color"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length?a(b.el).w2overlay(b.getColorHTML()):a("#w2ui-overlay").html(b.getColorHTML()),a("#w2ui-overlay .color").on("mousedown",function(c){var d=a(c.originalEvent.target).attr("name"),e=a(c.originalEvent.target).attr("index").split(":");b.tmp.cind1=e[0],b.tmp.cind2=e[1],a(b.el).val(d).change(),a(this).html("•")}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}if("date"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
    ',{css:{"background-color":"#f5f5f5"}});var d,e,f=w2utils.isDate(a(b.el).val(),b.options.format,!0);f&&(d=f.getMonth()+1,e=f.getFullYear()),function k(c,d){a("#w2ui-overlay > div > div").html(b.getMonthHTML(c,d)),a("#w2ui-overlay .w2ui-calendar-title").on("mousedown",function(){if(a(this).next().hasClass("w2ui-calendar-jump"))a(this).next().remove();else{var c,d;a(this).after('
    '),a(this).next().hide().html(b.getYearHTML()).fadeIn(200),setTimeout(function(){a("#w2ui-overlay .w2ui-calendar-jump").find(".w2ui-jump-month, .w2ui-jump-year").on("click",function(){a(this).hasClass("w2ui-jump-month")&&(a(this).parent().find(".w2ui-jump-month").removeClass("selected"),a(this).addClass("selected"),d=a(this).attr("name")),a(this).hasClass("w2ui-jump-year")&&(a(this).parent().find(".w2ui-jump-year").removeClass("selected"),a(this).addClass("selected"),c=a(this).attr("name")),null!=c&&null!=d&&(a("#w2ui-overlay .w2ui-calendar-jump").fadeOut(100),setTimeout(function(){k(parseInt(d)+1,c)},100))}),a("#w2ui-overlay .w2ui-calendar-jump >:last-child").prop("scrollTop",2e3)},1)}}),a("#w2ui-overlay .w2ui-date").on("mousedown",function(){var c=a(this).attr("date");a(b.el).val(c).change(),a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"})}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)}),a("#w2ui-overlay .previous").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])-1,k(a[0],a[1])}),a("#w2ui-overlay .next").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])+1,k(a[0],a[1])})}(d,e)}if("time"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
    ',{css:{"background-color":"#fff"}});var g="h24"==this.options.format?!0:!1;a("#w2ui-overlay > div").html(b.getHourHTML()),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var c=a(this).attr("hour");a(b.el).val((c>12&&!g?c-12:c)+":00"+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){var c=a(this).attr("hour");a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),a(b.el).w2overlay('
    ',{css:{"background-color":"#fff"}}),a("#w2ui-overlay > div").html(b.getMinHTML(c)),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var d=a(this).attr("min");a(b.el).val((c>12&&!g?c-12:c)+":"+(10>d?0:"")+d+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide() -},10)})})}if(-1!=["list","combo","enum"].indexOf(this.type)){var h=this.el,i=this.el;if("enum"==this.type&&(h=a(this.helpers.multi),i=a(h).find("input")),"list"==this.type&&(i=a(this.helpers.focus).find("input")),a(i).is(":focus")){if(c.openOnFocus===!1&&""==a(i).val()&&b.tmp.force_open!==!0)return void a().w2overlay();if(b.tmp.force_hide)return a().w2overlay(),void setTimeout(function(){delete b.tmp.force_hide},1);""!=a(i).val()&&delete b.tmp.force_open,0==a("#w2ui-overlay").length&&(c.index=0);var j=w2utils.lang("No matches");null!=c.url&&a(i).val().length=c.max&&c.max>0&&e.pop(),delete d.item.hidden,e.push(d.item),a(b.el).data("selected",e).change(),a(b.helpers.multi).find("input").val("").width(20),b.refresh(),a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),b.trigger(a.extend(f,{phase:"after"}))}}else a(b.el).data("selected",d.item).val(d.item.text).change(),b.helpers.focus&&(b.helpers.focus.find("input").val(""),b.refresh())}}))}}},inRange:function(b){var c=!1;if("date"==this.type){var d=w2utils.isDate(b,this.options.format,!0);if(d){if(this.options.start||this.options.end){var e="string"==typeof this.options.start?this.options.start:a(this.options.start).val(),f="string"==typeof this.options.end?this.options.end:a(this.options.end).val(),g=w2utils.isDate(e,this.options.format,!0),h=w2utils.isDate(f,this.options.format,!0),i=new Date(d);g||(g=i),h||(h=i),i>=g&&h>=i&&(c=!0)}else c=!0;this.options.blocked&&-1!=a.inArray(b,this.options.blocked)&&(c=!1)}}if("time"==this.type)if(this.options.start||this.options.end){var j=this.toMin(b),k=this.toMin(this.options.start),l=this.toMin(this.options.end);k||(k=j),l||(l=j),j>=k&&l>=j&&(c=!0)}else c=!0;return c},checkType:function(a,b){var c=this;switch(c.type){case"int":return b&&-1!=["-"].indexOf(a)?!0:w2utils.isInt(a.replace(c.options.numberRE,""));case"percent":a=a.replace(/%/g,"");case"float":return b&&-1!=["-","."].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.numberRE,""));case"money":case"currency":return b&&-1!=["-",".",c.options.groupSymbol,c.options.currencyPrefix,c.options.currencySuffix].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.moneyRE,""));case"hex":case"color":return w2utils.isHex(a);case"alphanumeric":return w2utils.isAlphaNumeric(a)}return!0},addPrefix:function(){var b=this;setTimeout(function(){if("clear"!==b.type){var c,d=a(b.el).data("tmp")||{};d["old-padding-left"]&&a(b.el).css("padding-left",d["old-padding-left"]),d["old-padding-left"]=a(b.el).css("padding-left"),a(b.el).data("tmp",d),""!==b.options.prefix&&(b.helpers.prefix&&a(b.helpers.prefix).remove(),a(b.el).before('
    '+b.options.prefix+"
    "),c=a(b.el).prev(),c.css({color:a(b.el).css("color"),"font-family":a(b.el).css("font-family"),"font-size":a(b.el).css("font-size"),"padding-top":a(b.el).css("padding-top"),"padding-bottom":a(b.el).css("padding-bottom"),"padding-left":a(b.el).css("padding-left"),"padding-right":0,"margin-top":parseInt(a(b.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(b.el).css("margin-bottom"),10)+1+"px","margin-left":a(b.el).css("margin-left"),"margin-right":0}).on("click",function(){if(b.options.icon&&"function"==typeof b.onIconClick){var c=b.trigger({phase:"before",type:"iconClick",target:b.el,el:a(this).find("span.w2ui-icon")[0]});if(c.isCancelled===!0)return;b.trigger(a.extend(c,{phase:"after"}))}else"list"==b.type?a(b.helpers.focus).find("input").focus():a(b.el).focus()}),a(b.el).css("padding-left",c.width()+parseInt(a(b.el).css("padding-left"),10)+"px"),b.helpers.prefix=c)}},1)},addSuffix:function(){var b,c,d=this;setTimeout(function(){if("clear"!==d.type){var e=a(d.el).data("tmp")||{};if(e["old-padding-right"]&&a(d.el).css("padding-right",e["old-padding-right"]),e["old-padding-right"]=a(d.el).css("padding-right"),a(d.el).data("tmp",e),c=parseInt(a(d.el).css("padding-right"),10),d.options.arrows){d.helpers.arrows&&a(d.helpers.arrows).remove(),a(d.el).after('
     
    ');{w2utils.getSize(d.el,"height")}b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),height:a(d.el).height()+parseInt(a(d.el).css("padding-top"),10)+parseInt(a(d.el).css("padding-bottom"),10)+"px",padding:0,"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":0,"border-left":"1px solid silver"}).css("margin-left","-"+(b.width()+parseInt(a(d.el).css("margin-right"),10)+12)+"px").on("mousedown",function(b){function c(){clearTimeout(a("body").data("_field_update_timer")),a("body").off("mouseup",c)}function e(c){a(d.el).focus(),d.keyDown(a.Event("keydown"),{keyCode:"up"==a(b.target).attr("type")?38:40}),c!==!1&&a("body").data("_field_update_timer",setTimeout(e,60))}a("body").on("mouseup",c),a("body").data("_field_update_timer",setTimeout(e,700)),e(!1)}),c+=b.width()+12,a(d.el).css("padding-right",c+"px"),d.helpers.arrows=b}""!==d.options.suffix&&(d.helpers.suffix&&a(d.helpers.suffix).remove(),a(d.el).after('
    '+d.options.suffix+"
    "),b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),"padding-top":a(d.el).css("padding-top"),"padding-bottom":a(d.el).css("padding-bottom"),"padding-left":"3px","padding-right":a(d.el).css("padding-right"),"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(d.el).css("margin-bottom"),10)+1+"px"}).on("click",function(){"list"==d.type?a(d.helpers.focus).find("input").focus():a(d.el).focus()}),b.css("margin-left","-"+(w2utils.getSize(b,"width")+parseInt(a(d.el).css("margin-right"),10)+2)+"px"),c+=b.width()+3,a(d.el).css("padding-right",c+"px"),d.helpers.suffix=b)}},1)},addFocus:function(){var b=this,c=this.options,d=0;c.icon&&(d=11),a(b.helpers.focus).remove();var e='
    ';a(b.el).attr("tabindex",-1).before(e);var f=a(b.el).prev();b.helpers.focus=f,f.css({width:a(b.el).width(),"margin-top":a(b.el).css("margin-top"),"margin-left":parseInt(a(b.el).css("margin-left"))+parseInt(a(b.el).css("padding-left"))+"px","margin-bottom":a(b.el).css("margin-bottom"),"margin-right":a(b.el).css("margin-right")}).find("input").css({cursor:"default",width:"100%",outline:"none",opacity:1,margin:0,border:"1px solid transparent",padding:a(b.el).css("padding-top"),"padding-left":0,"margin-left":d+(d>0?6:0),"background-color":"transparent"}),f.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),c.stopPropagation()}).on("focus",function(c){a(b.el).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(this).val(""),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(b.el).css("outline","none"),a(this).val(""),b.refresh(),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){b.keyPress(a)}),f.on("click",function(){a(this).find("input").focus()}),b.refresh()},addMulti:function(){{var b=this;this.options}a(b.helpers.multi).remove();var c="",d="margin-top : 0px; margin-bottom : 0px; margin-left : "+a(b.el).css("margin-left")+"; margin-right : "+a(b.el).css("margin-right")+"; width : "+(w2utils.getSize(b.el,"width")-parseInt(a(b.el).css("margin-left"),10)-parseInt(a(b.el).css("margin-right"),10))+"px;";"enum"==b.type&&(c='
    • "),"file"==b.type&&(c='
      '),a(b.el).before(c).css({"background-color":"transparent","border-color":"transparent"});var e=a(b.el).prev();b.helpers.multi=e,"enum"==b.type&&(a(b.el).attr("tabindex",-1),e.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),a(b.el).triggerHandler("click")}).on("focus",function(c){a(e).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(e).css("outline","none"),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){e.find(".w2ui-enum-placeholder").remove(),b.keyPress(a)}),e.on("click",function(){a(this).find("input").focus()})),"file"==b.type&&(a(b.el).css("outline","none"),e.on("click",function(c){a(b.el).focus(),a(b.el).attr("readonly")||(b.blur(c),e.find("input").click())}).on("dragenter",function(){a(b.el).attr("readonly")||a(e).addClass("w2ui-file-dragover")}).on("dragleave",function(c){if(!a(b.el).attr("readonly")){var d=a(c.target).parents(".w2ui-field-helper");0==d.length&&a(e).removeClass("w2ui-file-dragover")}}).on("drop",function(c){if(!a(b.el).attr("readonly")){a(e).removeClass("w2ui-file-dragover");for(var d=c.originalEvent.dataTransfer.files,f=0,g=d.length;g>f;f++)b.addFile.call(b,d[f]);c.preventDefault(),c.stopPropagation()}}).on("dragover",function(a){a.preventDefault(),a.stopPropagation()}),e.find("input").on("click",function(a){a.stopPropagation()}).on("change",function(){if("undefined"!=typeof this.files)for(var a=0,c=this.files.length;c>a;a++)b.addFile.call(b,this.files[a])})),b.refresh()},addFile:function(b){var c,d=this,e=this.options,f=a(d.el).data("selected"),g={name:b.name,type:b.type,modified:b.lastModifiedDate,size:b.size,content:null},h=0,i=0;for(var j in f)h+=f[j].size,i++;var k=d.trigger({phase:"before",type:"add",target:d.el,file:g,total:i,totalSize:h});if(k.isCancelled!==!0){if(0!==e.maxFileSize&&g.size>e.maxFileSize)return c="Maximum file size is "+w2utils.size(e.maxFileSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.maxSize&&h+g.size>e.maxSize)return c="Maximum total size is "+w2utils.size(e.maxSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.max&&i>=e.max)return c="Maximum number of files is "+e.max,e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(f.push(g),"undefined"!=typeof FileReader){var l=new FileReader;l.onload=function(){return function(b){var c=b.target.result,e=c.indexOf(",");g.content=c.substr(e+1),d.refresh(),a(d.el).trigger("change"),d.trigger(a.extend(k,{phase:"after"}))}}(),l.readAsDataURL(b)}else d.refresh(),a(d.el).trigger("change")}},normMenu:function(b){if(a.isArray(b)){for(var c=0;cc;c++){b+="";for(var d=0;8>d;d++)b+='
      '+(a(this.el).val()==this.pallete[c][d]?"•":" ")+"
      ";b+="",2>c&&(b+='')}return b+="
      "},getMonthHTML:function(a,b){var c=new Date,d=w2utils.settings.fullmonths,e=(w2utils.settings.fulldays,["31","28","31","30","31","30","31","31","30","31","30","31"]),f=c.getFullYear()+"/"+(Number(c.getMonth())+1)+"/"+c.getDate();b=w2utils.isInt(b)?parseInt(b):c.getFullYear(),a=w2utils.isInt(a)?parseInt(a):c.getMonth()+1,a>12&&(a-=12,b++),(1>a||0===a)&&(a+=12,b--),e[1]=b/4==Math.floor(b/4)?"29":"28",this.options.current=a+"/"+b,c=new Date(b,a-1,1);for(var g=c.getDay(),h=w2utils.settings.shortdays,i="",j=0,k=h.length;k>j;j++)i+=""+h[j]+"";for(var l='
      '+d[a-1]+", "+b+'
      '+i+"",m=1,n=1;43>n;n++){if(0===g&&1==n){for(var o=0;6>o;o++)l+='';n+=6}else if(g>n||m>e[a-1]){l+='',n%7===0&&(l+="");continue}var p=b+"/"+a+"/"+m,q="";n%7==6&&(q=" w2ui-saturday"),n%7===0&&(q=" w2ui-sunday"),p==f&&(q+=" w2ui-today");var r=m,s="",t="",u=w2utils.formatDate(p,this.options.format);this.options.colored&&void 0!==this.options.colored[u]&&(tmp=this.options.colored[u].split(":"),t="background-color: "+tmp[0]+";",s="color: "+tmp[1]+";"),l+='",(n%7===0||0===g&&1==n)&&(l+=""),m++}return l+="
        
      '+r+"
      "},getYearHTML:function(){var a=w2utils.settings.shortmonths,b="",c="";for(var d in a)b+='
      '+a[d]+"
      ";for(var e=1950;2020>=e;e++)c+='
      '+e+"
      ";return"
      "+b+"
      "+c+"
      "},getHourHTML:function(){for(var a=[],b="h24"==this.options.format?!0:!1,c=0;24>c;c++){var d=(c>=12&&!b?c-12:c)+":00"+(b?"":12>c?" am":" pm");12!=c||b||(d="12:00 pm"),a[Math.floor(c/8)]||(a[Math.floor(c/8)]="");var e=this.fromMin(this.toMin(d)),f=this.fromMin(this.toMin(d)+59);a[Math.floor(c/8)]+='
      '+d+"
      "}var g='
      '+a[0]+" "+a[1]+" "+a[2]+"
      ";return g},getMinHTML:function(a){"undefined"==typeof a&&(a=0);for(var b="h24"==this.options.format?!0:!1,c=[],d=0;60>d;d+=5){var e=(a>12&&!b?a-12:a)+":"+(10>d?0:"")+d+" "+(b?"":12>a?"am":"pm"),f=20>d?0:40>d?1:2;c[f]||(c[f]=""),c[f]+='
      '+e+"
      "}var g='
      '+c[0]+" "+c[1]+" "+c[2]+"
      ";return g},toMin:function(a){if("string"!=typeof a)return null;var b=a.split(":");return 2!=b.length?null:(b[0]=parseInt(b[0]),b[1]=parseInt(b[1]),-1!=a.indexOf("pm")&&12!=b[0]&&(b[0]+=12),60*b[0]+b[1])},fromMin:function(a){var b="";a>=1440&&(a%=1440),0>a&&(a=1440+a);var c=Math.floor(a/60),d=(10>a%60?"0":"")+a%60;return b=-1!=this.options.format.indexOf("h24")?c+":"+d:(12>=c?c:c-12)+":"+d+" "+(c>=12?"pm":"am")}},a.extend(b.prototype,w2utils.event),w2obj.field=b}(jQuery); \ No newline at end of file +var w2ui=w2ui||{},w2obj=w2obj||{},w2utils=function(){function a(a){var b=/^[-+]?[0-9]+$/;return b.test(a)}function b(a){return("number"==typeof a||"string"==typeof a&&""!==a)&&!isNaN(Number(a))}function c(a){var b=w2utils.settings,c=new RegExp("^"+(b.currencyPrefix?"\\"+b.currencyPrefix+"?":"")+"[-+]?[0-9]*[.]?[0-9]+"+(b.currencySuffix?"\\"+b.currencySuffix+"?":"")+"$","i");return"string"==typeof a&&(a=a.replace(new RegExp(b.groupSymbol,"g"),"")),"object"==typeof a||""===a?!1:c.test(a)}function d(a){var b=/^[a-fA-F0-9]+$/;return b.test(a)}function e(a){var b=/^[a-zA-Z0-9_-]+$/;return b.test(a)}function f(a){var b=/^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;return b.test(a)}function g(b,c,d){if(!b)return!1;var e,f,g,h="Invalid Date";if(null==c&&(c=w2utils.settings.date_format),"function"==typeof b.getUTCFullYear&&"function"==typeof b.getUTCMonth&&"function"==typeof b.getUTCDate)g=b.getUTCFullYear(),e=b.getUTCMonth(),f=b.getUTCDate();else if("function"==typeof b.getFullYear&&"function"==typeof b.getMonth&&"function"==typeof b.getDate)g=b.getFullYear(),e=b.getMonth(),f=b.getDate();else{if(b=String(b),RegExp("mon","ig").test(c)){c=c.replace(/month/gi,"m").replace(/mon/gi,"m").replace(/dd/gi,"d").replace(/[, ]/gi,"/").replace(/\/\//g,"/").toLowerCase(),b=b.replace(/[, ]/gi,"/").replace(/\/\//g,"/").toLowerCase();for(var i=0,j=w2utils.settings.fullmonths.length;j>i;i++){var k=w2utils.settings.fullmonths[i];b=b.replace(RegExp(k,"ig"),parseInt(i)+1).replace(RegExp(k.substr(0,3),"ig"),parseInt(i)+1)}}var l=b.replace(/-/g,"/").replace(/\./g,"/").toLowerCase().split("/"),m=c.replace(/-/g,"/").replace(/\./g,"/").toLowerCase();"mm/dd/yyyy"===m&&(e=l[0],f=l[1],g=l[2]),"m/d/yyyy"===m&&(e=l[0],f=l[1],g=l[2]),"dd/mm/yyyy"===m&&(e=l[1],f=l[0],g=l[2]),"d/m/yyyy"===m&&(e=l[1],f=l[0],g=l[2]),"yyyy/dd/mm"===m&&(e=l[2],f=l[1],g=l[0]),"yyyy/d/m"===m&&(e=l[2],f=l[1],g=l[0]),"yyyy/mm/dd"===m&&(e=l[1],f=l[2],g=l[0]),"yyyy/m/d"===m&&(e=l[1],f=l[2],g=l[0]),"mm/dd/yy"===m&&(e=l[0],f=l[1],g=l[2]),"m/d/yy"===m&&(e=l[0],f=l[1],g=parseInt(l[2])+1900),"dd/mm/yy"===m&&(e=l[1],f=l[0],g=parseInt(l[2])+1900),"d/m/yy"===m&&(e=l[1],f=l[0],g=parseInt(l[2])+1900),"yy/dd/mm"===m&&(e=l[2],f=l[1],g=parseInt(l[0])+1900),"yy/d/m"===m&&(e=l[2],f=l[1],g=parseInt(l[0])+1900),"yy/mm/dd"===m&&(e=l[1],f=l[2],g=parseInt(l[0])+1900),"yy/m/d"===m&&(e=l[1],f=l[2],g=parseInt(l[0])+1900)}return a(g)&&a(e)&&a(f)?(g=+g,e=+e,f=+f,h=new Date(g,e-1,f),null==e?!1:"Invalid Date"===h?!1:h.getMonth()+1!==e||h.getDate()!==f||h.getFullYear()!==g?!1:d===!0?h:!0):!1}function h(a,b){if(null==a)return!1;var c,d;a=String(a),a=a.toUpperCase(),d=a.indexOf("PM")>=0;var e=d||a.indexOf("AM")>=0;c=e?12:24,a=a.replace("AM","").replace("PM",""),a=$.trim(a);var f=a.split(":"),g=parseInt(f[0]||0),h=parseInt(f[1]||0);return e&&1===f.length||2===f.length?""===f[0]||0>g||g>c||!this.isInt(f[0])||f[0].length>2?!1:2===f.length&&(""===f[1]||0>h||h>59||!this.isInt(f[1])||2!==f[1].length)?!1:e||c!==g||0===h?e&&1===f.length&&0===g?!1:b===!0?(d&&(g+=12),{hours:g,minutes:h}):!0:!1:!1}function i(a){if(""===a||null==a)return"";var b=new Date(a);if(w2utils.isInt(a)&&(b=new Date(Number(a))),"Invalid Date"===b)return"";var c=new Date,d=(c.getTime()-b.getTime())/1e3,e="",f="";return 0>d?(e='future',f=""):60>d?(e=Math.floor(d),f="sec",0>d&&(e=0,f="sec")):3600>d?(e=Math.floor(d/60),f="min"):86400>d?(e=Math.floor(d/60/60),f="hour"):2592e3>d?(e=Math.floor(d/24/60/60),f="day"):31104e3>d?(e=Math.floor(d/30/24/60/60*10)/10,f="month"):d>=31104e3&&(e=Math.floor(d/12/30/24/60/60*10)/10,f="year"),e+" "+f+(e>1?"s":"")}function j(a){if(""===a||null==a)return"";var b=new Date(a);if(w2utils.isInt(a)&&(b=new Date(Number(a))),"Invalid Date"===b)return"";var c=w2utils.settings.shortmonths,d=new Date,e=new Date;e.setTime(e.getTime()-864e5);var f=c[b.getMonth()]+" "+b.getDate()+", "+b.getFullYear(),g=c[d.getMonth()]+" "+d.getDate()+", "+d.getFullYear(),h=c[e.getMonth()]+" "+e.getDate()+", "+e.getFullYear(),i=b.getHours()-(b.getHours()>12?12:0)+":"+(b.getMinutes()<10?"0":"")+b.getMinutes()+" "+(b.getHours()>=12?"pm":"am"),j=b.getHours()-(b.getHours()>12?12:0)+":"+(b.getMinutes()<10?"0":"")+b.getMinutes()+":"+(b.getSeconds()<10?"0":"")+b.getSeconds()+" "+(b.getHours()>=12?"pm":"am"),k=f;return f===g&&(k=i),f===h&&(k=w2utils.lang("Yesterday")),''+k+""}function k(a){if(!w2utils.isFloat(a)||""===a)return"";if(a=parseFloat(a),0===a)return 0;var b=["Bt","KB","MB","GB","TB"],c=parseInt(Math.floor(Math.log(a)/Math.log(1024)));return(Math.floor(a/Math.pow(1024,c)*10)/10).toFixed(0===c?0:1)+" "+b[c]}function l(a,b){var c="";return null==b&&(b=w2utils.settings.groupSymbol||","),(w2utils.isFloat(a)||w2utils.isInt(a)||w2utils.isMoney(a))&&(D=String(a).split("."),c=String(D[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1"+b),null!=D[1]&&(c+="."+D[1])),c}function m(a,b){w2utils.settings.shortmonths,w2utils.settings.fullmonths;if(b||(b=this.settings.date_format),""===a||null==a)return"";var c=new Date(a);if(w2utils.isInt(a)&&(c=new Date(Number(a))),"Invalid Date"===c)return"";var d=c.getFullYear(),e=c.getMonth(),f=c.getDate();return b.toLowerCase().replace("month",w2utils.settings.fullmonths[e]).replace("mon",w2utils.settings.shortmonths[e]).replace(/yyyy/g,d).replace(/yyy/g,d).replace(/yy/g,d>2e3?100+parseInt(String(d).substr(2)):String(d).substr(2)).replace(/(^|[^a-z$])y/g,"$1"+d).replace(/mm/g,(10>e+1?"0":"")+(e+1)).replace(/dd/g,(10>f?"0":"")+f).replace(/(^|[^a-z$])m/g,"$1"+(e+1)).replace(/(^|[^a-z$])d/g,"$1"+f)}function n(a,b){w2utils.settings.shortmonths,w2utils.settings.fullmonths;if(b||(b="h12"===this.settings.time_format?"hh:mi pm":"h24:mi"),""===a||null==a)return"";var c=new Date(a);if(w2utils.isInt(a)&&(c=new Date(Number(a))),w2utils.isTime(a)){var d=w2utils.isTime(a,!0);c=new Date,c.setHours(d.hours),c.setMinutes(d.minutes)}if("Invalid Date"===c)return"";var e="am",f=c.getHours(),g=c.getHours(),h=c.getMinutes(),i=c.getSeconds();return 10>h&&(h="0"+h),10>i&&(i="0"+i),(-1!==b.indexOf("am")||-1!==b.indexOf("pm"))&&(f>=12&&(e="pm"),f>12&&(f-=12)),b.toLowerCase().replace("am",e).replace("pm",e).replace("hh",f).replace("h24",g).replace("mm",h).replace("mi",h).replace("ss",i).replace(/(^|[^a-z$])h/g,"$1"+f).replace(/(^|[^a-z$])m/g,"$1"+h).replace(/(^|[^a-z$])s/g,"$1"+i)}function o(a,b){var c;return c="string"!=typeof b?[this.settings.date_format,this.settings.time_format]:b.split("|"),this.formatDate(a,c[0])+" "+this.formatTime(a,c[1])}function p(a){if(null===a)return a;switch(typeof a){case"number":break;case"string":a=$.trim(String(a).replace(/(<([^>]+)>)/gi,""));break;case"object":for(var b in a)a[b]=this.stripTags(a[b])}return a}function q(a){if(null===a)return a;switch(typeof a){case"number":break;case"string":a=String(a).replace(/&/g,"&").replace(/>/g,">").replace(/\|\/? {}\\])/g,"\\$1")}function s(a){function b(a){for(var a=String(a).replace(/\r\n/g,"\n"),b="",c=0;cd?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b}var c,d,e,f,g,h,i,j="",k=0,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";for(a=b(a);k>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,isNaN(d)?h=i=64:isNaN(e)&&(i=64),j=j+l.charAt(f)+l.charAt(g)+l.charAt(h)+l.charAt(i);return j}function t(a){function b(a){for(var b,c,d="",e=0,f=0;ef?(d+=String.fromCharCode(f),e++):f>191&&224>f?(b=a.charCodeAt(e+1),d+=String.fromCharCode((31&f)<<6|63&b),e+=2):(b=a.charCodeAt(e+1),c=a.charCodeAt(e+2),d+=String.fromCharCode((15&f)<<12|(63&b)<<6|63&c),e+=3);return d}var c,d,e,f,g,h,i,j="",k=0,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(c),64!==h&&(j+=String.fromCharCode(d)),64!==i&&(j+=String.fromCharCode(e));return j=b(j)}function u(a,b,c,d){function e(a,b,c){var d=!!window.webkitURL;return d||"undefined"==typeof c||(b=c),";"+a+": "+b+"; -webkit-"+a+": "+b+"; -moz-"+a+": "+b+"; -ms-"+a+": "+b+"; -o-"+a+": "+b+";"}var f=$(a).width(),g=$(a).height(),h=.5;if(!a||!b)return void console.log("ERROR: Cannot do transition when one of the divs is null");switch(a.parentNode.style.cssText+=e("perspective","700px")+"; overflow: hidden;",a.style.cssText+="; position: absolute; z-index: 1019; "+e("backface-visibility","hidden"),b.style.cssText+="; position: absolute; z-index: 1020; "+e("backface-visibility","hidden"),c){case"slide-left":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d("+f+"px, 0, 0)","translate("+f+"px, 0)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+";"+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),a.style.cssText+=e("transition",h+"s")+";"+e("transform","translate3d(-"+f+"px, 0, 0)","translate(-"+f+"px, 0)")},1);break;case"slide-right":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(-"+f+"px, 0, 0)","translate(-"+f+"px, 0)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0px, 0, 0)","translate(0px, 0)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d("+f+"px, 0, 0)","translate("+f+"px, 0)")},1);break;case"slide-down":a.style.cssText+="overflow: hidden; z-index: 1; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; z-index: 0; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, "+g+"px, 0)","translate(0, "+g+"px)")},1);break;case"slide-up":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, "+g+"px, 0)","translate(0, "+g+"px)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")},1);break;case"flip-left":a.style.cssText+="overflow: hidden; "+e("transform","rotateY(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateY(-180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(180deg)")},1);break;case"flip-right":a.style.cssText+="overflow: hidden; "+e("transform","rotateY(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateY(180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateY(-180deg)")},1);break;case"flip-down":a.style.cssText+="overflow: hidden; "+e("transform","rotateX(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateX(180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(-180deg)")},1);break;case"flip-up":a.style.cssText+="overflow: hidden; "+e("transform","rotateX(0deg)"),b.style.cssText+="overflow: hidden; "+e("transform","rotateX(-180deg)"),$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(0deg)"),a.style.cssText+=e("transition",h+"s")+"; "+e("transform","rotateX(180deg)")},1);break;case"pop-in":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; "+e("transform","scale(.8)")+"; opacity: 0;",$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; "+e("transform","scale(1)")+"; opacity: 1;",a.style.cssText+=e("transition",h+"s")+";"},1);break;case"pop-out":a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; "+e("transform","scale(1)")+"; opacity: 1;",b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; opacity: 0;",$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; opacity: 1;",a.style.cssText+=e("transition",h+"s")+"; "+e("transform","scale(1.7)")+"; opacity: 0;"},1);break;default:a.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)"),b.style.cssText+="overflow: hidden; "+e("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; opacity: 0;",$(b).show(),window.setTimeout(function(){b.style.cssText+=e("transition",h+"s")+"; opacity: 1;",a.style.cssText+=e("transition",h+"s")},1)}setTimeout(function(){"slide-down"===c&&($(a).css("z-index","1019"),$(b).css("z-index","1020")),b&&$(b).css({opacity:"1","-webkit-transition":"","-moz-transition":"","-ms-transition":"","-o-transition":"","-webkit-transform":"","-moz-transform":"","-ms-transform":"","-o-transform":"","-webkit-backface-visibility":"","-moz-backface-visibility":"","-ms-backface-visibility":"","-o-backface-visibility":""}),a&&($(a).css({opacity:"1","-webkit-transition":"","-moz-transition":"","-ms-transition":"","-o-transition":"","-webkit-transform":"","-moz-transform":"","-ms-transform":"","-o-transform":"","-webkit-backface-visibility":"","-moz-backface-visibility":"","-ms-backface-visibility":"","-o-backface-visibility":""}),a.parentNode&&$(a.parentNode).css({"-webkit-perspective":"","-moz-perspective":"","-ms-perspective":"","-o-perspective":""})),"function"==typeof d&&d()},1e3*h)}function v(a,b,c){var d={};"object"==typeof b?d=b:(d.msg=b,d.spinner=c),d.msg||0===d.msg||(d.msg=""),w2utils.unlock(a),$(a).prepend('
      ');var e=$(a).find(".w2ui-lock"),f=$(a).find(".w2ui-lock-msg");d.msg||f.css({"background-color":"transparent",border:"0px"}),d.spinner===!0&&(d.msg='
      "+d.msg),null!=d.opacity&&e.css("opacity",d.opacity),"function"==typeof e.fadeIn?(e.fadeIn(200),f.html(d.msg).fadeIn(200)):(e.show(),f.html(d.msg).show(0)),$().w2tag()}function w(a){$(a).find(".w2ui-lock").remove(),$(a).find(".w2ui-lock-msg").remove()}function x(a,b){var c=$(a),d={left:parseInt(c.css("border-left-width"))||0,right:parseInt(c.css("border-right-width"))||0,top:parseInt(c.css("border-top-width"))||0,bottom:parseInt(c.css("border-bottom-width"))||0},e={left:parseInt(c.css("margin-left"))||0,right:parseInt(c.css("margin-right"))||0,top:parseInt(c.css("margin-top"))||0,bottom:parseInt(c.css("margin-bottom"))||0},f={left:parseInt(c.css("padding-left"))||0,right:parseInt(c.css("padding-right"))||0,top:parseInt(c.css("padding-top"))||0,bottom:parseInt(c.css("padding-bottom"))||0};switch(b){case"top":return d.top+e.top+f.top;case"bottom":return d.bottom+e.bottom+f.bottom;case"left":return d.left+e.left+f.left;case"right":return d.right+e.right+f.right;case"width":return d.left+d.right+e.left+e.right+f.left+f.right+parseInt(c.width());case"height":return d.top+d.bottom+e.top+e.bottom+f.top+f.bottom+parseInt(c.height());case"+width":return d.left+d.right+e.left+e.right+f.left+f.right;case"+height":return d.top+d.bottom+e.top+e.bottom+f.top+f.bottom}return 0}function y(a){var b=this.settings.phrases[a];return null==b?a:b}function z(a){a||(a="en-us"),5===a.length&&(a="locale/"+a+".json"),$.ajax({url:a,type:"GET",dataType:"JSON",async:!1,cache:!1,success:function(a){w2utils.settings=$.extend(!0,w2utils.settings,a);var b=w2obj.grid.prototype;for(var c in b.buttons)b.buttons[c].caption=w2utils.lang(b.buttons[c].caption),b.buttons[c].hint=w2utils.lang(b.buttons[c].hint);b.msgDelete=w2utils.lang(b.msgDelete),b.msgNotJSON=w2utils.lang(b.msgNotJSON),b.msgRefresh=w2utils.lang(b.msgRefresh)},error:function(){console.log("ERROR: Cannot load locale "+a)}})}function A(){if(D.scrollBarSize)return D.scrollBarSize;var a='
      1
      ';return $("body").append(a),D.scrollBarSize=100-$("#_scrollbar_width > div").width(),$("#_scrollbar_width").remove(),String(navigator.userAgent).indexOf("MSIE")>=0&&(D.scrollBarSize=D.scrollBarSize/2),D.scrollBarSize}function B(a,b){return a&&"undefined"!=typeof a.name?"undefined"!=typeof w2ui[a.name]?(console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+a.name+")."),!1):w2utils.isAlphaNumeric(a.name)?!0:(console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '),!1):(console.log('ERROR: The parameter "name" is required but not supplied in $().'+b+"()."),!1)}function C(a,b,c,d){$.isArray(b)||(b=[b]);for(var e=0;ed;d++){var f=this.handlers[d];(f.event.type!==a.type&&"*"!==a.type||f.event.target!==a.target&&null!==a.target||f.handler!==b&&null!==b)&&c.push(f)}this.handlers=c},trigger:function(a){var a=$.extend({type:null,phase:"before",target:null},a,{isStopped:!1,isCancelled:!1,preventDefault:function(){this.isCancelled=!0},stopPropagation:function(){this.isStopped=!0}});"before"===a.phase&&(a.onComplete=null);var b,c,d;null==a.target&&(a.target=null);for(var e=this.handlers.length-1;e>=0;e--){var f=this.handlers[e];if(!(f.event.type!==a.type&&"*"!==f.event.type||f.event.target!==a.target&&null!==f.event.target||f.event.execute!==a.phase&&"*"!==f.event.execute&&"*"!==f.event.phase)&&(a=$.extend({},f.event,a),b=[],d=RegExp(/\((.*?)\)/).exec(f.handler),d&&(b=d[1].split(/\s*,\s*/)),2===b.length?f.handler.call(this,a.target,a):f.handler.call(this,a),a.isStopped===!0||a.stop===!0))return a}var g="on"+a.type.substr(0,1).toUpperCase()+a.type.substr(1);return"before"===a.phase&&"function"==typeof this[g]&&(c=this[g],b=[],d=RegExp(/\((.*?)\)/).exec(c),d&&(b=d[1].split(/\s*,\s*/)),2===b.length?c.call(this,a.target,a):c.call(this,a),a.isStopped===!0||a.stop===!0)?a:null!=a.object&&"before"===a.phase&&"function"==typeof a.object[g]&&(c=a.object[g],b=[],d=RegExp(/\((.*?)\)/).exec(c),d&&(b=d[1].split(/\s*,\s*/)),2===b.length?c.call(this,a.target,a):c.call(this,a),a.isStopped===!0||a.stop===!0)?a:("after"===a.phase&&"function"==typeof a.onComplete&&a.onComplete.call(this,a),a)}},w2utils.keyboard=function(a){function b(){$(document).on("keydown",c),$(document).on("mousedown",d)}function c(a){var b=a.target.tagName;-1===$.inArray(b,["INPUT","SELECT","TEXTAREA"])&&"true"!==$(a.target).prop("contenteditable")&&h&&w2ui[h]&&"function"==typeof w2ui[h].keydown&&w2ui[h].keydown.call(w2ui[h],a)}function d(a){var b=(a.target.tagName,$(a.target).parents(".w2ui-reset"));if(b.length>0){var c=b.attr("name");w2ui[c]&&w2ui[c].keyboard&&(h=c)}}function e(a){return"undefined"!=typeof a&&(h=a),h}function f(){h=null}function g(){}var h=null;return a.active=e,a.clear=f,a.register=g,b(),a}({}),function(){$.fn.w2render=function(a){$(this).length>0&&("string"==typeof a&&w2ui[a]&&w2ui[a].render($(this)[0]),"object"==typeof a&&a.render($(this)[0]))},$.fn.w2destroy=function(a){!a&&this.length>0&&(a=this.attr("name")),"string"==typeof a&&w2ui[a]&&w2ui[a].destroy(),"object"==typeof a&&a.destroy()},$.fn.w2marker=function(a){return $(this).each(""===a||null==a?function(a,b){b.innerHTML=b.innerHTML.replace(/\(.*)\<\/span\>/gi,"$1")}:function(b,c){function d(a){return''+a+""}"string"==typeof a&&(a=[a]),c.innerHTML=c.innerHTML.replace(/\(.*)\<\/span\>/gi,"$1");for(var e in a){var f=a[e];"string"!=typeof f&&(f=String(f)),f=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&").replace(/&/g,"&").replace(//g,"<");var g=new RegExp(f+"(?!([^<]+)?>)","gi");c.innerHTML=c.innerHTML.replace(g,d)}})},$.fn.w2tag=function(a,b){return $.isPlainObject(b)||(b={}),$.isPlainObject(b.css)||(b.css={}),"undefined"==typeof b["class"]&&(b["class"]=""),0===$(this).length?void $(".w2ui-tag").each(function(a,b){var c=$(b).data("options");null==c&&(c={}),$($(b).data("taged-el")).removeClass(c["class"]),clearInterval($(b).data("timer")),$(b).remove()}):$(this).each(function(c,d){function e(){$tag=$("#w2ui-tag-"+g),$tag.length<=0||(clearInterval($tag.data("timer")),$tag.remove(),$(d).off("keypress",e).removeClass(b["class"]),$(d).length>0&&($(d)[0].style.cssText=i),"function"==typeof b.onHide&&b.onHide())}var f=d.id,g=w2utils.escapeId(d.id);if(""===a||null==a)$("#w2ui-tag-"+g).css("opacity",0),setTimeout(function(){clearInterval($("#w2ui-tag-"+g).data("timer")),$("#w2ui-tag-"+g).remove()},300);else{clearInterval($("#w2ui-tag-"+g).data("timer")),$("#w2ui-tag-"+g).remove(),$("body").append('
      0?"w2ui-tag-popup":"")+'" style="">
      ');var h=setInterval(function(){return 0===$(d).length||0===$(d).offset().left&&0===$(d).offset().top?(clearInterval($("#w2ui-tag-"+g).data("timer")),void e()):void($("#w2ui-tag-"+g).data("position")!==$(d).offset().left+d.offsetWidth+"x"+$(d).offset().top&&$("#w2ui-tag-"+g).css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s",left:$(d).offset().left+d.offsetWidth+"px",top:$(d).offset().top+"px"}).data("position",$(d).offset().left+d.offsetWidth+"x"+$(d).offset().top))},100);setTimeout(function(){$(d).offset()&&($("#w2ui-tag-"+g).css({opacity:"1",left:$(d).offset().left+d.offsetWidth+"px",top:$(d).offset().top+"px"}).html('
      '+a+"
      ").data("text",a).data("taged-el",d).data("options",b).data("position",$(d).offset().left+d.offsetWidth+"x"+$(d).offset().top).data("timer",h),$(d).off("keypress",e).on("keypress",e).off("change",e).on("change",e).css(b.css).addClass(b["class"]),"function"==typeof b.onShow&&b.onShow())},1);var i="";$(d).length>0&&(i=$(d)[0].style.cssText)}})},$.fn.w2overlay=function(a,b){function c(){var a=$("#w2ui-overlay"+g);if(a.data("element")===f[0]&&0!==a.length){var b=$(f).offset().left+"x"+$(f).offset().top;a.data("position")!==b?d():setTimeout(c,250)}}function d(){var a=$("#w2ui-overlay"+g);if(a.data("keepOpen")===!0)return void a.removeData("keepOpen");var c;"function"==typeof b.onHide&&(c=b.onHide()),c!==!1&&(a.remove(),$(document).off("click",d),clearInterval(a.data("timer")))}function e(){var a=$("#w2ui-overlay"+g),c=a.find(" > div");if(a.length>0){c.height("auto").width("auto");var d=!1,h=!1,i=c.height(),j=c.width();switch(b.width&&b.widthj&&(j=30),b.tmp.contentHeight&&(i=b.tmp.contentHeight,c.height(i),setTimeout(function(){c.height()>c.find("div.menu > table").height()&&c.find("div.menu").css("overflow-y","hidden")},1),setTimeout(function(){c.find("div.menu").css("overflow-y","auto")},10)),b.tmp.contentWidth&&(j=b.tmp.contentWidth,c.width(j),setTimeout(function(){c.width()>c.find("div.menu > table").width()&&c.find("div.menu").css("overflow-x","hidden")},1),setTimeout(function(){c.find("div.menu").css("overflow-y","auto")},10)),b.align){case"both":b.left=17,0===b.width&&(b.width=w2utils.getSize($(f),"width"));break;case"left":b.left=17;break;case"right":b.tipLeft=j-45,b.left=w2utils.getSize($(f),"width")-j+10}var k=(j-17)/2,l=b.left,m=b.width,n=b.tipLeft;m=30!==j||m?b.width?b.width:"auto":30,25>k&&(l=25-k,n=Math.floor(k)),a.css({top:f.offset().top+w2utils.getSize(f,"height")+b.top+7+"px",left:(f.offset().left>25?f.offset().left:25)+l+"px","min-width":m,"min-height":b.height?b.height:"auto"});var o=window.innerHeight+$(document).scrollTop()-c.offset().top-7,p=window.innerWidth+$(document).scrollLeft()-c.offset().left-7;o>-50&&210>o||b.openAbove===!0?(o=c.offset().top-$(document).scrollTop()-7,b.maxHeight&&o>b.maxHeight&&(o=b.maxHeight),i>o&&(h=!0,c.height(o).width(j).css({"overflow-y":"auto"}),i=o),a.css("top",$(f).offset().top-i-24+b.top+"px"),a.find(">style").html("#w2ui-overlay"+g+":before { display: none; margin-left: "+parseInt(n)+"px; }#w2ui-overlay"+g+":after { display: block; margin-left: "+parseInt(n)+"px; }")):(b.maxHeight&&o>b.maxHeight&&(o=b.maxHeight),i>o&&(h=!0,c.height(o).width(j).css({"overflow-y":"auto"})),a.find(">style").html("#w2ui-overlay"+g+":before { display: block; margin-left: "+parseInt(n)+"px; }#w2ui-overlay"+g+":after { display: none; margin-left: "+parseInt(n)+"px; }")),j=c.width(),p=window.innerWidth+$(document).scrollLeft()-c.offset().left-7,b.maxWidth&&p>b.maxWidth&&(p=b.maxWidth),j>p&&"both"!==b.align&&(b.align="right",setTimeout(function(){e()},1)),h&&d&&c.width(j+w2utils.scrollBarSize()+2)}}var f=this,g="",h={name:null,align:"none",left:0,top:0,tipLeft:30,width:0,height:0,maxWidth:null,maxHeight:null,style:"","class":"",onShow:null,onHide:null,openAbove:!1,tmp:{}};$.isPlainObject(b)||(b={}),b=$.extend({},h,b),b.name&&(g="-"+b.name);var i;if(0===this.length||""===a||null==a)return $("#w2ui-overlay"+g).length>0?(i=$("#w2ui-overlay"+g)[0].hide,"function"==typeof i&&i()):$("#w2ui-overlay"+g).remove(),$(this);$("#w2ui-overlay"+g).length>0&&(i=$("#w2ui-overlay"+g)[0].hide,$(document).off("click",i),"function"==typeof i&&i()),$("body").append('');var j=$("#w2ui-overlay"+g),k=j.find(" > div");k.html(a);var l=k.css("background-color");return null!=l&&"rgba(0, 0, 0, 0)"!==l&&"transparent"!==l&&j.css("background-color",l),j.data("element",f.length>0?f[0]:null).data("options",b).data("position",$(f).offset().left+"x"+$(f).offset().top).fadeIn("fast").on("mousedown",function(a){$("#w2ui-overlay"+g).data("keepOpen",!0),-1===["INPUT","TEXTAREA","SELECT"].indexOf(a.target.tagName)&&a.preventDefault()}),j[0].hide=d,j[0].resize=e,e(),setTimeout(function(){e(),$(document).off("click",d).on("click",d),"function"==typeof b.onShow&&b.onShow()},10),c(),$(this)},$.fn.w2menu=function(a,b){function c(){setTimeout(function(){$("#w2ui-overlay"+h+" tr.w2ui-selected").removeClass("w2ui-selected");var a=$("#w2ui-overlay"+h+" tr[index="+b.index+"]"),c=$("#w2ui-overlay"+h+" div.menu").scrollTop();if(a.addClass("w2ui-selected"),b.tmp&&(b.tmp.contentHeight=$("#w2ui-overlay"+h+" table").height()+(b.search?50:10)),b.tmp&&(b.tmp.contentWidth=$("#w2ui-overlay"+h+" table").width()),$("#w2ui-overlay"+h)[0].resize(),a.length>0){var d=a[0].offsetTop-5,e=$("#w2ui-overlay"+h+" div.menu"),f=e.height();$("#w2ui-overlay"+h+" div.menu").scrollTop(c),(c>d||d+a.height()>c+f)&&$("#w2ui-overlay"+h+" div.menu").animate({scrollTop:d-(f-2*a.height())/2},200,"linear")}},1)}function d(a){var d=this.value,e=a.keyCode,f=!1;switch(e){case 13:$("#w2ui-overlay"+h).remove(),$.fn.w2menuHandler(a,b.index);break;case 9:case 27:$("#w2ui-overlay"+h).remove(),$.fn.w2menuHandler(a,-1);break;case 38:for(b.index=w2utils.isInt(b.index)?parseInt(b.index):0,b.index--;b.index>0&&b.items[b.index].hidden;)b.index--;if(0===b.index&&b.items[b.index].hidden)for(;b.items[b.index]&&b.items[b.index].hidden;)b.index++;b.index<0&&(b.index=0),f=!0;break;case 40:for(b.index=w2utils.isInt(b.index)?parseInt(b.index):0,b.index++;b.index=b.items.length&&(b.index=b.items.length-1),f=!0}if(!f){var i=0;for(var j in b.items){var k=b.items[j],l="",m="";-1!==["is","begins with"].indexOf(b.match)&&(l="^"),-1!==["is","ends with"].indexOf(b.match)&&(m="$");try{var n=new RegExp(l+d+m,"i");k.hidden=n.test(k.text)||"..."===k.text?!1:!0,b.applyFilter!==!0&&(k.hidden=!1)}catch(o){}"enum"===g.type&&-1!==$.inArray(k.id,ids)&&(k.hidden=!0),k.hidden!==!0&&i++}for(b.index=0;b.index=i&&(b.index=-1)}$(g).w2menu("refresh",b),c()}function e(){if(b.spinner)return'
      Loading...
      ';for(var a=0,c='',d=null,e=null,f=0;f
      '),e&&(i='
      '),"undefined"==typeof j||""===j||/^-+$/.test(j))c+='';else{var k=a%2===0?"w2ui-item-even":"w2ui-item-odd";b.altRows!==!0&&(k=""),c+='"+i+" ",a++ +}}b.items[f]=g}return 0===a&&(c+='"),c+="
      "+j+"
      '+b.msgNoItems+"
      "}var f={index:null,items:[],render:null,msgNoItems:"No items",onSelect:null,tmp:{}},g=this,h="";if("refresh"!==a){1===arguments.length?b=a:b.items=a,"object"!=typeof b&&(b={}),b=$.extend({},f,b),$.fn.w2menuOptions=b,b.name&&(h="-"+b.name),"function"==typeof b.select&&"function"!=typeof b.onSelect&&(b.onSelect=b.select),"function"==typeof b.onRender&&"function"!=typeof b.render&&(b.render=b.onRender),$.fn.w2menuHandler=function(a,c){"function"==typeof b.onSelect&&setTimeout(function(){b.onSelect({index:c,item:b.items[c],originalEvent:a})},10)};var i="";if(b.search){i+='
      ',b.style+=";background-color: #ECECEC",b.index=0;for(var j in b.items)b.items[j].hidden=!1}i+='";var k=$(this).w2overlay(i,b);return setTimeout(function(){$("#w2ui-overlay"+h+" #menu-search").on("keyup",d).on("keydown",function(a){9===a.keyCode&&(a.stopPropagation(),a.preventDefault())})},200),c(),k}if($("#w2ui-overlay"+h).length>0){b=$.extend($.fn.w2menuOptions,b);var l=$("#w2ui-overlay"+h+" div.menu").scrollTop();$("#w2ui-overlay"+h+" div.menu").html(e()),$("#w2ui-overlay"+h+" div.menu").scrollTop(l),c()}else $(this).w2menu(b)}}(),function(a){var b=function(b){this.el=null,this.helpers={},this.type=b.type||"text",this.options=a.extend(!0,{},b),this.onSearch=b.onSearch||null,this.onRequest=b.onRequest||null,this.onLoad=b.onLoad||null,this.onError=b.onError||null,this.onClick=b.onClick||null,this.onAdd=b.onAdd||null,this.onNew=b.onNew||null,this.onRemove=b.onRemove||null,this.onMouseOver=b.onMouseOver||null,this.onMouseOut=b.onMouseOut||null,this.onIconClick=b.onIconClick||null,this.tmp={},delete this.options.type,delete this.options.onSearch,delete this.options.onRequest,delete this.options.onLoad,delete this.options.onError,delete this.options.onClick,delete this.options.onMouseOver,delete this.options.onMouseOut,delete this.options.onIconClick,a.extend(!0,this,w2obj.field)};a.fn.w2field=function(c,d){if(0!=this.length)return"string"==typeof c&&"object"==typeof d&&(c=a.extend(!0,{},d,{type:c})),"string"==typeof c&&"undefined"==typeof d&&(c={type:c}),c.type=String(c.type).toLowerCase(),this.each(function(d,e){var f=a(e).data("w2field");if("undefined"==typeof f){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}if(f.clear(),"clear"!=c.type){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}});var e=b.prototype;return e[c]?e[c].apply(e,Array.prototype.slice.call(arguments,1)):void 0},b.prototype={custom:{},pallete:[["000000","444444","666666","999999","CCCCCC","EEEEEE","F3F3F3","FFFFFF"],["FF011B","FF9838","FFFD59","01FD55","00FFFE","0424F3","9B24F4","FF21F5"],["F4CCCC","FCE5CD","FFF2CC","D9EAD3","D0E0E3","CFE2F3","D9D1E9","EAD1DC"],["EA9899","F9CB9C","FEE599","B6D7A8","A2C4C9","9FC5E8","B4A7D6","D5A6BD"],["E06666","F6B26B","FED966","93C47D","76A5AF","6FA8DC","8E7CC3","C27BA0"],["CC0814","E69138","F1C232","6AA84F","45818E","3D85C6","674EA7","A54D79"],["99050C","B45F17","BF901F","37761D","124F5C","0A5394","351C75","741B47"],["660205","783F0B","7F6011","274E12","0C343D","063762","20124D","4C1030"]],addType:function(a,b){return a=String(a).toLowerCase(),this.custom[a]=b,!0},removeType:function(a){return a=String(a).toLowerCase(),this.custom[a]?(delete this.custom[a],!0):!1},init:function(){var b,c=this,d=this.options;if("function"==typeof this.custom[this.type])return void this.custom[this.type].call(this,d);if(-1==["INPUT","TEXTAREA"].indexOf(this.el.tagName))return void console.log("ERROR: w2field could only be applied to INPUT or TEXTAREA.",this.el);switch(this.type){case"text":case"int":case"float":case"money":case"currency":case"percent":case"alphanumeric":case"hex":b={min:null,max:null,step:1,placeholder:"",autoFormat:!0,currencyPrefix:w2utils.settings.currencyPrefix,currencySuffix:w2utils.settings.currencySuffix,currencyPrecision:w2utils.settings.currencyPrecision,groupSymbol:w2utils.settings.groupSymbol,arrows:!1,keyboard:!0,precision:null,silent:!0,prefix:"",suffix:""},this.options=a.extend(!0,{},b,d),d=this.options,d.numberRE=new RegExp("["+d.groupSymbol+"]","g"),d.moneyRE=new RegExp("["+d.currencyPrefix+d.currencySuffix+d.groupSymbol+"]","g"),d.percentRE=new RegExp("["+d.groupSymbol+"%]","g"),-1!=["text","alphanumeric","hex"].indexOf(this.type)&&(d.arrows=!1,d.keyboard=!1),this.addPrefix(),this.addSuffix(),a(this.el).attr("placeholder",d.placeholder);break;case"color":b={prefix:"#",suffix:'
       
      ',placeholder:"",arrows:!1,keyboard:!1},a.extend(d,b),this.addPrefix(),this.addSuffix(),a(this.el).attr("maxlength",6),""!=a(this.el).val()&&setTimeout(function(){a(c.el).change()},1),a(this.el).attr("placeholder",d.placeholder);break;case"date":b={format:w2utils.settings.date_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:"",blocked:{},colored:{}},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:d.format);break;case"time":b={format:w2utils.settings.time_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:""},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:"h12"==d.format?"hh:mi pm":"hh:mi");break;case"datetime":break;case"list":case"combo":if(b={items:[],selected:{},placeholder:"",url:null,postData:{},minLength:1,cacheMax:250,maxDropHeight:350,match:"begins",silent:!0,icon:null,iconStyle:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onIconClick:null,renderDrop:null,prefix:"",suffix:"",openOnFocus:!1,markSearch:!1},"list"==this.type&&(b.openOnFocus=!0,b.suffix='
      ',a(this.el).addClass("w2ui-select"),!a.isPlainObject(d.selected)))for(var e in d.items){var f=d.items[e];if(f&&f.id==d.selected){d.selected=a.extend(!0,{},f);break}}d=a.extend({},b,d,{align:"both",altRows:!0}),d.items=this.normMenu(d.items),this.options=d,a.isPlainObject(d.selected)||(d.selected={}),a(this.el).data("selected",d.selected),d.url&&this.request(0),d.icon&&(d.prefix=''),"list"==this.type&&this.addFocus(),this.addPrefix(),this.addSuffix(),setTimeout(function(){c.refresh()},10),a(this.el).attr("placeholder",d.placeholder).attr("autocomplete","off"),"undefined"!=typeof d.selected.text&&a(this.el).val(d.selected.text);break;case"enum":b={items:[],selected:[],placeholder:"",max:0,url:null,postData:{},minLength:1,cacheMax:250,maxWidth:250,maxHeight:350,maxDropHeight:350,match:"contains",silent:!0,openOnFocus:!1,markSearch:!0,renderDrop:null,renderItem:null,style:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onClick:null,onAdd:null,onNew:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",suffix:"",altRows:!0}),d.items=this.normMenu(d.items),d.selected=this.normMenu(d.selected),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),d.url&&this.request(0),this.addSuffix(),this.addMulti();break;case"file":b={selected:[],placeholder:w2utils.lang("Attach files by dragging and dropping or Click to Select"),max:0,maxSize:0,maxFileSize:0,maxWidth:250,maxHeight:350,maxDropHeight:350,silent:!0,renderItem:null,style:"",onClick:null,onAdd:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",altRows:!0}),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),this.addMulti()}this.tmp={onChange:function(a){c.change.call(c,a)},onClick:function(a){c.click.call(c,a)},onFocus:function(a){c.focus.call(c,a)},onBlur:function(a){c.blur.call(c,a)},onKeydown:function(a){c.keyDown.call(c,a)},onKeyup:function(a){c.keyUp.call(c,a)},onKeypress:function(a){c.keyPress.call(c,a)}},a(this.el).addClass("w2field").data("w2field",this).on("change",this.tmp.onChange).on("click",this.tmp.onClick).on("focus",this.tmp.onFocus).on("blur",this.tmp.onBlur).on("keydown",this.tmp.onKeydown).on("keyup",this.tmp.onKeyup).on("keypress",this.tmp.onKeypress).css({"box-sizing":"border-box","-webkit-box-sizing":"border-box","-moz-box-sizing":"border-box","-ms-box-sizing":"border-box","-o-box-sizing":"border-box"}),this.change(a.Event("change"))},clear:function(){var b=this.options;-1!=["money","currency"].indexOf(this.type)&&a(this.el).val(a(this.el).val().replace(b.moneyRE,"")),"percent"==this.type&&a(this.el).val(a(this.el).val().replace(/%/g,"")),"color"==this.type&&a(this.el).removeAttr("maxlength"),"list"==this.type&&a(this.el).removeClass("w2ui-select"),this.type="clear";var c=a(this.el).data("tmp");if(this.tmp){"undefined"!=typeof c&&(c&&c["old-padding-left"]&&a(this.el).css("padding-left",c["old-padding-left"]),c&&c["old-padding-right"]&&a(this.el).css("padding-right",c["old-padding-right"])),a(this.el).val(this.clean(a(this.el).val())).removeClass("w2field").removeData().off("change",this.tmp.onChange).off("click",this.tmp.onClick).off("focus",this.tmp.onFocus).off("blur",this.tmp.onBlur).off("keydown",this.tmp.onKeydown).off("keyup",this.tmp.onKeyup).off("keypress",this.tmp.onKeypress);for(var d in this.helpers)a(this.helpers[d]).remove();this.helpers={}}},refresh:function(){var b=this,c=this.options,d=a(this.el).data("selected"),e=(new Date).getTime();if(-1!=["list"].indexOf(this.type)&&(a(b.el).parent().css("white-space","nowrap"),b.helpers.prefix&&b.helpers.prefix.hide(),setTimeout(function(){var c=b.helpers.focus.find("input");""==a(c).val()?(a(c).css("opacity",0).prev().css("opacity",0),a(b.el).val(d&&null!=d.text?d.text:""),a(b.el).attr("placeholder",a(b.el).attr("_placeholder")),a.isEmptyObject(d)?b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide():b.helpers&&b.helpers.prefix&&b.helpers.prefix.show()):(a(c).css("opacity",1).prev().css("opacity",1),b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide(),a(b.el).val(""),a(b.el).attr("_placeholder",a(b.el).attr("placeholder")).removeAttr("placeholder"))},1)),-1!=["enum","file"].indexOf(this.type)){var f="";for(var g in d){var h=d[g],i="";i="function"==typeof c.renderItem?c.renderItem(h,g,'
        
      '):'
        
      '+("enum"==b.type?h.text:h.name+' - '+w2utils.size(h.size)+""),f+='
    • '+i+"
    • "}var j=b.helpers.multi,k=j.find("ul");if(j.attr("style",j.attr("style")+";"+c.style),a(b.el).attr("readonly")?j.addClass("w2ui-readonly"):j.removeClass("w2ui-readonly"),j.find(".w2ui-enum-placeholder").remove(),k.find("li").not("li.nomouse").remove(),""!=f)k.prepend(f);else if("undefined"!=typeof c.placeholder){var l="padding-top: "+a(this.el).css("padding-top")+";padding-left: "+a(this.el).css("padding-left")+"; box-sizing: "+a(this.el).css("box-sizing")+"; line-height: "+a(this.el).css("line-height")+"; font-size: "+a(this.el).css("font-size")+"; font-family: "+a(this.el).css("font-family")+"; ";j.prepend('
      '+c.placeholder+"
      ")}j.find("li").data("mouse","out").on("click",function(c){var e=d[a(c.target).attr("index")];if(!a(c.target).hasClass("nomouse")){c.stopPropagation();var f=b.trigger({phase:"before",type:"click",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled!==!0){if(a(c.target).hasClass("w2ui-list-remove")){if(a(b.el).attr("readonly"))return;var f=b.trigger({phase:"before",type:"remove",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled===!0)return;a().w2overlay(),d.splice(a(c.target).attr("index"),1),a(b.el).trigger("change"),a(c.target).parent().fadeOut("fast"),setTimeout(function(){b.refresh(),b.trigger(a.extend(f,{phase:"after"}))},300)}if("file"==b.type&&!a(c.target).hasClass("w2ui-list-remove")){var g="";/image/i.test(e.type)&&(g='
      ');var h='style="padding: 3px; text-align: right; color: #777;"',i='style="padding: 3px"';g+='
      Name:"+e.name+"
      Size:"+w2utils.size(e.size)+"
      Type: '+e.type+"
      Modified:"+w2utils.date(e.modified)+"
      ",a(c.target).w2overlay(g)}b.trigger(a.extend(f,{phase:"after"}))}}}).on("mouseover",function(c){var e=c.target;if("LI"!=e.tagName&&(e=e.parentNode),!a(e).hasClass("nomouse")){if("out"==a(e).data("mouse")){var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"mouseOver",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}a(e).data("mouse","over")}}).on("mouseout",function(c){var e=c.target;"LI"!=e.tagName&&(e=e.parentNode),a(e).hasClass("nomouse")||(a(e).data("mouse","leaving"),setTimeout(function(){if("leaving"==a(e).data("mouse")){a(e).data("mouse","out");var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"f",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}},0))}),a(this.el).height("auto");var m=a(j).find("> div").height()+2*w2utils.getSize(j,"+height");26>m&&(m=26),m>c.maxHeight&&(m=c.maxHeight),j.length>0&&(j[0].scrollTop=1e3);var n=w2utils.getSize(a(this.el),"height")-2;n>m&&(m=n),a(j).css({height:m+"px",overflow:m==c.maxHeight?"auto":"hidden"}),mc.max&&(b=c.max,a(this.el).val(c.max))),b=""!==b&&w2utils.isFloat(b)?Number(b):""),b},format:function(a){var b=this.options;if(b.autoFormat&&""!=a)switch(this.type){case"money":case"currency":a=w2utils.formatNumber(Number(a).toFixed(b.currencyPrecision),b.groupSymbol),""!=a&&(a=b.currencyPrefix+a+b.currencySuffix);break;case"percent":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol),""!=a&&(a+="%");break;case"float":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol);break;case"int":a=w2utils.formatNumber(a,b.groupSymbol)}return a},change:function(b){{var c=this;c.options}if(-1!=["int","float","money","currency","percent"].indexOf(this.type)){var d=a(this.el).val(),e=this.format(this.clean(a(this.el).val()));if(""!=d&&d!=e)return a(this.el).val(e).change(),b.stopPropagation(),b.preventDefault(),!1}if("color"==this.type){var f="#"+a(this.el).val();6!=a(this.el).val().length&&3!=a(this.el).val().length&&(f=""),a(this.el).next().find("div").css("background-color",f),a(c.el).is(":focus")&&this.updateOverlay()}},click:function(b){b.stopPropagation(),-1!=["list","combo","enum"].indexOf(this.type)&&(a(this.el).is(":focus")||this.focus(b)),-1!=["date","time","color"].indexOf(this.type)&&this.updateOverlay()},focus:function(){{var b=this;this.options}if(-1!==["color","date","time"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){b.updateOverlay()},150)}if(-1!=["list","combo","enum"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){return"list"==b.type&&a(b.el).is(":focus")?void a(b.helpers.focus).find("input").focus():(b.search(),void setTimeout(function(){b.updateOverlay()},1))},1)}"file"==b.type&&a(b.helpers.multi).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"})},blur:function(){var b=this,c=b.options,d=a(b.el).val().trim();-1!=["color","date","time","list","combo","enum"].indexOf(b.type)&&a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),-1!=["int","float","money","currency","percent"].indexOf(b.type)&&(""===d||b.checkType(d)||(a(b.el).val("").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid number"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),-1!=["date","time"].indexOf(b.type)&&(w2utils.isInt(b.el.value)&&a(b.el).val(w2utils.formatDate(new Date(parseInt(b.el.value)),c.format)).change(),""===d||b.inRange(b.el.value)?("date"!=b.type||""===d||w2utils.isDate(b.el.value,c.format)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid date"),setTimeout(function(){a(b.el).w2tag("")},3e3))),"time"!=b.type||""===d||w2utils.isTime(b.el.value)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid time"),setTimeout(function(){a(b.el).w2tag("")},3e3)))):(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not in range"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),"enum"==b.type&&a(b.helpers.multi).find("input").val("").width(20),"file"==b.type&&a(b.helpers.multi).css({outline:"none"})},keyPress:function(a){{var b=this;b.options}if(-1!=["int","float","money","currency","percent","hex","color","alphanumeric"].indexOf(b.type)){if(a.metaKey||a.ctrlKey||a.altKey||a.charCode!=a.keyCode&&a.keyCode>0)return;var c=String.fromCharCode(a.charCode);if(!b.checkType(c,!0)&&13!=a.keyCode)return a.preventDefault(),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,!1}-1!=["date","time"].indexOf(b.type)&&setTimeout(function(){b.updateOverlay()},1)},keyDown:function(b,c){var d=this,e=d.options,f=b.keyCode||c&&c.keyCode;if(-1!=["int","float","money","currency","percent"].indexOf(d.type)){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,h=parseFloat(a(d.el).val().replace(e.moneyRE,""))||0,i=e.step;switch((b.ctrlKey||b.metaKey)&&(i=10),f){case 38:if(b.shiftKey)break;a(d.el).val(h+i<=e.max||null===e.max?Number((h+i).toFixed(12)):e.max).change(),g=!0;break;case 40:if(b.shiftKey)break;a(d.el).val(h-i>=e.min||null===e.min?Number((h-i).toFixed(12)):e.min).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("date"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,j=864e5,i=1;(b.ctrlKey||b.metaKey)&&(i=10),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatDate(new Date(parseInt(d.el.value)),e.format)).change();var k=w2utils.isDate(a(d.el).val(),e.format,!0);switch(k||(k=new Date,j=0),f){case 38:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()+j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()+1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0;break;case 40:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()-j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()-1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length),d.updateOverlay()},0))}if("time"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,i=1;(b.ctrlKey||b.metaKey)&&(i=60),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatTime(new Date(parseInt(d.el.value)),e.format)).change();var h=a(d.el).val(),m=d.toMin(h)||d.toMin((new Date).getHours()+":"+((new Date).getMinutes()-1));switch(f){case 38:if(b.shiftKey)break;m+=i,g=!0;break;case 40:if(b.shiftKey)break;m-=i,g=!0}g&&(a(d.el).val(d.fromMin(m)).change(),b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("color"==d.type){if(a(d.el).attr("readonly"))return;if(86==b.keyCode&&(b.ctrlKey||b.metaKey)&&(a(d.el).prop("maxlength",7),setTimeout(function(){var b=a(d).val();"#"==b.substr(0,1)&&(b=b.substr(1)),w2utils.isHex(b)||(b=""),a(d).val(b).prop("maxlength",6).change()},20)),(b.ctrlKey||b.metaKey)&&!b.shiftKey){if("undefined"==typeof d.tmp.cind1)d.tmp.cind1=-1,d.tmp.cind2=-1;else{switch(f){case 38:d.tmp.cind1--;break;case 40:d.tmp.cind1++;break;case 39:d.tmp.cind2++;break;case 37:d.tmp.cind2--}d.tmp.cind1<0&&(d.tmp.cind1=0),d.tmp.cind1>this.pallete.length-1&&(d.tmp.cind1=this.pallete.length-1),d.tmp.cind2<0&&(d.tmp.cind2=0),d.tmp.cind2>this.pallete[0].length-1&&(d.tmp.cind2=this.pallete[0].length-1)}-1!=[37,38,39,40].indexOf(f)&&(a(d.el).val(this.pallete[d.tmp.cind1][d.tmp.cind2]).change(),b.preventDefault())}}if(-1!=["list","combo","enum"].indexOf(d.type)){if(a(d.el).attr("readonly"))return;var g=!1,n=a(d.el).data("selected"),o=a(d.helpers.focus).find("input");switch("list"==d.type&&-1==[37,38,39,40].indexOf(f)&&d.refresh(),f){case 27:"list"==d.type&&(""==a(o).val()?a(d.el).data("selected",{}):a(o).val(""),d.refresh(),b.stopPropagation());break;case 37:case 39:break;case 13:if(0==a("#w2ui-overlay").length)break;var p=e.items[e.index],q=a(d.helpers.multi).find("input");if("enum"==d.type)if(null!=p){var r=d.trigger({phase:"before",type:"add",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,n.length>=e.max&&e.max>0&&n.pop(),delete p.hidden,delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}else{p={id:q.val(),text:q.val()};var r=d.trigger({phase:"before",type:"new",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,"function"==typeof d.onNew&&(n.length>=e.max&&e.max>0&&n.pop(),delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh()),d.trigger(a.extend(r,{phase:"after"}))}else p&&a(d.el).data("selected",p).val(p.text).change(),""==a(d.el).val()&&a(d.el).data("selected")&&a(d.el).removeData("selected").val("").change(),"list"==d.type&&(o.val(""),d.refresh()),d.tmp.force_hide=!0;break;case 8:if(-1!=["enum"].indexOf(d.type)&&""==a(d.helpers.multi).find("input").val()&&n.length>0){var p=n[n.length-1],r=d.trigger({phase:"before",type:"remove",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;n.pop(),a(d.el).trigger("change"),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}break;case 38:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):0,e.index--;e.index>0&&e.items[e.index].hidden;)e.index--;if(0==e.index&&e.items[e.index].hidden)for(;e.items[e.index]&&e.items[e.index].hidden;)e.index++;g=!0;break;case 40:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):-1,e.index++;e.index=e.items.length&&(e.index=e.items.length-1),d.updateOverlay(),b.preventDefault(),void setTimeout(function(){if("enum"==d.type){var a=d.helpers.multi.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else if("list"==d.type){var a=d.helpers.focus.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0);if("enum"==d.type){var s=d.helpers.multi.find("input"),t=s.val();s.width(8*(t.length+2)+"px")}-1==[16,17,18,20,37,39,91].indexOf(f)&&setTimeout(function(){d.tmp.force_hide||d.request(),d.search()},1)}},keyUp:function(b){"color"==this.type&&86==b.keyCode&&(b.ctrlKey||b.metaKey)&&a(this).prop("maxlength",6)},clearCache:function(){var a=this.options;a.items=[],this.tmp.xhr_loading=!1,this.tmp.xhr_search="",this.tmp.xhr_total=-1,this.search()},request:function(b){var c=this,d=this.options,e=a(c.el).val()||"";if(d.url){if("enum"==c.type){var f=a(c.helpers.multi).find("input");e=0==f.length?"":f.val()}if("list"==c.type){var f=a(c.helpers.focus).find("input");e=0==f.length?"":f.val()}if(0!=d.minLength&&e.lengthc.tmp.xhr_search.length||e.length>=c.tmp.xhr_search.length&&e.substr(0,c.tmp.xhr_search.length)!=c.tmp.xhr_search||e.lengthd.cacheMax&&b.items.splice(d.cacheMax,1e5),c.tmp.xhr_loading=!1,c.tmp.xhr_search=e,c.tmp.xhr_total=b.items.length,d.items=b.items,c.tmp.emptySet=""==e&&0==b.items.length?!0:!1,c.search(),c.trigger(a.extend(i,{phase:"after"}))}}).error(function(b,d,f){var g={status:d,exceptionThrown:f,rawResponseText:b.responseText},h=c.trigger({phase:"before",type:"error",target:c.el,search:e,error:g,xhr:b});h.isCancelled!==!0&&(console.log("ERROR: server communication failed. The server should return",{status:"success",items:[{id:1,text:"item"}]},", instead the AJAX request produced this: ",g),c.clearCache(),c.trigger(a.extend(h,{phase:"after"})))}),c.trigger(a.extend(g,{phase:"after"})))},b))}},search:function(){var b=this,c=this.options,d=a(b.el).val(),e=b.el,f=[],g=a(b.el).data("selected");if("enum"==b.type){e=a(b.helpers.multi).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}if("list"==b.type){e=a(b.helpers.focus).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}var i=b.trigger({phase:"before",type:"search",target:e,search:d});if(i.isCancelled!==!0){if(b.tmp.xhr_loading!==!0){var j=0;for(var k in c.items){var l=c.items[k],m="",n="";-1!=["is","begins"].indexOf(c.match)&&(m="^"),-1!=["is","ends"].indexOf(c.match)&&(n="$");try{var o=new RegExp(m+d+n,"i");l.hidden=o.test(l.text)||"..."==l.text?!1:!0}catch(p){}"enum"==b.type&&-1!=a.inArray(l.id,f)&&(l.hidden=!0),l.hidden!==!0&&j++}if("combo"!=b.type)for(c.index=0;c.items[c.index]&&c.items[c.index].hidden;)c.index++;else c.index=-1;0>=j&&(c.index=-1),c.spinner=!1,b.updateOverlay(),setTimeout(function(){var b=a("#w2ui-overlay").html()||"";c.markSearch&&-1!=b.indexOf("$.fn.w2menuHandler")&&a("#w2ui-overlay").w2marker(d)},1)}else c.items.splice(0,c.cacheMax),c.spinner=!0,b.updateOverlay();b.trigger(a.extend(i,{phase:"after"}))}},updateOverlay:function(){var b=this,c=this.options;if("color"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length?a(b.el).w2overlay(b.getColorHTML()):a("#w2ui-overlay").html(b.getColorHTML()),a("#w2ui-overlay .color").on("mousedown",function(c){var d=a(c.originalEvent.target).attr("name"),e=a(c.originalEvent.target).attr("index").split(":");b.tmp.cind1=e[0],b.tmp.cind2=e[1],a(b.el).val(d).change(),a(this).html("•")}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}if("date"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
      ',{css:{"background-color":"#f5f5f5"}});var d,e,f=w2utils.isDate(a(b.el).val(),b.options.format,!0);f&&(d=f.getMonth()+1,e=f.getFullYear()),function k(c,d){a("#w2ui-overlay > div > div").html(b.getMonthHTML(c,d)),a("#w2ui-overlay .w2ui-calendar-title").on("mousedown",function(){if(a(this).next().hasClass("w2ui-calendar-jump"))a(this).next().remove();else{var c,d;a(this).after('
      '),a(this).next().hide().html(b.getYearHTML()).fadeIn(200),setTimeout(function(){a("#w2ui-overlay .w2ui-calendar-jump").find(".w2ui-jump-month, .w2ui-jump-year").on("click",function(){a(this).hasClass("w2ui-jump-month")&&(a(this).parent().find(".w2ui-jump-month").removeClass("selected"),a(this).addClass("selected"),d=a(this).attr("name")),a(this).hasClass("w2ui-jump-year")&&(a(this).parent().find(".w2ui-jump-year").removeClass("selected"),a(this).addClass("selected"),c=a(this).attr("name")),null!=c&&null!=d&&(a("#w2ui-overlay .w2ui-calendar-jump").fadeOut(100),setTimeout(function(){k(parseInt(d)+1,c)},100))}),a("#w2ui-overlay .w2ui-calendar-jump >:last-child").prop("scrollTop",2e3)},1)}}),a("#w2ui-overlay .w2ui-date").on("mousedown",function(){var c=a(this).attr("date");a(b.el).val(c).change(),a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"})}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)}),a("#w2ui-overlay .previous").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])-1,k(a[0],a[1])}),a("#w2ui-overlay .next").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])+1,k(a[0],a[1])})}(d,e)}if("time"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
      ',{css:{"background-color":"#fff"}});var g="h24"==this.options.format?!0:!1;a("#w2ui-overlay > div").html(b.getHourHTML()),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var c=a(this).attr("hour");a(b.el).val((c>12&&!g?c-12:c)+":00"+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){var c=a(this).attr("hour");a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),a(b.el).w2overlay('
      ',{css:{"background-color":"#fff"}}),a("#w2ui-overlay > div").html(b.getMinHTML(c)),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var d=a(this).attr("min");a(b.el).val((c>12&&!g?c-12:c)+":"+(10>d?0:"")+d+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide() +},10)})})}if(-1!=["list","combo","enum"].indexOf(this.type)){var h=this.el,i=this.el;if("enum"==this.type&&(h=a(this.helpers.multi),i=a(h).find("input")),"list"==this.type&&(i=a(this.helpers.focus).find("input")),a(i).is(":focus")){if(c.openOnFocus===!1&&""==a(i).val()&&b.tmp.force_open!==!0)return void a().w2overlay();if(b.tmp.force_hide)return a().w2overlay(),void setTimeout(function(){delete b.tmp.force_hide},1);""!=a(i).val()&&delete b.tmp.force_open,0==a("#w2ui-overlay").length&&(c.index=0);var j=w2utils.lang("No matches");null!=c.url&&a(i).val().length=c.max&&c.max>0&&e.pop(),delete d.item.hidden,e.push(d.item),a(b.el).data("selected",e).change(),a(b.helpers.multi).find("input").val("").width(20),b.refresh(),a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),b.trigger(a.extend(f,{phase:"after"}))}}else a(b.el).data("selected",d.item).val(d.item.text).change(),b.helpers.focus&&(b.helpers.focus.find("input").val(""),b.refresh())}}))}}},inRange:function(b){var c=!1;if("date"==this.type){var d=w2utils.isDate(b,this.options.format,!0);if(d){if(this.options.start||this.options.end){var e="string"==typeof this.options.start?this.options.start:a(this.options.start).val(),f="string"==typeof this.options.end?this.options.end:a(this.options.end).val(),g=w2utils.isDate(e,this.options.format,!0),h=w2utils.isDate(f,this.options.format,!0),i=new Date(d);g||(g=i),h||(h=i),i>=g&&h>=i&&(c=!0)}else c=!0;this.options.blocked&&-1!=a.inArray(b,this.options.blocked)&&(c=!1)}}if("time"==this.type)if(this.options.start||this.options.end){var j=this.toMin(b),k=this.toMin(this.options.start),l=this.toMin(this.options.end);k||(k=j),l||(l=j),j>=k&&l>=j&&(c=!0)}else c=!0;return c},checkType:function(a,b){var c=this;switch(c.type){case"int":return b&&-1!=["-"].indexOf(a)?!0:w2utils.isInt(a.replace(c.options.numberRE,""));case"percent":a=a.replace(/%/g,"");case"float":return b&&-1!=["-","."].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.numberRE,""));case"money":case"currency":return b&&-1!=["-",".",c.options.groupSymbol,c.options.currencyPrefix,c.options.currencySuffix].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.moneyRE,""));case"hex":case"color":return w2utils.isHex(a);case"alphanumeric":return w2utils.isAlphaNumeric(a)}return!0},addPrefix:function(){var b=this;setTimeout(function(){if("clear"!==b.type){var c,d=a(b.el).data("tmp")||{};d["old-padding-left"]&&a(b.el).css("padding-left",d["old-padding-left"]),d["old-padding-left"]=a(b.el).css("padding-left"),a(b.el).data("tmp",d),""!==b.options.prefix&&(b.helpers.prefix&&a(b.helpers.prefix).remove(),a(b.el).before('
      '+b.options.prefix+"
      "),c=a(b.el).prev(),c.css({color:a(b.el).css("color"),"font-family":a(b.el).css("font-family"),"font-size":a(b.el).css("font-size"),"padding-top":a(b.el).css("padding-top"),"padding-bottom":a(b.el).css("padding-bottom"),"padding-left":a(b.el).css("padding-left"),"padding-right":0,"margin-top":parseInt(a(b.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(b.el).css("margin-bottom"),10)+1+"px","margin-left":a(b.el).css("margin-left"),"margin-right":0}).on("click",function(){if(b.options.icon&&"function"==typeof b.onIconClick){var c=b.trigger({phase:"before",type:"iconClick",target:b.el,el:a(this).find("span.w2ui-icon")[0]});if(c.isCancelled===!0)return;b.trigger(a.extend(c,{phase:"after"}))}else"list"==b.type?a(b.helpers.focus).find("input").focus():a(b.el).focus()}),a(b.el).css("padding-left",c.width()+parseInt(a(b.el).css("padding-left"),10)+"px"),b.helpers.prefix=c)}},1)},addSuffix:function(){var b,c,d=this;setTimeout(function(){if("clear"!==d.type){var e=a(d.el).data("tmp")||{};if(e["old-padding-right"]&&a(d.el).css("padding-right",e["old-padding-right"]),e["old-padding-right"]=a(d.el).css("padding-right"),a(d.el).data("tmp",e),c=parseInt(a(d.el).css("padding-right"),10),d.options.arrows){d.helpers.arrows&&a(d.helpers.arrows).remove(),a(d.el).after('
       
      ');{w2utils.getSize(d.el,"height")}b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),height:a(d.el).height()+parseInt(a(d.el).css("padding-top"),10)+parseInt(a(d.el).css("padding-bottom"),10)+"px",padding:0,"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":0,"border-left":"1px solid silver"}).css("margin-left","-"+(b.width()+parseInt(a(d.el).css("margin-right"),10)+12)+"px").on("mousedown",function(b){function c(){clearTimeout(a("body").data("_field_update_timer")),a("body").off("mouseup",c)}function e(c){a(d.el).focus(),d.keyDown(a.Event("keydown"),{keyCode:"up"==a(b.target).attr("type")?38:40}),c!==!1&&a("body").data("_field_update_timer",setTimeout(e,60))}a("body").on("mouseup",c),a("body").data("_field_update_timer",setTimeout(e,700)),e(!1)}),c+=b.width()+12,a(d.el).css("padding-right",c+"px"),d.helpers.arrows=b}""!==d.options.suffix&&(d.helpers.suffix&&a(d.helpers.suffix).remove(),a(d.el).after('
      '+d.options.suffix+"
      "),b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),"padding-top":a(d.el).css("padding-top"),"padding-bottom":a(d.el).css("padding-bottom"),"padding-left":"3px","padding-right":a(d.el).css("padding-right"),"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(d.el).css("margin-bottom"),10)+1+"px"}).on("click",function(){"list"==d.type?a(d.helpers.focus).find("input").focus():a(d.el).focus()}),b.css("margin-left","-"+(w2utils.getSize(b,"width")+parseInt(a(d.el).css("margin-right"),10)+2)+"px"),c+=b.width()+3,a(d.el).css("padding-right",c+"px"),d.helpers.suffix=b)}},1)},addFocus:function(){var b=this,c=this.options,d=0;c.icon&&(d=11),a(b.helpers.focus).remove();var e='
      ';a(b.el).attr("tabindex",-1).before(e);var f=a(b.el).prev();b.helpers.focus=f,f.css({width:a(b.el).width(),"margin-top":a(b.el).css("margin-top"),"margin-left":parseInt(a(b.el).css("margin-left"))+parseInt(a(b.el).css("padding-left"))+"px","margin-bottom":a(b.el).css("margin-bottom"),"margin-right":a(b.el).css("margin-right")}).find("input").css({cursor:"default",width:"100%",outline:"none",opacity:1,margin:0,border:"1px solid transparent",padding:a(b.el).css("padding-top"),"padding-left":0,"margin-left":d+(d>0?6:0),"background-color":"transparent"}),f.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),c.stopPropagation()}).on("focus",function(c){a(b.el).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(this).val(""),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(b.el).css("outline","none"),a(this).val(""),b.refresh(),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){b.keyPress(a)}),f.on("click",function(){a(this).find("input").focus()}),b.refresh()},addMulti:function(){{var b=this;this.options}a(b.helpers.multi).remove();var c="",d="margin-top : 0px; margin-bottom : 0px; margin-left : "+a(b.el).css("margin-left")+"; margin-right : "+a(b.el).css("margin-right")+"; width : "+(w2utils.getSize(b.el,"width")-parseInt(a(b.el).css("margin-left"),10)-parseInt(a(b.el).css("margin-right"),10))+"px;";"enum"==b.type&&(c='
      • "),"file"==b.type&&(c='
        '),a(b.el).before(c).css({"background-color":"transparent","border-color":"transparent"});var e=a(b.el).prev();b.helpers.multi=e,"enum"==b.type&&(a(b.el).attr("tabindex",-1),e.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),a(b.el).triggerHandler("click")}).on("focus",function(c){a(e).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(e).css("outline","none"),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){e.find(".w2ui-enum-placeholder").remove(),b.keyPress(a)}),e.on("click",function(){a(this).find("input").focus()})),"file"==b.type&&(a(b.el).css("outline","none"),e.on("click",function(c){a(b.el).focus(),a(b.el).attr("readonly")||(b.blur(c),e.find("input").click())}).on("dragenter",function(){a(b.el).attr("readonly")||a(e).addClass("w2ui-file-dragover")}).on("dragleave",function(c){if(!a(b.el).attr("readonly")){var d=a(c.target).parents(".w2ui-field-helper");0==d.length&&a(e).removeClass("w2ui-file-dragover")}}).on("drop",function(c){if(!a(b.el).attr("readonly")){a(e).removeClass("w2ui-file-dragover");for(var d=c.originalEvent.dataTransfer.files,f=0,g=d.length;g>f;f++)b.addFile.call(b,d[f]);c.preventDefault(),c.stopPropagation()}}).on("dragover",function(a){a.preventDefault(),a.stopPropagation()}),e.find("input").on("click",function(a){a.stopPropagation()}).on("change",function(){if("undefined"!=typeof this.files)for(var a=0,c=this.files.length;c>a;a++)b.addFile.call(b,this.files[a])})),b.refresh()},addFile:function(b){var c,d=this,e=this.options,f=a(d.el).data("selected"),g={name:b.name,type:b.type,modified:b.lastModifiedDate,size:b.size,content:null},h=0,i=0;for(var j in f)h+=f[j].size,i++;var k=d.trigger({phase:"before",type:"add",target:d.el,file:g,total:i,totalSize:h});if(k.isCancelled!==!0){if(0!==e.maxFileSize&&g.size>e.maxFileSize)return c="Maximum file size is "+w2utils.size(e.maxFileSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.maxSize&&h+g.size>e.maxSize)return c="Maximum total size is "+w2utils.size(e.maxSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.max&&i>=e.max)return c="Maximum number of files is "+e.max,e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(f.push(g),"undefined"!=typeof FileReader){var l=new FileReader;l.onload=function(){return function(b){var c=b.target.result,e=c.indexOf(",");g.content=c.substr(e+1),d.refresh(),a(d.el).trigger("change"),d.trigger(a.extend(k,{phase:"after"}))}}(),l.readAsDataURL(b)}else d.refresh(),a(d.el).trigger("change")}},normMenu:function(b){if(a.isArray(b)){for(var c=0;cc;c++){b+="";for(var d=0;8>d;d++)b+='
        '+(a(this.el).val()==this.pallete[c][d]?"•":" ")+"
        ";b+="",2>c&&(b+='')}return b+="
        "},getMonthHTML:function(a,b){var c=new Date,d=w2utils.settings.fullmonths,e=(w2utils.settings.fulldays,["31","28","31","30","31","30","31","31","30","31","30","31"]),f=c.getFullYear()+"/"+(Number(c.getMonth())+1)+"/"+c.getDate();b=w2utils.isInt(b)?parseInt(b):c.getFullYear(),a=w2utils.isInt(a)?parseInt(a):c.getMonth()+1,a>12&&(a-=12,b++),(1>a||0===a)&&(a+=12,b--),e[1]=b/4==Math.floor(b/4)?"29":"28",this.options.current=a+"/"+b,c=new Date(b,a-1,1);for(var g=c.getDay(),h=w2utils.settings.shortdays,i="",j=0,k=h.length;k>j;j++)i+=""+h[j]+"";for(var l='
        '+d[a-1]+", "+b+'
        '+i+"",m=1,n=1;43>n;n++){if(0===g&&1==n){for(var o=0;6>o;o++)l+='';n+=6}else if(g>n||m>e[a-1]){l+='',n%7===0&&(l+="");continue}var p=b+"/"+a+"/"+m,q="";n%7==6&&(q=" w2ui-saturday"),n%7===0&&(q=" w2ui-sunday"),p==f&&(q+=" w2ui-today");var r=m,s="",t="",u=w2utils.formatDate(p,this.options.format);this.options.colored&&void 0!==this.options.colored[u]&&(tmp=this.options.colored[u].split(":"),t="background-color: "+tmp[0]+";",s="color: "+tmp[1]+";"),l+='",(n%7===0||0===g&&1==n)&&(l+=""),m++}return l+="
          
        '+r+"
        "},getYearHTML:function(){var a=w2utils.settings.shortmonths,b="",c="";for(var d in a)b+='
        '+a[d]+"
        ";for(var e=1950;2020>=e;e++)c+='
        '+e+"
        ";return"
        "+b+"
        "+c+"
        "},getHourHTML:function(){for(var a=[],b="h24"==this.options.format?!0:!1,c=0;24>c;c++){var d=(c>=12&&!b?c-12:c)+":00"+(b?"":12>c?" am":" pm");12!=c||b||(d="12:00 pm"),a[Math.floor(c/8)]||(a[Math.floor(c/8)]="");var e=this.fromMin(this.toMin(d)),f=this.fromMin(this.toMin(d)+59);a[Math.floor(c/8)]+='
        '+d+"
        "}var g='
        '+a[0]+" "+a[1]+" "+a[2]+"
        ";return g},getMinHTML:function(a){"undefined"==typeof a&&(a=0);for(var b="h24"==this.options.format?!0:!1,c=[],d=0;60>d;d+=5){var e=(a>12&&!b?a-12:a)+":"+(10>d?0:"")+d+" "+(b?"":12>a?"am":"pm"),f=20>d?0:40>d?1:2;c[f]||(c[f]=""),c[f]+='
        '+e+"
        "}var g='
        '+c[0]+" "+c[1]+" "+c[2]+"
        ";return g},toMin:function(a){if("string"!=typeof a)return null;var b=a.split(":");return 2!=b.length?null:(b[0]=parseInt(b[0]),b[1]=parseInt(b[1]),-1!=a.indexOf("pm")&&12!=b[0]&&(b[0]+=12),60*b[0]+b[1])},fromMin:function(a){var b="";a>=1440&&(a%=1440),0>a&&(a=1440+a);var c=Math.floor(a/60),d=(10>a%60?"0":"")+a%60;return b=-1!=this.options.format.indexOf("h24")?c+":"+d:(12>=c?c:c-12)+":"+d+" "+(c>=12?"pm":"am")}},a.extend(b.prototype,w2utils.event),w2obj.field=b}(jQuery); \ No newline at end of file diff --git a/dist/w2ui.css b/dist/w2ui.css index 9a9986686..d787bfe3f 100644 --- a/dist/w2ui.css +++ b/dist/w2ui.css @@ -702,7 +702,7 @@ select { border-top-color: #81C6FF; } /* -* ARROWS +* ARROWS */ .arrow-up { background: none; @@ -754,7 +754,7 @@ select { line-height: 0; } /* -* COLOR overlay +* COLOR overlay */ .w2ui-color { padding: 5px; @@ -786,7 +786,7 @@ select { border: 1px solid #fff; } /* -* DATE overlay +* DATE overlay */ .w2ui-calendar { margin: 0px; @@ -974,7 +974,7 @@ select { padding: 6px; } /* -* Time +* Time */ .w2ui-calendar-time { padding: 5px; @@ -1010,7 +1010,7 @@ select { background-image: linear-gradient(top,#ffffff 20%,#f6f6f6 50%,#eeeeee 52%,#f4f4f4 100%); } /* -* Drop down menu +* Drop down menu */ .w2ui-drop-menu td { white-space: nowrap; @@ -1030,7 +1030,7 @@ select { border-bottom: 1px solid #D3D2D4; } /* -* ENUM items +* ENUM items */ .w2ui-list { color: inherit; diff --git a/dist/w2ui.js b/dist/w2ui.js index 044c43f88..590b8741f 100644 --- a/dist/w2ui.js +++ b/dist/w2ui.js @@ -5,866 +5,866 @@ var w2obj = w2obj || {}; // expose object to be able to overwrite default functi /************************************************ * Library: Web 2.0 UI for jQuery * - Following objects are defines -* - w2ui - object that will contain all widgets -* - w2obj - object with widget prototypes -* - w2utils - basic utilities -* - $().w2render - common render -* - $().w2destroy - common destroy -* - $().w2marker - marker plugin -* - $().w2tag - tag plugin -* - $().w2overlay - overlay plugin -* - $().w2menu - menu plugin -* - w2utils.event - generic event object -* - w2utils.keyboard - object for keyboard navigation +* - w2ui - object that will contain all widgets +* - w2obj - object with widget prototypes +* - w2utils - basic utilities +* - $().w2render - common render +* - $().w2destroy - common destroy +* - $().w2marker - marker plugin +* - $().w2tag - tag plugin +* - $().w2overlay - overlay plugin +* - $().w2menu - menu plugin +* - w2utils.event - generic event object +* - w2utils.keyboard - object for keyboard navigation * - Dependencies: jQuery * * == NICE TO HAVE == -* - date has problems in FF new Date('yyyy-mm-dd') breaks -* - bug: w2utils.formatDate('2011-31-01', 'yyyy-dd-mm'); - wrong foratter -* - overlay should be displayed where more space (on top or on bottom) -* - write and article how to replace certain framework functions -* - format date and time is buggy -* - onComplete should pass widget as context (this) -* - add maxHeight for the w2menu -* - user localization from another lib (make it generic), https://github.com/jquery/globalize#readme -* - hidden and disabled in menus -* - isTime should support seconds -* - TEST On IOS +* - date has problems in FF new Date('yyyy-mm-dd') breaks +* - bug: w2utils.formatDate('2011-31-01', 'yyyy-dd-mm'); - wrong foratter +* - overlay should be displayed where more space (on top or on bottom) +* - write and article how to replace certain framework functions +* - format date and time is buggy +* - onComplete should pass widget as context (this) +* - add maxHeight for the w2menu +* - user localization from another lib (make it generic), https://github.com/jquery/globalize#readme +* - hidden and disabled in menus +* - isTime should support seconds +* - TEST On IOS * * == 1.4 changes -* - lock(box, options) || lock(box, msg, spinner) -* - updated age() date(), formatDate(), formatTime() - input format either '2013/12/21 19:03:59 PST' or unix timestamp -* - formatNumer(num, groupSymbol) - added new param -* - improved localization support (currency prefix, suffix, numbger group symbol) -* - improoved overlays (better positioning, refresh, etc.) -* - multiple overlay at the same time (if it has name) -* - overlay options.css removed, I have added options.style -* - ability to open searchable w2menu -* - w2confirm({}) +* - lock(box, options) || lock(box, msg, spinner) +* - updated age() date(), formatDate(), formatTime() - input format either '2013/12/21 19:03:59 PST' or unix timestamp +* - formatNumer(num, groupSymbol) - added new param +* - improved localization support (currency prefix, suffix, numbger group symbol) +* - improoved overlays (better positioning, refresh, etc.) +* - multiple overlay at the same time (if it has name) +* - overlay options.css removed, I have added options.style +* - ability to open searchable w2menu +* - w2confirm({}) * ************************************************/ var w2utils = (function () { - var tmp = {}; // for some temp variables - var obj = { - settings : { - "locale" : "en-us", - "date_format" : "m/d/yyyy", - "date_display" : "Mon d, yyyy", - "time_format" : "h12", - "currencyPrefix": "$", - "currencySuffix": "", - "currencyPrecision": 2, - "groupSymbol" : ",", - "shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - "fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - "shortdays" : ["M", "T", "W", "T", "F", "S", "S"], - "fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], - "RESTfull" : false, - "phrases" : {} // empty object for english phrases - }, - isInt : isInt, - isFloat : isFloat, - isMoney : isMoney, - isHex : isHex, - isAlphaNumeric : isAlphaNumeric, - isEmail : isEmail, - isDate : isDate, - isTime : isTime, - age : age, - date : date, - size : size, - formatNumber : formatNumber, - formatDate : formatDate, - formatTime : formatTime, - formatDateTime : formatDateTime, - stripTags : stripTags, - encodeTags : encodeTags, - escapeId : escapeId, - base64encode : base64encode, - base64decode : base64decode, - transition : transition, - lock : lock, - unlock : unlock, - lang : lang, - locale : locale, - getSize : getSize, - scrollBarSize : scrollBarSize, - checkName : checkName, - checkUniqueId : checkUniqueId - }; - return obj; - - function isInt (val) { - var re = /^[-+]?[0-9]+$/; - return re.test(val); - } - - function isFloat (val) { - return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)); - } - - function isMoney (val) { - var se = w2utils.settings; - var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +'[-+]?[0-9]*[\.]?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i'); - if (typeof val === 'string') { - val = val.replace(new RegExp(se.groupSymbol, 'g'), ''); - } - if (typeof val === 'object' || val === '') return false; - return re.test(val); - } - - function isHex (val) { - var re = /^[a-fA-F0-9]+$/; - return re.test(val); - } - - function isAlphaNumeric (val) { - var re = /^[a-zA-Z0-9_-]+$/; - return re.test(val); - } - - function isEmail (val) { - var email = /^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; - return email.test(val); - } - - function isDate (val, format, retDate) { - if (!val) return false; - - var dt = 'Invalid Date'; - var month, day, year; - - if (format == null) format = w2utils.settings.date_format; - - if (typeof val.getUTCFullYear === 'function' && typeof val.getUTCMonth === 'function' && typeof val.getUTCDate === 'function') { - year = val.getUTCFullYear(); - month = val.getUTCMonth(); - day = val.getUTCDate(); - } else if (typeof val.getFullYear === 'function' && typeof val.getMonth === 'function' && typeof val.getDate === 'function') { - year = val.getFullYear(); - month = val.getMonth(); - day = val.getDate(); - } else { - val = String(val); - // convert month formats - if (RegExp('mon', 'ig').test(format)) { - format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); - val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); - for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) { - var t = w2utils.settings.fullmonths[m]; - val = val.replace(RegExp(t, 'ig'), (parseInt(m) + 1)).replace(RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)); - } - } - // format date - var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); - var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); - if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } - if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } - if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } - if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } - if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } - if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } - if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } - } - if (!isInt(year)) return false; - if (!isInt(month)) return false; - if (!isInt(day)) return false; - year = +year; - month = +month; - day = +day; - dt = new Date(year, month - 1, day); - // do checks - if (month == null) return false; - if (dt === 'Invalid Date') return false; - if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false; - if (retDate === true) return dt; else return true; - } - - function isTime (val, retTime) { - // Both formats 10:20pm and 22:20 - if (val == null) return false; - var max, pm; - // -- process american format - val = String(val); - val = val.toUpperCase(); - pm = val.indexOf('PM') >= 0; - var ampm = (pm || val.indexOf('AM') >= 0); - if (ampm) max = 12; else max = 24; - val = val.replace('AM', '').replace('PM', ''); - val = $.trim(val); - // --- - var tmp = val.split(':'); - var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0); - // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: - if ((!ampm || tmp.length !== 1) && tmp.length !== 2) { return false; } - if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; } - if (tmp.length === 2 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; } - // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). - // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. - if (!ampm && max === h && m !== 0) { return false; } - if (ampm && tmp.length === 1 && h === 0) { return false; } - - if (retTime === true) { - if (pm) h += 12; - return { - hours: h, - minutes: m - }; - } - return true; - } - - function age (dateStr) { - if (dateStr === '' || dateStr == null) return ''; - var d1 = new Date(dateStr); - if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps - if (d1 === 'Invalid Date') return ''; - - var d2 = new Date(); - var sec = (d2.getTime() - d1.getTime()) / 1000; - var amount = ''; - var type = ''; - if (sec < 0) { - amount = 'future'; - type = ''; - } else if (sec < 60) { - amount = Math.floor(sec); - type = 'sec'; - if (sec < 0) { amount = 0; type = 'sec'; } - } else if (sec < 60*60) { - amount = Math.floor(sec/60); - type = 'min'; - } else if (sec < 24*60*60) { - amount = Math.floor(sec/60/60); - type = 'hour'; - } else if (sec < 30*24*60*60) { - amount = Math.floor(sec/24/60/60); - type = 'day'; - } else if (sec < 12*30*24*60*60) { - amount = Math.floor(sec/30/24/60/60*10)/10; - type = 'month'; - } else if (sec >= 12*30*24*60*60) { - amount = Math.floor(sec/12/30/24/60/60*10)/10; - type = 'year'; - } - return amount + ' ' + type + (amount > 1 ? 's' : ''); - } - - function date (dateStr) { - if (dateStr === '' || dateStr == null) return ''; - var d1 = new Date(dateStr); - if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps - if (d1 === 'Invalid Date') return ''; - - var months = w2utils.settings.shortmonths; - var d2 = new Date(); // today - var d3 = new Date(); - d3.setTime(d3.getTime() - 86400000); // yesterday - - var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear(); - var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear(); - var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear(); - - var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); - var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); - var dsp = dd1; - if (dd1 === dd2) dsp = time; - if (dd1 === dd3) dsp = w2utils.lang('Yesterday'); - - return ''+ dsp +''; - } - - function size (sizeStr) { - if (!w2utils.isFloat(sizeStr) || sizeStr === '') return ''; - sizeStr = parseFloat(sizeStr); - if (sizeStr === 0) return 0; - var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB']; - var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ); - return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + sizes[i]; - } - - function formatNumber (val, groupSymbol) { - var ret = ''; - if (groupSymbol == null) groupSymbol = w2utils.settings.groupSymbol || ','; - // check if this is a number - if (w2utils.isFloat(val) || w2utils.isInt(val) || w2utils.isMoney(val)) { - tmp = String(val).split('.'); - ret = String(tmp[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + groupSymbol); - if (tmp[1] != null) ret += '.' + tmp[1]; - } - return ret; - } - - function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String - var months = w2utils.settings.shortmonths; - var fullMonths = w2utils.settings.fullmonths; - if (!format) format = this.settings.date_format; - if (dateStr === '' || dateStr == null) return ''; - - var dt = new Date(dateStr); - if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps - if (dt === 'Invalid Date') return ''; - - var year = dt.getFullYear(); - var month = dt.getMonth(); - var date = dt.getDate(); - return format.toLowerCase() - .replace('month', w2utils.settings.fullmonths[month]) - .replace('mon', w2utils.settings.shortmonths[month]) - .replace(/yyyy/g, year) - .replace(/yyy/g, year) - .replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2)) - .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceeded by a letter - .replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1)) - .replace(/dd/g, (date < 10 ? '0' : '') + date) - .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceeded by a letter - } - - function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String - var months = w2utils.settings.shortmonths; - var fullMonths = w2utils.settings.fullmonths; - if (!format) format = (this.settings.time_format === 'h12' ? 'hh:mi pm' : 'h24:mi'); - if (dateStr === '' || dateStr == null) return ''; - - var dt = new Date(dateStr); - if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps - if (w2utils.isTime(dateStr)) { - var tmp = w2utils.isTime(dateStr, true); - dt = new Date(); - dt.setHours(tmp.hours); - dt.setMinutes(tmp.minutes); - } - if (dt === 'Invalid Date') return ''; - - var type = 'am'; - var hour = dt.getHours(); - var h24 = dt.getHours(); - var min = dt.getMinutes(); - var sec = dt.getSeconds(); - if (min < 10) min = '0' + min; - if (sec < 10) sec = '0' + sec; - if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { - if (hour >= 12) type = 'pm'; - if (hour > 12) hour = hour - 12; - } - return format.toLowerCase() - .replace('am', type) - .replace('pm', type) - .replace('hh', hour) - .replace('h24', h24) - .replace('mm', min) - .replace('mi', min) - .replace('ss', sec) - .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceeded by a letter - } - - function formatDateTime(dateStr, format) { - var fmt; - if (typeof format !== 'string') { - fmt = [this.settings.date_format, this.settings.time_format]; - } else { - fmt = format.split('|'); - } - return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]); - } - - function stripTags (html) { - if (html === null) return html; - switch (typeof html) { - case 'number': - break; - case 'string': - html = $.trim(String(html).replace(/(<([^>]+)>)/ig, "")); - break; - case 'object': - for (var a in html) html[a] = this.stripTags(html[a]); - break; - } - return html; - } - - function encodeTags (html) { - if (html === null) return html; - switch (typeof html) { - case 'number': - break; - case 'string': - html = String(html).replace(/&/g, "&").replace(/>/g, ">").replace(/\|\/? {}\\])/g, '\\$1'); - } - - function base64encode (input) { - var output = ""; - var chr1, chr2, chr3, enc1, enc2, enc3, enc4; - var i = 0; - var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - input = utf8_encode(input); - - while (i < input.length) { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); - } - - function utf8_encode (string) { - var string = String(string).replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - } - return utftext; - } - - return output; - } - - function base64decode (input) { - var output = ""; - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0; - var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - enc1 = keyStr.indexOf(input.charAt(i++)); - enc2 = keyStr.indexOf(input.charAt(i++)); - enc3 = keyStr.indexOf(input.charAt(i++)); - enc4 = keyStr.indexOf(input.charAt(i++)); - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - output = output + String.fromCharCode(chr1); - if (enc3 !== 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 !== 64) { - output = output + String.fromCharCode(chr3); - } - } - output = utf8_decode(output); - - function utf8_decode (utftext) { - var string = ""; - var i = 0; - var c = 0, c2, c3; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string += String.fromCharCode(c); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return string; - } - - return output; - } - - function transition (div_old, div_new, type, callBack) { - var width = $(div_old).width(); - var height = $(div_old).height(); - var time = 0.5; - - if (!div_old || !div_new) { - console.log('ERROR: Cannot do transition when one of the divs is null'); - return; - } - - div_old.parentNode.style.cssText += cross('perspective', '700px') +'; overflow: hidden;'; - div_old.style.cssText += '; position: absolute; z-index: 1019; '+ cross('backface-visibility', 'hidden'); - div_new.style.cssText += '; position: absolute; z-index: 1020; '+ cross('backface-visibility', 'hidden'); - - switch (type) { - case 'slide-left': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d('+ width + 'px, 0, 0)', 'translate('+ width +'px, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); - }, 1); - break; - - case 'slide-right': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0px, 0, 0)', 'translate(0px, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d('+ width +'px, 0, 0)', 'translate('+ width +'px, 0)'); - }, 1); - break; - - case 'slide-down': - // init divs - div_old.style.cssText += 'overflow: hidden; z-index: 1; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; z-index: 0; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); - }, 1); - break; - - case 'slide-up': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - }, 1); - break; - - case 'flip-left': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(-180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(180deg)'); - }, 1); - break; - - case 'flip-right': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(-180deg)'); - }, 1); - break; - - case 'flip-down': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(-180deg)'); - }, 1); - break; - - case 'flip-up': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(-180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(180deg)'); - }, 1); - break; - - case 'pop-in': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') + '; '+ cross('transform', 'scale(.8)') + '; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time+'s') +';'; - }, 1); - break; - - case 'pop-out': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1.7)') +'; opacity: 0;'; - }, 1); - break; - - default: - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time +'s') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time +'s'); - }, 1); - break; - } - - setTimeout(function () { - if (type === 'slide-down') { - $(div_old).css('z-index', '1019'); - $(div_new).css('z-index', '1020'); - } - if (div_new) { - $(div_new).css({ - 'opacity': '1', - '-webkit-transition': '', - '-moz-transition': '', - '-ms-transition': '', - '-o-transition': '', - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '', - '-webkit-backface-visibility': '', - '-moz-backface-visibility': '', - '-ms-backface-visibility': '', - '-o-backface-visibility': '' - }); - } - if (div_old) { - $(div_old).css({ - 'opacity': '1', - '-webkit-transition': '', - '-moz-transition': '', - '-ms-transition': '', - '-o-transition': '', - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '', - '-webkit-backface-visibility': '', - '-moz-backface-visibility': '', - '-ms-backface-visibility': '', - '-o-backface-visibility': '' - }); - if (div_old.parentNode) $(div_old.parentNode).css({ - '-webkit-perspective': '', - '-moz-perspective': '', - '-ms-perspective': '', - '-o-perspective': '' - }); - } - if (typeof callBack === 'function') callBack(); - }, time * 1000); - - function cross(property, value, none_webkit_value) { - var isWebkit=!!window.webkitURL; // jQuery no longer supports $.browser - RR - if (!isWebkit && typeof none_webkit_value !== 'undefined') value = none_webkit_value; - return ';'+ property +': '+ value +'; -webkit-'+ property +': '+ value +'; -moz-'+ property +': '+ value +'; '+ - '-ms-'+ property +': '+ value +'; -o-'+ property +': '+ value +';'; - } - } - - function lock (box, msg, spinner) { - var options = {}; - if (typeof msg === 'object') { - options = msg; - } else { - options.msg = msg; - options.spinner = spinner; - } - if (!options.msg && options.msg !== 0) options.msg = ''; - w2utils.unlock(box); - $(box).prepend( - '
        '+ - '
        ' - ); - var $lock = $(box).find('.w2ui-lock'); - var mess = $(box).find('.w2ui-lock-msg'); - if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' }); - if (options.spinner === true) options.msg = '
        ' + options.msg; - if (options.opacity != null) $lock.css('opacity', options.opacity); - if (typeof $lock.fadeIn == 'function') { - $lock.fadeIn(200); - mess.html(options.msg).fadeIn(200); - } else { - $lock.show(); - mess.html(options.msg).show(0); - } - // hide all tags (do not hide overlays as the form can be in overlay) - $().w2tag(); - } - - function unlock (box) { - $(box).find('.w2ui-lock').remove(); - $(box).find('.w2ui-lock-msg').remove(); - } - - function getSize (el, type) { - var $el = $(el); - var bwidth = { - left: parseInt($el.css('border-left-width')) || 0, - right: parseInt($el.css('border-right-width')) || 0, - top: parseInt($el.css('border-top-width')) || 0, - bottom: parseInt($el.css('border-bottom-width')) || 0 - }; - var mwidth = { - left: parseInt($el.css('margin-left')) || 0, - right: parseInt($el.css('margin-right')) || 0, - top: parseInt($el.css('margin-top')) || 0, - bottom: parseInt($el.css('margin-bottom')) || 0 - }; - var pwidth = { - left: parseInt($el.css('padding-left')) || 0, - right: parseInt($el.css('padding-right')) || 0, - top: parseInt($el.css('padding-top')) || 0, - bottom: parseInt($el.css('padding-bottom')) || 0 - }; - switch (type) { - case 'top': return bwidth.top + mwidth.top + pwidth.top; - case 'bottom': return bwidth.bottom + mwidth.bottom + pwidth.bottom; - case 'left': return bwidth.left + mwidth.left + pwidth.left; - case 'right': return bwidth.right + mwidth.right + pwidth.right; - case 'width': return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width()); - case 'height': return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height()); - case '+width': return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right; - case '+height': return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom; - } - return 0; - } - - function lang (phrase) { - var translation = this.settings.phrases[phrase]; - if (translation == null) return phrase; else return translation; - } - - function locale (locale) { - if (!locale) locale = 'en-us'; - if (locale.length === 5) locale = 'locale/'+ locale +'.json'; - // load from the file - $.ajax({ - url : locale, - type : "GET", - dataType: "JSON", - async : false, - cache : false, - success : function (data, status, xhr) { - w2utils.settings = $.extend(true, w2utils.settings, data); - // apply translation to some prototype functions - var p = w2obj.grid.prototype; - for (var b in p.buttons) { - p.buttons[b].caption = w2utils.lang(p.buttons[b].caption); - p.buttons[b].hint = w2utils.lang(p.buttons[b].hint); - } - p.msgDelete = w2utils.lang(p.msgDelete); - p.msgNotJSON = w2utils.lang(p.msgNotJSON); - p.msgRefresh = w2utils.lang(p.msgRefresh); - }, - error : function (xhr, status, msg) { - console.log('ERROR: Cannot load locale '+ locale); - } - }); - } - - function scrollBarSize () { - if (tmp.scrollBarSize) return tmp.scrollBarSize; - var html = - '
        '+ - '
        1
        '+ - '
        '; - $('body').append(html); - tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width(); - $('#_scrollbar_width').remove(); - if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+ - return tmp.scrollBarSize; - } + var tmp = {}; // for some temp variables + var obj = { + settings : { + "locale" : "en-us", + "date_format" : "m/d/yyyy", + "date_display" : "Mon d, yyyy", + "time_format" : "h12", + "currencyPrefix" : "$", + "currencySuffix" : "", + "currencyPrecision" : 2, + "groupSymbol" : ",", + "shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + "fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + "shortdays" : ["M", "T", "W", "T", "F", "S", "S"], + "fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + "RESTfull" : false, + "phrases" : {} // empty object for english phrases + }, + isInt : isInt, + isFloat : isFloat, + isMoney : isMoney, + isHex : isHex, + isAlphaNumeric : isAlphaNumeric, + isEmail : isEmail, + isDate : isDate, + isTime : isTime, + age : age, + date : date, + size : size, + formatNumber : formatNumber, + formatDate : formatDate, + formatTime : formatTime, + formatDateTime : formatDateTime, + stripTags : stripTags, + encodeTags : encodeTags, + escapeId : escapeId, + base64encode : base64encode, + base64decode : base64decode, + transition : transition, + lock : lock, + unlock : unlock, + lang : lang, + locale : locale, + getSize : getSize, + scrollBarSize : scrollBarSize, + checkName : checkName, + checkUniqueId : checkUniqueId + }; + return obj; + + function isInt (val) { + var re = /^[-+]?[0-9]+$/; + return re.test(val); + } + + function isFloat (val) { + return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)); + } + + function isMoney (val) { + var se = w2utils.settings; + var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +'[-+]?[0-9]*[\.]?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i'); + if (typeof val === 'string') { + val = val.replace(new RegExp(se.groupSymbol, 'g'), ''); + } + if (typeof val === 'object' || val === '') return false; + return re.test(val); + } + + function isHex (val) { + var re = /^[a-fA-F0-9]+$/; + return re.test(val); + } + + function isAlphaNumeric (val) { + var re = /^[a-zA-Z0-9_-]+$/; + return re.test(val); + } + + function isEmail (val) { + var email = /^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; + return email.test(val); + } + + function isDate (val, format, retDate) { + if (!val) return false; + + var dt = 'Invalid Date'; + var month, day, year; + + if (format == null) format = w2utils.settings.date_format; + + if (typeof val.getUTCFullYear === 'function' && typeof val.getUTCMonth === 'function' && typeof val.getUTCDate === 'function') { + year = val.getUTCFullYear(); + month = val.getUTCMonth(); + day = val.getUTCDate(); + } else if (typeof val.getFullYear === 'function' && typeof val.getMonth === 'function' && typeof val.getDate === 'function') { + year = val.getFullYear(); + month = val.getMonth(); + day = val.getDate(); + } else { + val = String(val); + // convert month formats + if (RegExp('mon', 'ig').test(format)) { + format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) { + var t = w2utils.settings.fullmonths[m]; + val = val.replace(RegExp(t, 'ig'), (parseInt(m) + 1)).replace(RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)); + } + } + // format date + var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); + var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); + if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + } + if (!isInt(year)) return false; + if (!isInt(month)) return false; + if (!isInt(day)) return false; + year = +year; + month = +month; + day = +day; + dt = new Date(year, month - 1, day); + // do checks + if (month == null) return false; + if (dt === 'Invalid Date') return false; + if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false; + if (retDate === true) return dt; else return true; + } + + function isTime (val, retTime) { + // Both formats 10:20pm and 22:20 + if (val == null) return false; + var max, pm; + // -- process american format + val = String(val); + val = val.toUpperCase(); + pm = val.indexOf('PM') >= 0; + var ampm = (pm || val.indexOf('AM') >= 0); + if (ampm) max = 12; else max = 24; + val = val.replace('AM', '').replace('PM', ''); + val = $.trim(val); + // --- + var tmp = val.split(':'); + var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0); + // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: + if ((!ampm || tmp.length !== 1) && tmp.length !== 2) { return false; } + if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; } + if (tmp.length === 2 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; } + // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). + // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. + if (!ampm && max === h && m !== 0) { return false; } + if (ampm && tmp.length === 1 && h === 0) { return false; } + + if (retTime === true) { + if (pm) h += 12; + return { + hours: h, + minutes: m + }; + } + return true; + } + + function age (dateStr) { + if (dateStr === '' || dateStr == null) return ''; + var d1 = new Date(dateStr); + if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps + if (d1 === 'Invalid Date') return ''; + + var d2 = new Date(); + var sec = (d2.getTime() - d1.getTime()) / 1000; + var amount = ''; + var type = ''; + if (sec < 0) { + amount = 'future'; + type = ''; + } else if (sec < 60) { + amount = Math.floor(sec); + type = 'sec'; + if (sec < 0) { amount = 0; type = 'sec'; } + } else if (sec < 60*60) { + amount = Math.floor(sec/60); + type = 'min'; + } else if (sec < 24*60*60) { + amount = Math.floor(sec/60/60); + type = 'hour'; + } else if (sec < 30*24*60*60) { + amount = Math.floor(sec/24/60/60); + type = 'day'; + } else if (sec < 12*30*24*60*60) { + amount = Math.floor(sec/30/24/60/60*10)/10; + type = 'month'; + } else if (sec >= 12*30*24*60*60) { + amount = Math.floor(sec/12/30/24/60/60*10)/10; + type = 'year'; + } + return amount + ' ' + type + (amount > 1 ? 's' : ''); + } + + function date (dateStr) { + if (dateStr === '' || dateStr == null) return ''; + var d1 = new Date(dateStr); + if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps + if (d1 === 'Invalid Date') return ''; + + var months = w2utils.settings.shortmonths; + var d2 = new Date(); // today + var d3 = new Date(); + d3.setTime(d3.getTime() - 86400000); // yesterday + + var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear(); + var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear(); + var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear(); + + var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var dsp = dd1; + if (dd1 === dd2) dsp = time; + if (dd1 === dd3) dsp = w2utils.lang('Yesterday'); + + return ''+ dsp +''; + } + + function size (sizeStr) { + if (!w2utils.isFloat(sizeStr) || sizeStr === '') return ''; + sizeStr = parseFloat(sizeStr); + if (sizeStr === 0) return 0; + var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB']; + var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ); + return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + sizes[i]; + } + + function formatNumber (val, groupSymbol) { + var ret = ''; + if (groupSymbol == null) groupSymbol = w2utils.settings.groupSymbol || ','; + // check if this is a number + if (w2utils.isFloat(val) || w2utils.isInt(val) || w2utils.isMoney(val)) { + tmp = String(val).split('.'); + ret = String(tmp[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + groupSymbol); + if (tmp[1] != null) ret += '.' + tmp[1]; + } + return ret; + } + + function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + var months = w2utils.settings.shortmonths; + var fullMonths = w2utils.settings.fullmonths; + if (!format) format = this.settings.date_format; + if (dateStr === '' || dateStr == null) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (dt === 'Invalid Date') return ''; + + var year = dt.getFullYear(); + var month = dt.getMonth(); + var date = dt.getDate(); + return format.toLowerCase() + .replace('month', w2utils.settings.fullmonths[month]) + .replace('mon', w2utils.settings.shortmonths[month]) + .replace(/yyyy/g, year) + .replace(/yyy/g, year) + .replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2)) + .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceeded by a letter + .replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1)) + .replace(/dd/g, (date < 10 ? '0' : '') + date) + .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceeded by a letter + } + + function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + var months = w2utils.settings.shortmonths; + var fullMonths = w2utils.settings.fullmonths; + if (!format) format = (this.settings.time_format === 'h12' ? 'hh:mi pm' : 'h24:mi'); + if (dateStr === '' || dateStr == null) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (w2utils.isTime(dateStr)) { + var tmp = w2utils.isTime(dateStr, true); + dt = new Date(); + dt.setHours(tmp.hours); + dt.setMinutes(tmp.minutes); + } + if (dt === 'Invalid Date') return ''; + + var type = 'am'; + var hour = dt.getHours(); + var h24 = dt.getHours(); + var min = dt.getMinutes(); + var sec = dt.getSeconds(); + if (min < 10) min = '0' + min; + if (sec < 10) sec = '0' + sec; + if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { + if (hour >= 12) type = 'pm'; + if (hour > 12) hour = hour - 12; + } + return format.toLowerCase() + .replace('am', type) + .replace('pm', type) + .replace('hh', hour) + .replace('h24', h24) + .replace('mm', min) + .replace('mi', min) + .replace('ss', sec) + .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceeded by a letter + } + + function formatDateTime(dateStr, format) { + var fmt; + if (typeof format !== 'string') { + fmt = [this.settings.date_format, this.settings.time_format]; + } else { + fmt = format.split('|'); + } + return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]); + } + + function stripTags (html) { + if (html === null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = $.trim(String(html).replace(/(<([^>]+)>)/ig, "")); + break; + case 'object': + for (var a in html) html[a] = this.stripTags(html[a]); + break; + } + return html; + } + + function encodeTags (html) { + if (html === null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = String(html).replace(/&/g, "&").replace(/>/g, ">").replace(/\|\/? {}\\])/g, '\\$1'); + } + + function base64encode (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = utf8_encode(input); + + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); + } + + function utf8_encode (string) { + var string = String(string).replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + } + + return output; + } + + function base64decode (input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 !== 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 !== 64) { + output = output + String.fromCharCode(chr3); + } + } + output = utf8_decode(output); + + function utf8_decode (utftext) { + var string = ""; + var i = 0; + var c = 0, c2, c3; + + while ( i < utftext.length ) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + + return string; + } + + return output; + } + + function transition (div_old, div_new, type, callBack) { + var width = $(div_old).width(); + var height = $(div_old).height(); + var time = 0.5; + + if (!div_old || !div_new) { + console.log('ERROR: Cannot do transition when one of the divs is null'); + return; + } + + div_old.parentNode.style.cssText += cross('perspective', '700px') +'; overflow: hidden;'; + div_old.style.cssText += '; position: absolute; z-index: 1019; '+ cross('backface-visibility', 'hidden'); + div_new.style.cssText += '; position: absolute; z-index: 1020; '+ cross('backface-visibility', 'hidden'); + + switch (type) { + case 'slide-left': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d('+ width + 'px, 0, 0)', 'translate('+ width +'px, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); + }, 1); + break; + + case 'slide-right': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0px, 0, 0)', 'translate(0px, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d('+ width +'px, 0, 0)', 'translate('+ width +'px, 0)'); + }, 1); + break; + + case 'slide-down': + // init divs + div_old.style.cssText += 'overflow: hidden; z-index: 1; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; z-index: 0; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); + }, 1); + break; + + case 'slide-up': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + }, 1); + break; + + case 'flip-left': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(-180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(180deg)'); + }, 1); + break; + + case 'flip-right': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(-180deg)'); + }, 1); + break; + + case 'flip-down': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(-180deg)'); + }, 1); + break; + + case 'flip-up': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(-180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(180deg)'); + }, 1); + break; + + case 'pop-in': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') + '; '+ cross('transform', 'scale(.8)') + '; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time+'s') +';'; + }, 1); + break; + + case 'pop-out': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1.7)') +'; opacity: 0;'; + }, 1); + break; + + default: + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time +'s') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time +'s'); + }, 1); + break; + } + + setTimeout(function () { + if (type === 'slide-down') { + $(div_old).css('z-index', '1019'); + $(div_new).css('z-index', '1020'); + } + if (div_new) { + $(div_new).css({ + 'opacity': '1', + '-webkit-transition': '', + '-moz-transition': '', + '-ms-transition': '', + '-o-transition': '', + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '', + '-webkit-backface-visibility': '', + '-moz-backface-visibility': '', + '-ms-backface-visibility': '', + '-o-backface-visibility': '' + }); + } + if (div_old) { + $(div_old).css({ + 'opacity': '1', + '-webkit-transition': '', + '-moz-transition': '', + '-ms-transition': '', + '-o-transition': '', + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '', + '-webkit-backface-visibility': '', + '-moz-backface-visibility': '', + '-ms-backface-visibility': '', + '-o-backface-visibility': '' + }); + if (div_old.parentNode) $(div_old.parentNode).css({ + '-webkit-perspective': '', + '-moz-perspective': '', + '-ms-perspective': '', + '-o-perspective': '' + }); + } + if (typeof callBack === 'function') callBack(); + }, time * 1000); + + function cross(property, value, none_webkit_value) { + var isWebkit=!!window.webkitURL; // jQuery no longer supports $.browser - RR + if (!isWebkit && typeof none_webkit_value !== 'undefined') value = none_webkit_value; + return ';'+ property +': '+ value +'; -webkit-'+ property +': '+ value +'; -moz-'+ property +': '+ value +'; '+ + '-ms-'+ property +': '+ value +'; -o-'+ property +': '+ value +';'; + } + } + + function lock (box, msg, spinner) { + var options = {}; + if (typeof msg === 'object') { + options = msg; + } else { + options.msg = msg; + options.spinner = spinner; + } + if (!options.msg && options.msg !== 0) options.msg = ''; + w2utils.unlock(box); + $(box).prepend( + '
        '+ + '
        ' + ); + var $lock = $(box).find('.w2ui-lock'); + var mess = $(box).find('.w2ui-lock-msg'); + if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' }); + if (options.spinner === true) options.msg = '
        ' + options.msg; + if (options.opacity != null) $lock.css('opacity', options.opacity); + if (typeof $lock.fadeIn == 'function') { + $lock.fadeIn(200); + mess.html(options.msg).fadeIn(200); + } else { + $lock.show(); + mess.html(options.msg).show(0); + } + // hide all tags (do not hide overlays as the form can be in overlay) + $().w2tag(); + } + + function unlock (box) { + $(box).find('.w2ui-lock').remove(); + $(box).find('.w2ui-lock-msg').remove(); + } + + function getSize (el, type) { + var $el = $(el); + var bwidth = { + left : parseInt($el.css('border-left-width')) || 0, + right : parseInt($el.css('border-right-width')) || 0, + top : parseInt($el.css('border-top-width')) || 0, + bottom : parseInt($el.css('border-bottom-width')) || 0 + }; + var mwidth = { + left : parseInt($el.css('margin-left')) || 0, + right : parseInt($el.css('margin-right')) || 0, + top : parseInt($el.css('margin-top')) || 0, + bottom : parseInt($el.css('margin-bottom')) || 0 + }; + var pwidth = { + left : parseInt($el.css('padding-left')) || 0, + right : parseInt($el.css('padding-right')) || 0, + top : parseInt($el.css('padding-top')) || 0, + bottom : parseInt($el.css('padding-bottom')) || 0 + }; + switch (type) { + case 'top' : return bwidth.top + mwidth.top + pwidth.top; + case 'bottom' : return bwidth.bottom + mwidth.bottom + pwidth.bottom; + case 'left' : return bwidth.left + mwidth.left + pwidth.left; + case 'right' : return bwidth.right + mwidth.right + pwidth.right; + case 'width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width()); + case 'height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height()); + case '+width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right; + case '+height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom; + } + return 0; + } + + function lang (phrase) { + var translation = this.settings.phrases[phrase]; + if (translation == null) return phrase; else return translation; + } + + function locale (locale) { + if (!locale) locale = 'en-us'; + if (locale.length === 5) locale = 'locale/'+ locale +'.json'; + // load from the file + $.ajax({ + url : locale, + type : "GET", + dataType : "JSON", + async : false, + cache : false, + success : function (data, status, xhr) { + w2utils.settings = $.extend(true, w2utils.settings, data); + // apply translation to some prototype functions + var p = w2obj.grid.prototype; + for (var b in p.buttons) { + p.buttons[b].caption = w2utils.lang(p.buttons[b].caption); + p.buttons[b].hint = w2utils.lang(p.buttons[b].hint); + } + p.msgDelete = w2utils.lang(p.msgDelete); + p.msgNotJSON = w2utils.lang(p.msgNotJSON); + p.msgRefresh = w2utils.lang(p.msgRefresh); + }, + error : function (xhr, status, msg) { + console.log('ERROR: Cannot load locale '+ locale); + } + }); + } + + function scrollBarSize () { + if (tmp.scrollBarSize) return tmp.scrollBarSize; + var html = + '
        '+ + '
        1
        '+ + '
        '; + $('body').append(html); + tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width(); + $('#_scrollbar_width').remove(); + if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+ + return tmp.scrollBarSize; + } function checkName (params, component) { // was w2checkNameParam - if (!params || typeof params.name === 'undefined') { - console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().'); - return false; - } - if (typeof w2ui[params.name] !== 'undefined') { - console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').'); - return false; - } - if (!w2utils.isAlphaNumeric(params.name)) { - console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); - return false; - } - return true; - } - - function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId - if (!$.isArray(items)) items = [items]; - for (var i = 0; i < items.length; i++) { - if (items[i].id === id) { - console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')'); - return false; - } - } - return true; - } + if (!params || typeof params.name === 'undefined') { + console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().'); + return false; + } + if (typeof w2ui[params.name] !== 'undefined') { + console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').'); + return false; + } + if (!w2utils.isAlphaNumeric(params.name)) { + console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); + return false; + } + return true; + } + + function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId + if (!$.isArray(items)) items = [items]; + for (var i = 0; i < items.length; i++) { + if (items[i].id === id) { + console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')'); + return false; + } + } + return true; + } })(); /*********************************************************** @@ -876,102 +876,102 @@ var w2utils = (function () { w2utils.event = { - on: function (eventData, handler) { - if (!$.isPlainObject(eventData)) eventData = { type: eventData }; - eventData = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, eventData); - - if (!eventData.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; } - if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; } - this.handlers.push({ event: eventData, handler: handler }); - }, - - off: function (eventData, handler) { - if (!$.isPlainObject(eventData)) eventData = { type: eventData }; - eventData = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, eventData); - - if (!eventData.type) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; } - if (!handler) { handler = null; } - // remove handlers - var newHandlers = []; - for (var h = 0, len = this.handlers.length; h < len; h++) { - var t = this.handlers[h]; - if ((t.event.type === eventData.type || eventData.type === '*') && - (t.event.target === eventData.target || eventData.target === null) && - (t.handler === handler || handler === null)) - { - // match - } else { - newHandlers.push(t); - } - } - this.handlers = newHandlers; - }, - - trigger: function (eventData) { - var eventData = $.extend({ type: null, phase: 'before', target: null }, eventData, { - isStopped: false, isCancelled: false, - preventDefault : function () { this.isCancelled = true; }, - stopPropagation : function () { this.isStopped = true; } - }); - if (eventData.phase === 'before') eventData.onComplete = null; - var args, fun, tmp; - if (eventData.target == null) eventData.target = null; - // process events in REVERSE order - for (var h = this.handlers.length-1; h >= 0; h--) { - var item = this.handlers[h]; - if ((item.event.type === eventData.type || item.event.type === '*') && - (item.event.target === eventData.target || item.event.target === null) && - (item.event.execute === eventData.phase || item.event.execute === '*' || item.event.phase === '*')) - { - eventData = $.extend({}, item.event, eventData); - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(item.handler); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - item.handler.call(this, eventData.target, eventData); // old way for back compatibility - } else { - item.handler.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true - } - } - // main object events - var funName = 'on' + eventData.type.substr(0,1).toUpperCase() + eventData.type.substr(1); - if (eventData.phase === 'before' && typeof this[funName] === 'function') { - fun = this[funName]; - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(fun); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - fun.call(this, eventData.target, eventData); // old way for back compatibility - } else { - fun.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true - } - // item object events - if (eventData.object != null && eventData.phase === 'before' && - typeof eventData.object[funName] === 'function') - { - fun = eventData.object[funName]; - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(fun); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - fun.call(this, eventData.target, eventData); // old way for back compatibility - } else { - fun.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; - } - // execute onComplete - if (eventData.phase === 'after' && typeof eventData.onComplete === 'function') eventData.onComplete.call(this, eventData); - - return eventData; - } + on: function (eventData, handler) { + if (!$.isPlainObject(eventData)) eventData = { type: eventData }; + eventData = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, eventData); + + if (!eventData.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; } + if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; } + this.handlers.push({ event: eventData, handler: handler }); + }, + + off: function (eventData, handler) { + if (!$.isPlainObject(eventData)) eventData = { type: eventData }; + eventData = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, eventData); + + if (!eventData.type) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; } + if (!handler) { handler = null; } + // remove handlers + var newHandlers = []; + for (var h = 0, len = this.handlers.length; h < len; h++) { + var t = this.handlers[h]; + if ((t.event.type === eventData.type || eventData.type === '*') && + (t.event.target === eventData.target || eventData.target === null) && + (t.handler === handler || handler === null)) + { + // match + } else { + newHandlers.push(t); + } + } + this.handlers = newHandlers; + }, + + trigger: function (eventData) { + var eventData = $.extend({ type: null, phase: 'before', target: null }, eventData, { + isStopped: false, isCancelled: false, + preventDefault : function () { this.isCancelled = true; }, + stopPropagation : function () { this.isStopped = true; } + }); + if (eventData.phase === 'before') eventData.onComplete = null; + var args, fun, tmp; + if (eventData.target == null) eventData.target = null; + // process events in REVERSE order + for (var h = this.handlers.length-1; h >= 0; h--) { + var item = this.handlers[h]; + if ((item.event.type === eventData.type || item.event.type === '*') && + (item.event.target === eventData.target || item.event.target === null) && + (item.event.execute === eventData.phase || item.event.execute === '*' || item.event.phase === '*')) + { + eventData = $.extend({}, item.event, eventData); + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(item.handler); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + item.handler.call(this, eventData.target, eventData); // old way for back compatibility + } else { + item.handler.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true + } + } + // main object events + var funName = 'on' + eventData.type.substr(0,1).toUpperCase() + eventData.type.substr(1); + if (eventData.phase === 'before' && typeof this[funName] === 'function') { + fun = this[funName]; + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, eventData.target, eventData); // old way for back compatibility + } else { + fun.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true + } + // item object events + if (eventData.object != null && eventData.phase === 'before' && + typeof eventData.object[funName] === 'function') + { + fun = eventData.object[funName]; + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, eventData.target, eventData); // old way for back compatibility + } else { + fun.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; + } + // execute onComplete + if (eventData.phase === 'after' && typeof eventData.onComplete === 'function') eventData.onComplete.call(this, eventData); + + return eventData; + } }; /*********************************************************** @@ -983,52 +983,52 @@ w2utils.event = { *********************************************************/ w2utils.keyboard = (function (obj) { - // private scope - var w2ui_name = null; - - obj.active = active; - obj.clear = clear; - obj.register = register; - - init(); - return obj; - - function init() { - $(document).on('keydown', keydown); - $(document).on('mousedown', mousedown); - } - - function keydown (event) { - var tag = event.target.tagName; - if ($.inArray(tag, ['INPUT', 'SELECT', 'TEXTAREA']) !== -1) return; - if ($(event.target).prop('contenteditable') === 'true') return; - if (!w2ui_name) return; - // pass to appropriate widget - if (w2ui[w2ui_name] && typeof w2ui[w2ui_name].keydown === 'function') { - w2ui[w2ui_name].keydown.call(w2ui[w2ui_name], event); - } - } - - function mousedown (event) { - var tag = event.target.tagName; - var obj = $(event.target).parents('.w2ui-reset'); - if (obj.length > 0) { - var name = obj.attr('name'); - if (w2ui[name] && w2ui[name].keyboard) w2ui_name = name; - } - } - - function active (new_w2ui_name) { - if (typeof new_w2ui_name !== 'undefined') w2ui_name = new_w2ui_name; - return w2ui_name; - } - - function clear () { - w2ui_name = null; - } - - function register () { - } + // private scope + var w2ui_name = null; + + obj.active = active; + obj.clear = clear; + obj.register = register; + + init(); + return obj; + + function init() { + $(document).on('keydown', keydown); + $(document).on('mousedown', mousedown); + } + + function keydown (event) { + var tag = event.target.tagName; + if ($.inArray(tag, ['INPUT', 'SELECT', 'TEXTAREA']) !== -1) return; + if ($(event.target).prop('contenteditable') === 'true') return; + if (!w2ui_name) return; + // pass to appropriate widget + if (w2ui[w2ui_name] && typeof w2ui[w2ui_name].keydown === 'function') { + w2ui[w2ui_name].keydown.call(w2ui[w2ui_name], event); + } + } + + function mousedown (event) { + var tag = event.target.tagName; + var obj = $(event.target).parents('.w2ui-reset'); + if (obj.length > 0) { + var name = obj.attr('name'); + if (w2ui[name] && w2ui[name].keyboard) w2ui_name = name; + } + } + + function active (new_w2ui_name) { + if (typeof new_w2ui_name !== 'undefined') w2ui_name = new_w2ui_name; + return w2ui_name; + } + + function clear () { + w2ui_name = null; + } + + function register () { + } })({}); @@ -1040,6576 +1040,6576 @@ w2utils.keyboard = (function (obj) { (function () { - $.fn.w2render = function (name) { - if ($(this).length > 0) { - if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]); - if (typeof name === 'object') name.render($(this)[0]); - } - }; - - $.fn.w2destroy = function (name) { - if (!name && this.length > 0) name = this.attr('name'); - if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy(); - if (typeof name === 'object') name.destroy(); - }; - - $.fn.w2marker = function (str) { - if (str === '' || str == null) { // remove marker - return $(this).each(function (index, el) { - el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark - }); - } else { // add marker - return $(this).each(function (index, el) { - if (typeof str === 'string') str = [str]; - el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark - for (var s in str) { - var tmp = str[s]; - if (typeof tmp !== 'string') tmp = String(tmp); - // escape regex special chars - tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&').replace(//g, '<'); - var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags - el.innerHTML = el.innerHTML.replace(regex, replaceValue); - } - function replaceValue(matched) { // mark new - return '' + matched + ''; - } - }); - } - }; - - // -- w2tag - appears on the right side from element, there can be multiple on screen at a time - - $.fn.w2tag = function (text, options) { - if (!$.isPlainObject(options)) options = {}; - if (!$.isPlainObject(options.css)) options.css = {}; - if (typeof options['class'] === 'undefined') options['class'] = ''; - // remove all tags - if ($(this).length === 0) { - $('.w2ui-tag').each(function (index, elem) { - var opt = $(elem).data('options'); - if (opt == null) opt = {}; - $($(elem).data('taged-el')).removeClass( opt['class'] ); - clearInterval($(elem).data('timer')); - $(elem).remove(); - }); - return; - } - return $(this).each(function (index, el) { - // show or hide tag - var tagOrigID = el.id; - var tagID = w2utils.escapeId(el.id); - if (text === '' || text == null) { - $('#w2ui-tag-'+tagID).css('opacity', 0); - setTimeout(function () { - // remmove element - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - $('#w2ui-tag-'+tagID).remove(); - }, 300); - } else { - // remove elements - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - $('#w2ui-tag-'+tagID).remove(); - // insert - $('body').append( - '
        '); - - var timer = setInterval(function () { - // monitor if destroyed - if ($(el).length === 0 || ($(el).offset().left === 0 && $(el).offset().top === 0)) { - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - tmp_hide(); - return; - } - // monitor if moved - if ($('#w2ui-tag-'+tagID).data('position') !== ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) { - $('#w2ui-tag-'+tagID).css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s', - left: ($(el).offset().left + el.offsetWidth) + 'px', - top: $(el).offset().top + 'px' - }).data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top); - } - }, 100); - setTimeout(function () { - if (!$(el).offset()) return; - $('#w2ui-tag-'+tagID).css({ - opacity: '1', - left: ($(el).offset().left + el.offsetWidth) + 'px', - top: $(el).offset().top + 'px' - }).html('
        '+ text +'
        ') - .data('text', text) - .data('taged-el', el) - .data('options', options) - .data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) - .data('timer', timer); - $(el).off('keypress', tmp_hide).on('keypress', tmp_hide).off('change', tmp_hide).on('change', tmp_hide) - .css(options.css).addClass(options['class']); - if (typeof options.onShow === 'function') options.onShow(); - }, 1); - var originalCSS = ''; - if ($(el).length > 0) originalCSS = $(el)[0].style.cssText; - // bind event to hide it - function tmp_hide() { - $tag = $('#w2ui-tag-'+tagID); - if ($tag.length <= 0) return; - clearInterval($tag.data('timer')); - $tag.remove(); - $(el).off('keypress', tmp_hide).removeClass(options['class']); - if ($(el).length > 0) $(el)[0].style.cssText = originalCSS; - if (typeof options.onHide === 'function') options.onHide(); - } - } - }); - }; - - // w2overlay - appears under the element, there can be only one at a time - - $.fn.w2overlay = function (html, options) { - var obj = this; - var name = ''; - var defaults = { - name : null, // it not null, then allows multiple concurent overlays - align : 'none', // can be none, left, right, both - left : 0, // offset left - top : 0, // offset top - tipLeft : 30, // tip offset left - width : 0, // fixed width - height : 0, // fixed height - maxWidth : null, // max width if any - maxHeight : null, // max height if any - style : '', // additional style for main div - 'class' : '', // additional class name for main dvi - onShow : null, // event on show - onHide : null, // event on hide - openAbove : false, // show abover control - tmp : {} - }; - if (!$.isPlainObject(options)) options = {}; - options = $.extend({}, defaults, options); - if (options.name) name = '-' + options.name; - // if empty then hide - var tmp_hide; - if (this.length === 0 || html === '' || html == null) { - if ($('#w2ui-overlay'+ name).length > 0) { - tmp_hide = $('#w2ui-overlay'+ name)[0].hide; - if (typeof tmp_hide === 'function') tmp_hide(); - } else { - $('#w2ui-overlay'+ name).remove(); - } - return $(this); - } - if ($('#w2ui-overlay'+ name).length > 0) { - tmp_hide = $('#w2ui-overlay'+ name)[0].hide; - $(document).off('click', tmp_hide); - if (typeof tmp_hide === 'function') tmp_hide(); - } - $('body').append( - '' - ); - // init - var div1 = $('#w2ui-overlay'+ name); - var div2 = div1.find(' > div'); - div2.html(html); - // pick bg color of first div - var bc = div2.css('background-color'); - if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css('background-color', bc); - - div1.data('element', obj.length > 0 ? obj[0] : null) - .data('options', options) - .data('position', $(obj).offset().left + 'x' + $(obj).offset().top) - .fadeIn('fast').on('mousedown', function (event) { - $('#w2ui-overlay'+ name).data('keepOpen', true); - if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName) === -1) event.preventDefault(); - }); - div1[0].hide = hide; - div1[0].resize = resize; - - // need time to display - resize(); - setTimeout(function () { - resize(); - $(document).off('click', hide).on('click', hide); - if (typeof options.onShow === 'function') options.onShow(); - }, 10); - - monitor(); - return $(this); - - // monitor position - function monitor() { - var tmp = $('#w2ui-overlay'+ name); - if (tmp.data('element') !== obj[0]) return; // it if it different overlay - if (tmp.length === 0) return; - var pos = $(obj).offset().left + 'x' + $(obj).offset().top; - if (tmp.data('position') !== pos) { - hide(); - } else { - setTimeout(monitor, 250); - } - } - - // click anywhere else hides the drop down - function hide () { - var div1 = $('#w2ui-overlay'+ name); - if (div1.data('keepOpen') === true) { - div1.removeData('keepOpen'); - return; - } - var result; - if (typeof options.onHide === 'function') result = options.onHide(); - if (result === false) return; - div1.remove(); - $(document).off('click', hide); - clearInterval(div1.data('timer')); - } - - function resize () { - var div1 = $('#w2ui-overlay'+ name); - var div2 = div1.find(' > div'); - // if goes over the screen, limit height and width - if (div1.length > 0) { - div2.height('auto').width('auto'); - // width/height - var overflowX = false; - var overflowY = false; - var h = div2.height(); - var w = div2.width(); - if (options.width && options.width < w) w = options.width; - if (w < 30) w = 30; - // if content of specific height - if (options.tmp.contentHeight) { - h = options.tmp.contentHeight; - div2.height(h); - setTimeout(function () { - if (div2.height() > div2.find('div.menu > table').height()) { - div2.find('div.menu').css('overflow-y', 'hidden'); - } - }, 1); - setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); - } - if (options.tmp.contentWidth) { - w = options.tmp.contentWidth; - div2.width(w); - setTimeout(function () { - if (div2.width() > div2.find('div.menu > table').width()) { - div2.find('div.menu').css('overflow-x', 'hidden'); - } - }, 1); - setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); - } - // alignment - switch (options.align) { - case 'both': - options.left = 17; - if (options.width === 0) options.width = w2utils.getSize($(obj), 'width'); - break; - case 'left': - options.left = 17; - break; - case 'right': - options.tipLeft = w - 45; - options.left = w2utils.getSize($(obj), 'width') - w + 10; - break; - } - // adjust position - var tmp = (w - 17) / 2; - var boxLeft = options.left; - var boxWidth = options.width; - var tipLeft = options.tipLeft; - if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto'); - if (tmp < 25) { - boxLeft = 25 - tmp; - tipLeft = Math.floor(tmp); - } - // Y coord - div1.css({ - top : (obj.offset().top + w2utils.getSize(obj, 'height') + options.top + 7) + 'px', - left : ((obj.offset().left > 25 ? obj.offset().left : 25) + boxLeft) + 'px', - 'min-width' : boxWidth, - 'min-height': (options.height ? options.height : 'auto') - }); - // $(window).height() - has a problem in FF20 - var maxHeight = window.innerHeight + $(document).scrollTop() - div2.offset().top - 7; - var maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; - if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) { - // show on top - maxHeight = div2.offset().top - $(document).scrollTop() - 7; - if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; - if (h > maxHeight) { - overflowY = true; - div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); - h = maxHeight; - } - div1.css('top', ($(obj).offset().top - h - 24 + options.top) + 'px'); - div1.find('>style').html( - '#w2ui-overlay'+ name +':before { display: none; margin-left: '+ parseInt(tipLeft) +'px; }'+ - '#w2ui-overlay'+ name +':after { display: block; margin-left: '+ parseInt(tipLeft) +'px; }' - ); - } else { - // show under - if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; - if (h > maxHeight) { - overflowY = true; - div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); - } - div1.find('>style').html( - '#w2ui-overlay'+ name +':before { display: block; margin-left: '+ parseInt(tipLeft) +'px; }'+ - '#w2ui-overlay'+ name +':after { display: none; margin-left: '+ parseInt(tipLeft) +'px; }' - ); - } - // check width - w = div2.width(); - maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; - if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth; - if (w > maxWidth && options.align !== 'both') { - options.align = 'right'; - setTimeout(function () { resize(); }, 1); - } - // check scroll bar - if (overflowY && overflowX) div2.width(w + w2utils.scrollBarSize() + 2); - } - } - }; - - $.fn.w2menu = function (menu, options) { - /* - ITEM STRUCTURE - item : { - id : null, - text : '', - style : '', - hidden : true - ... - } - */ - var defaults = { - index : null, // current selected - items : [], - render : null, - msgNoItems : 'No items', - onSelect : null, - tmp : {} - }; - var obj = this; - var name = ''; - if (menu === 'refresh') { - // if not show - call blur - if ($('#w2ui-overlay'+ name).length > 0) { - options = $.extend($.fn.w2menuOptions, options); - var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); - $('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML()); - $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); - mresize(); - } else { - $(this).w2menu(options); - } - } else { - if (arguments.length === 1) options = menu; else options.items = menu; - if (typeof options !== 'object') options = {}; - options = $.extend({}, defaults, options); - $.fn.w2menuOptions = options; - if (options.name) name = '-' + options.name; - if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select; - if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender; - // since only one overlay can exist at a time - $.fn.w2menuHandler = function (event, index) { - if (typeof options.onSelect === 'function') { - // need time so that menu first hides - setTimeout(function () { - options.onSelect({ - index : index, - item : options.items[index], - originalEvent: event - }); - }, 10); - } - }; - var html = ''; - if (options.search) { - html += - '
        '+ - ' '+ - ' '+ - '
        '; - options.style += ';background-color: #ECECEC'; - options.index = 0; - for (var i in options.items) options.items[i].hidden = false; - } - html += ''; - var ret = $(this).w2overlay(html, options); - setTimeout(function () { - $('#w2ui-overlay'+ name +' #menu-search') - .on('keyup', change) - .on('keydown', function (event) { - // cancel tab key - if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); } - }); - }, 200); - mresize(); - return ret; - } - - function mresize() { - setTimeout(function () { - // show selected - $('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected'); - var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']'); - var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); - cur.addClass('w2ui-selected'); - if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10); - if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width(); - $('#w2ui-overlay'+ name)[0].resize(); - // scroll into view - if (cur.length > 0) { - var top = cur[0].offsetTop - 5; // 5 is margin top - var el = $('#w2ui-overlay'+ name +' div.menu'); - var height = el.height(); - $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); - if (top < scrTop || top + cur.height() > scrTop + height) { - $('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); - } - } - }, 1); - } - - function change(event) { - var search = this.value; - var key = event.keyCode; - var cancel = false; - switch (key) { - case 13: // enter - $('#w2ui-overlay'+ name).remove(); - $.fn.w2menuHandler(event, options.index); - break; - case 9: // tab - case 27: // escape - $('#w2ui-overlay'+ name).remove(); - $.fn.w2menuHandler(event, -1); - break; - case 38: // up - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index--; - while (options.index > 0 && options.items[options.index].hidden) options.index--; - if (options.index === 0 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } - if (options.index < 0) options.index = 0; - cancel = true; - break; - case 40: // down - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index++; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (options.index === options.items.length-1 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index--; - } - if (options.index >= options.items.length) options.index = options.items.length - 1; - cancel = true; - break; - } - // filter - if (!cancel) { - var shown = 0; - for (var i in options.items) { - var item = options.items[i]; - var prefix = ''; - var suffix = ''; - if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^'; - if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$'; - try { - var re = new RegExp(prefix + search + suffix, 'i'); - if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true; - if (options.applyFilter !== true) item.hidden = false; - } catch (e) {} - // do not show selected items - if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true; - if (item.hidden !== true) shown++; - } - options.index = 0; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (shown <= 0) options.index = -1; - } - $(obj).w2menu('refresh', options); - mresize(); - } - - function getMenuHTML () { - if (options.spinner) { - return '
        '+ - '
        '+ - '
        Loading...
        '+ - '
        '; - } - var count = 0; - var menu_html = ''; - var img = null, icon = null; - for (var f = 0; f < options.items.length; f++) { - var mitem = options.items[f]; - if (typeof mitem === 'string') { - mitem = { id: mitem, text: mitem }; - } else { - if (mitem.text != null && mitem.id == null) mitem.id = mitem.text; - if (mitem.text == null && mitem.id != null) mitem.text = mitem.id; - if (mitem.caption != null) mitem.text = mitem.caption; - img = mitem.img; - icon = mitem.icon; - if (img == null) img = null; - if (icon == null) icon = null; - } - if (mitem.hidden !== true) { - var imgd = ''; - var txt = mitem.text; - if (typeof options.render === 'function') txt = options.render(mitem, options); - if (img) imgd = ''; - if (icon) imgd = ''; - // render only if non-empty - if (typeof txt !== 'undefined' && txt !== '' && !(/^-+$/.test(txt))) { - var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd'); - if (options.altRows !== true) bg = ''; - menu_html += - ''+ - imgd + - ' '+ - ''; - count++; - } else { - // horizontal line - menu_html += ''; - } - } - options.items[f] = mitem; - } - if (count === 0) { - menu_html += ''; - } - menu_html += "
        '+ txt +'
        '+ options.msgNoItems +'
        "; - return menu_html; - } - }; + $.fn.w2render = function (name) { + if ($(this).length > 0) { + if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]); + if (typeof name === 'object') name.render($(this)[0]); + } + }; + + $.fn.w2destroy = function (name) { + if (!name && this.length > 0) name = this.attr('name'); + if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy(); + if (typeof name === 'object') name.destroy(); + }; + + $.fn.w2marker = function (str) { + if (str === '' || str == null) { // remove marker + return $(this).each(function (index, el) { + el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark + }); + } else { // add marker + return $(this).each(function (index, el) { + if (typeof str === 'string') str = [str]; + el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark + for (var s in str) { + var tmp = str[s]; + if (typeof tmp !== 'string') tmp = String(tmp); + // escape regex special chars + tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&').replace(//g, '<'); + var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags + el.innerHTML = el.innerHTML.replace(regex, replaceValue); + } + function replaceValue(matched) { // mark new + return '' + matched + ''; + } + }); + } + }; + + // -- w2tag - appears on the right side from element, there can be multiple on screen at a time + + $.fn.w2tag = function (text, options) { + if (!$.isPlainObject(options)) options = {}; + if (!$.isPlainObject(options.css)) options.css = {}; + if (typeof options['class'] === 'undefined') options['class'] = ''; + // remove all tags + if ($(this).length === 0) { + $('.w2ui-tag').each(function (index, elem) { + var opt = $(elem).data('options'); + if (opt == null) opt = {}; + $($(elem).data('taged-el')).removeClass( opt['class'] ); + clearInterval($(elem).data('timer')); + $(elem).remove(); + }); + return; + } + return $(this).each(function (index, el) { + // show or hide tag + var tagOrigID = el.id; + var tagID = w2utils.escapeId(el.id); + if (text === '' || text == null) { + $('#w2ui-tag-'+tagID).css('opacity', 0); + setTimeout(function () { + // remmove element + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + $('#w2ui-tag-'+tagID).remove(); + }, 300); + } else { + // remove elements + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + $('#w2ui-tag-'+tagID).remove(); + // insert + $('body').append( + '
        '); + + var timer = setInterval(function () { + // monitor if destroyed + if ($(el).length === 0 || ($(el).offset().left === 0 && $(el).offset().top === 0)) { + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + tmp_hide(); + return; + } + // monitor if moved + if ($('#w2ui-tag-'+tagID).data('position') !== ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) { + $('#w2ui-tag-'+tagID).css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s', + left: ($(el).offset().left + el.offsetWidth) + 'px', + top: $(el).offset().top + 'px' + }).data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top); + } + }, 100); + setTimeout(function () { + if (!$(el).offset()) return; + $('#w2ui-tag-'+tagID).css({ + opacity: '1', + left: ($(el).offset().left + el.offsetWidth) + 'px', + top: $(el).offset().top + 'px' + }).html('
        '+ text +'
        ') + .data('text', text) + .data('taged-el', el) + .data('options', options) + .data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) + .data('timer', timer); + $(el).off('keypress', tmp_hide).on('keypress', tmp_hide).off('change', tmp_hide).on('change', tmp_hide) + .css(options.css).addClass(options['class']); + if (typeof options.onShow === 'function') options.onShow(); + }, 1); + var originalCSS = ''; + if ($(el).length > 0) originalCSS = $(el)[0].style.cssText; + // bind event to hide it + function tmp_hide() { + $tag = $('#w2ui-tag-'+tagID); + if ($tag.length <= 0) return; + clearInterval($tag.data('timer')); + $tag.remove(); + $(el).off('keypress', tmp_hide).removeClass(options['class']); + if ($(el).length > 0) $(el)[0].style.cssText = originalCSS; + if (typeof options.onHide === 'function') options.onHide(); + } + } + }); + }; + + // w2overlay - appears under the element, there can be only one at a time + + $.fn.w2overlay = function (html, options) { + var obj = this; + var name = ''; + var defaults = { + name : null, // it not null, then allows multiple concurent overlays + align : 'none', // can be none, left, right, both + left : 0, // offset left + top : 0, // offset top + tipLeft : 30, // tip offset left + width : 0, // fixed width + height : 0, // fixed height + maxWidth : null, // max width if any + maxHeight : null, // max height if any + style : '', // additional style for main div + 'class' : '', // additional class name for main dvi + onShow : null, // event on show + onHide : null, // event on hide + openAbove : false, // show abover control + tmp : {} + }; + if (!$.isPlainObject(options)) options = {}; + options = $.extend({}, defaults, options); + if (options.name) name = '-' + options.name; + // if empty then hide + var tmp_hide; + if (this.length === 0 || html === '' || html == null) { + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + if (typeof tmp_hide === 'function') tmp_hide(); + } else { + $('#w2ui-overlay'+ name).remove(); + } + return $(this); + } + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + $(document).off('click', tmp_hide); + if (typeof tmp_hide === 'function') tmp_hide(); + } + $('body').append( + '' + ); + // init + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + div2.html(html); + // pick bg color of first div + var bc = div2.css('background-color'); + if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css('background-color', bc); + + div1.data('element', obj.length > 0 ? obj[0] : null) + .data('options', options) + .data('position', $(obj).offset().left + 'x' + $(obj).offset().top) + .fadeIn('fast').on('mousedown', function (event) { + $('#w2ui-overlay'+ name).data('keepOpen', true); + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName) === -1) event.preventDefault(); + }); + div1[0].hide = hide; + div1[0].resize = resize; + + // need time to display + resize(); + setTimeout(function () { + resize(); + $(document).off('click', hide).on('click', hide); + if (typeof options.onShow === 'function') options.onShow(); + }, 10); + + monitor(); + return $(this); + + // monitor position + function monitor() { + var tmp = $('#w2ui-overlay'+ name); + if (tmp.data('element') !== obj[0]) return; // it if it different overlay + if (tmp.length === 0) return; + var pos = $(obj).offset().left + 'x' + $(obj).offset().top; + if (tmp.data('position') !== pos) { + hide(); + } else { + setTimeout(monitor, 250); + } + } + + // click anywhere else hides the drop down + function hide () { + var div1 = $('#w2ui-overlay'+ name); + if (div1.data('keepOpen') === true) { + div1.removeData('keepOpen'); + return; + } + var result; + if (typeof options.onHide === 'function') result = options.onHide(); + if (result === false) return; + div1.remove(); + $(document).off('click', hide); + clearInterval(div1.data('timer')); + } + + function resize () { + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + // if goes over the screen, limit height and width + if (div1.length > 0) { + div2.height('auto').width('auto'); + // width/height + var overflowX = false; + var overflowY = false; + var h = div2.height(); + var w = div2.width(); + if (options.width && options.width < w) w = options.width; + if (w < 30) w = 30; + // if content of specific height + if (options.tmp.contentHeight) { + h = options.tmp.contentHeight; + div2.height(h); + setTimeout(function () { + if (div2.height() > div2.find('div.menu > table').height()) { + div2.find('div.menu').css('overflow-y', 'hidden'); + } + }, 1); + setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); + } + if (options.tmp.contentWidth) { + w = options.tmp.contentWidth; + div2.width(w); + setTimeout(function () { + if (div2.width() > div2.find('div.menu > table').width()) { + div2.find('div.menu').css('overflow-x', 'hidden'); + } + }, 1); + setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); + } + // alignment + switch (options.align) { + case 'both': + options.left = 17; + if (options.width === 0) options.width = w2utils.getSize($(obj), 'width'); + break; + case 'left': + options.left = 17; + break; + case 'right': + options.tipLeft = w - 45; + options.left = w2utils.getSize($(obj), 'width') - w + 10; + break; + } + // adjust position + var tmp = (w - 17) / 2; + var boxLeft = options.left; + var boxWidth = options.width; + var tipLeft = options.tipLeft; + if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto'); + if (tmp < 25) { + boxLeft = 25 - tmp; + tipLeft = Math.floor(tmp); + } + // Y coord + div1.css({ + top : (obj.offset().top + w2utils.getSize(obj, 'height') + options.top + 7) + 'px', + left : ((obj.offset().left > 25 ? obj.offset().left : 25) + boxLeft) + 'px', + 'min-width' : boxWidth, + 'min-height': (options.height ? options.height : 'auto') + }); + // $(window).height() - has a problem in FF20 + var maxHeight = window.innerHeight + $(document).scrollTop() - div2.offset().top - 7; + var maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; + if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) { + // show on top + maxHeight = div2.offset().top - $(document).scrollTop() - 7; + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + h = maxHeight; + } + div1.css('top', ($(obj).offset().top - h - 24 + options.top) + 'px'); + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { display: none; margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { display: block; margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } else { + // show under + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + } + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { display: block; margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { display: none; margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } + // check width + w = div2.width(); + maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; + if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth; + if (w > maxWidth && options.align !== 'both') { + options.align = 'right'; + setTimeout(function () { resize(); }, 1); + } + // check scroll bar + if (overflowY && overflowX) div2.width(w + w2utils.scrollBarSize() + 2); + } + } + }; + + $.fn.w2menu = function (menu, options) { + /* + ITEM STRUCTURE + item : { + id : null, + text : '', + style : '', + hidden : true + ... + } + */ + var defaults = { + index : null, // current selected + items : [], + render : null, + msgNoItems : 'No items', + onSelect : null, + tmp : {} + }; + var obj = this; + var name = ''; + if (menu === 'refresh') { + // if not show - call blur + if ($('#w2ui-overlay'+ name).length > 0) { + options = $.extend($.fn.w2menuOptions, options); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + $('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML()); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + mresize(); + } else { + $(this).w2menu(options); + } + } else { + if (arguments.length === 1) options = menu; else options.items = menu; + if (typeof options !== 'object') options = {}; + options = $.extend({}, defaults, options); + $.fn.w2menuOptions = options; + if (options.name) name = '-' + options.name; + if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select; + if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender; + // since only one overlay can exist at a time + $.fn.w2menuHandler = function (event, index) { + if (typeof options.onSelect === 'function') { + // need time so that menu first hides + setTimeout(function () { + options.onSelect({ + index : index, + item : options.items[index], + originalEvent: event + }); + }, 10); + } + }; + var html = ''; + if (options.search) { + html += + '
        '+ + ' '+ + ' '+ + '
        '; + options.style += ';background-color: #ECECEC'; + options.index = 0; + for (var i in options.items) options.items[i].hidden = false; + } + html += ''; + var ret = $(this).w2overlay(html, options); + setTimeout(function () { + $('#w2ui-overlay'+ name +' #menu-search') + .on('keyup', change) + .on('keydown', function (event) { + // cancel tab key + if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); } + }); + }, 200); + mresize(); + return ret; + } + + function mresize() { + setTimeout(function () { + // show selected + $('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected'); + var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']'); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + cur.addClass('w2ui-selected'); + if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10); + if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width(); + $('#w2ui-overlay'+ name)[0].resize(); + // scroll into view + if (cur.length > 0) { + var top = cur[0].offsetTop - 5; // 5 is margin top + var el = $('#w2ui-overlay'+ name +' div.menu'); + var height = el.height(); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + if (top < scrTop || top + cur.height() > scrTop + height) { + $('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); + } + } + }, 1); + } + + function change(event) { + var search = this.value; + var key = event.keyCode; + var cancel = false; + switch (key) { + case 13: // enter + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuHandler(event, options.index); + break; + case 9: // tab + case 27: // escape + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuHandler(event, -1); + break; + case 38: // up + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index--; + while (options.index > 0 && options.items[options.index].hidden) options.index--; + if (options.index === 0 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } + if (options.index < 0) options.index = 0; + cancel = true; + break; + case 40: // down + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index++; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (options.index === options.items.length-1 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index--; + } + if (options.index >= options.items.length) options.index = options.items.length - 1; + cancel = true; + break; + } + // filter + if (!cancel) { + var shown = 0; + for (var i in options.items) { + var item = options.items[i]; + var prefix = ''; + var suffix = ''; + if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^'; + if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$'; + try { + var re = new RegExp(prefix + search + suffix, 'i'); + if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true; + if (options.applyFilter !== true) item.hidden = false; + } catch (e) {} + // do not show selected items + if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true; + if (item.hidden !== true) shown++; + } + options.index = 0; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (shown <= 0) options.index = -1; + } + $(obj).w2menu('refresh', options); + mresize(); + } + + function getMenuHTML () { + if (options.spinner) { + return '
        '+ + '
        '+ + '
        Loading...
        '+ + '
        '; + } + var count = 0; + var menu_html = ''; + var img = null, icon = null; + for (var f = 0; f < options.items.length; f++) { + var mitem = options.items[f]; + if (typeof mitem === 'string') { + mitem = { id: mitem, text: mitem }; + } else { + if (mitem.text != null && mitem.id == null) mitem.id = mitem.text; + if (mitem.text == null && mitem.id != null) mitem.text = mitem.id; + if (mitem.caption != null) mitem.text = mitem.caption; + img = mitem.img; + icon = mitem.icon; + if (img == null) img = null; + if (icon == null) icon = null; + } + if (mitem.hidden !== true) { + var imgd = ''; + var txt = mitem.text; + if (typeof options.render === 'function') txt = options.render(mitem, options); + if (img) imgd = ''; + if (icon) imgd = ''; + // render only if non-empty + if (typeof txt !== 'undefined' && txt !== '' && !(/^-+$/.test(txt))) { + var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd'); + if (options.altRows !== true) bg = ''; + menu_html += + ''+ + imgd + + ' '+ + ''; + count++; + } else { + // horizontal line + menu_html += ''; + } + } + options.items[f] = mitem; + } + if (count === 0) { + menu_html += ''; + } + menu_html += "
        '+ txt +'
        '+ options.msgNoItems +'
        "; + return menu_html; + } + }; })(); /************************************************************************ * Library: Web 2.0 UI for jQuery (using prototypical inheritance) * - Following objects defined -* - w2grid - grid widget -* - $().w2grid - jQuery wrapper -* - Dependencies: jQuery, w2utils, w2toolbar, w2fields, w2alert, w2confirm +* - w2grid - grid widget +* - $().w2grid - jQuery wrapper +* - Dependencies: jQuery, w2utils, w2toolbar, w2fields, w2alert, w2confirm * * == NICE TO HAVE == -* - frozen columns -* - add colspans -* - get rid of this.buffered -* - allow this.total to be unknown (-1) -* - column autosize based on largest content -* - save grid state into localStorage and restore -* - easy bubbles in the grid -* - More than 2 layers of header groups -* - reorder columns/records -* - hidden searches could not be clearned by the user -* - problem with .set() and arrays, array get extended too, but should be replaced -* - move events into prototype -* - add grid.focus() -* - add showExtra, KickIn Infinite scroll when so many records -* - after edit stay on the same record option +* - frozen columns +* - add colspans +* - get rid of this.buffered +* - allow this.total to be unknown (-1) +* - column autosize based on largest content +* - save grid state into localStorage and restore +* - easy bubbles in the grid +* - More than 2 layers of header groups +* - reorder columns/records +* - hidden searches could not be clearned by the user +* - problem with .set() and arrays, array get extended too, but should be replaced +* - move events into prototype +* - add grid.focus() +* - add showExtra, KickIn Infinite scroll when so many records +* - after edit stay on the same record option * * == 1.4 changes -* - for search fields one should be able to pass w2field options -* - add enum to advanced search fields -* - editable fields -> LIST type is not working -* - search-logic -> searchLogic -* - new: refreshRow(recid) - should it be part of refresh? -* - new: refreshCell(recid, field) - should it be part of refresh? -* - removed: getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - new: reorderColumns -* - removed name from the POST -* - rename: markSearchResults -> markSearch -* - refactored inline editing -* - new: getCellValue(ind, col_ind, [summary]) -* - refactored selection -* - removed: record.selected -* - new: nextCell, prevCell, nextRow, prevRow -* - new: editChange(el, index, column, event) -* - new: method - overwrite default ajax method (see also w2utils.settings.RESTfull) -* - rename: onSave -> onSubmit, onSaved -> onSave, just like in the form -* - new: recid - if id of the data is different from recid -* - new: parser - to converd data received from the server -* - change: rec.changes = {} and removed rec.changed -* - record.style can be a string or an object (for cell formatting) -* - col.resizable = true by default -* - new: prepareData(); -* - context menu similar to sidebar's -* - find will return array or recids not objects +* - for search fields one should be able to pass w2field options +* - add enum to advanced search fields +* - editable fields -> LIST type is not working +* - search-logic -> searchLogic +* - new: refreshRow(recid) - should it be part of refresh? +* - new: refreshCell(recid, field) - should it be part of refresh? +* - removed: getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - new: reorderColumns +* - removed name from the POST +* - rename: markSearchResults -> markSearch +* - refactored inline editing +* - new: getCellValue(ind, col_ind, [summary]) +* - refactored selection +* - removed: record.selected +* - new: nextCell, prevCell, nextRow, prevRow +* - new: editChange(el, index, column, event) +* - new: method - overwrite default ajax method (see also w2utils.settings.RESTfull) +* - rename: onSave -> onSubmit, onSaved -> onSave, just like in the form +* - new: recid - if id of the data is different from recid +* - new: parser - to converd data received from the server +* - change: rec.changes = {} and removed rec.changed +* - record.style can be a string or an object (for cell formatting) +* - col.resizable = true by default +* - new: prepareData(); +* - context menu similar to sidebar's +* - find will return array or recids not objects * ************************************************************************/ (function () { - var w2grid = function(options) { - - // public properties - this.name = null; - this.box = null; // HTML element that hold this element - this.header = ''; - this.url = ''; - this.columns = []; // { field, caption, size, attr, render, hidden, gridMinWidth, [editable: {type, inTag, outTag, style, items}] } - this.columnGroups = []; // { span: int, caption: 'string', master: true/false } - this.records = []; // { recid: int(requied), field1: 'value1', ... fieldN: 'valueN', style: 'string', editable: true/false, summary: true/false, changes: object } - this.summary = []; // arry of summary records, same structure as records array - this.searches = []; // { type, caption, field, inTag, outTag, default, items, hidden } - this.searchData = []; - this.sortData = []; - this.postData = {}; - this.toolbar = {}; // if not empty object; then it is toolbar object - - this.show = { - header : false, - toolbar : false, - footer : false, - columnHeaders : true, - lineNumbers : false, - expandColumn : false, - selectColumn : false, - emptyRecords : true, - toolbarReload : true, - toolbarColumns : true, - toolbarSearch : true, - toolbarAdd : false, - toolbarEdit : false, - toolbarDelete : false, - toolbarSave : false, - selectionBorder : true, - recordTitles : true - }; - - this.autoLoad = true; // for infinite scroll - this.fixedBody = true; // if false; then grid grows with data - this.recordHeight = 24; - this.keyboard = true; - this.selectType = 'row'; // can be row|cell - this.multiSearch = true; - this.multiSelect = true; - this.multiSort = true; - this.reorderColumns = false; - this.reorderRows = false; - this.markSearch = true; - - this.total = 0; // server total - this.buffered = 0; // number of records in the records array - this.limit = 100; - this.offset = 0; // how many records to skip (for infinite scroll) when pulling from server - this.style = ''; - this.ranges = []; - this.menu = []; - this.method; // if defined, then overwrited ajax method - this.recid; - this.parser; - - // events - this.onAdd = null; - this.onEdit = null; - this.onRequest = null; // called on any server event - this.onLoad = null; - this.onDelete = null; - this.onDeleted = null; - this.onSubmit = null; - this.onSave = null; - this.onSelect = null; - this.onUnselect = null; - this.onClick = null; - this.onDblClick = null; - this.onContextMenu = null; - this.onMenuClick = null; // when context menu item selected - this.onColumnClick = null; - this.onColumnResize = null; - this.onSort = null; - this.onSearch = null; - this.onChange = null; // called when editable record is changed - this.onRestore = null; // called when editable record is restored - this.onExpand = null; - this.onCollapse = null; - this.onError = null; - this.onKeydown = null; - this.onToolbar = null; // all events from toolbar - this.onColumnOnOff = null; - this.onCopy = null; - this.onPaste = null; - this.onSelectionExtend = null; - this.onEditField = null; - this.onRender = null; - this.onRefresh = null; - this.onReload = null; - this.onResize = null; - this.onDestroy = null; - - // internal - this.last = { - field : 'all', - caption : w2utils.lang('All Fields'), - logic : 'OR', - search : '', - searchIds : [], - selection : { - indexes : [], - columns : {}, - }, - multi : false, - scrollTop : 0, - scrollLeft : 0, - sortData : null, - sortCount : 0, - xhr : null, - range_start : null, - range_end : null, - sel_ind : null, - sel_col : null, - sel_type : null, - edit_col : null - }; - - this.isIOS = (navigator.userAgent.toLowerCase().indexOf('iphone') != -1 || - navigator.userAgent.toLowerCase().indexOf('ipod') != -1 || - navigator.userAgent.toLowerCase().indexOf('ipad') != -1) ? true : false; - - $.extend(true, this, w2obj.grid, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2grid = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2grid')) return; - // remember items - var columns = method.columns; - var columnGroups= method.columnGroups; - var records = method.records; - var searches = method.searches; - var searchData = method.searchData; - var sortData = method.sortData; - var postData = method.postData; - var toolbar = method.toolbar; - // extend items - var object = new w2grid(method); - $.extend(object, { postData: {}, records: [], columns: [], searches: [], toolbar: {}, sortData: [], searchData: [], handlers: [] }); - if (object.onExpand != null) object.show.expandColumn = true; - $.extend(true, object.toolbar, toolbar); - // reassign variables - for (var p in columns) object.columns[p] = $.extend(true, {}, columns[p]); - for (var p in columnGroups) object.columnGroups[p] = $.extend(true, {}, columnGroups[p]); - for (var p in searches) object.searches[p] = $.extend(true, {}, searches[p]); - for (var p in searchData) object.searchData[p] = $.extend(true, {}, searchData[p]); - for (var p in sortData) object.sortData[p] = $.extend(true, {}, sortData[p]); - object.postData = $.extend(true, {}, postData); - - // check if there are records without recid - for (var r in records) { - if (records[r].recid == null || typeof records[r].recid == 'undefined') { - console.log('ERROR: Cannot add records without recid. (obj: '+ object.name +')'); - return; - } - object.records[r] = $.extend(true, {}, records[r]); - } - if (object.records.length > 0) object.buffered = object.records.length; - // add searches - for (var c in object.columns) { - var col = object.columns[c]; - if (typeof col.searchable == 'undefined' || object.getSearch(col.field) != null) continue; - var stype = col.searchable; - var attr = ''; - if (col.searchable === true) { stype = 'text'; attr = 'size="20"'; } - object.addSearch({ field: col.field, caption: col.caption, type: stype, attr: attr }); - } - // init toolbar - object.initToolbar(); - // render if necessary - if ($(this).length !== 0) { - object.render($(this)[0]); - } - // register new object - w2ui[object.name] = object; - return object; - - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2grid'); - } - } - - // ==================================================== - // -- Implementation of core functionality - - w2grid.prototype = { - // ---- - // properties that need to be in prototype - - msgDelete : 'Are you sure you want to delete selected records?', - msgNotJSON : 'Returned data is not in valid JSON format.', - msgAJAXerror: 'AJAX error. See console for more details.', - msgRefresh : 'Refreshing...', - - // for easy button overwrite - buttons: { - 'reload' : { type: 'button', id: 'w2ui-reload', img: 'icon-reload', hint: 'Reload data in the list' }, - 'columns' : { type: 'drop', id: 'w2ui-column-on-off', img: 'icon-columns', hint: 'Show/hide columns', arrow: false, html: '' }, - 'search' : { type: 'html', id: 'w2ui-search', - html: '
        ' - }, - 'search-go' : { type: 'check', id: 'w2ui-search-advanced', caption: 'Search...', hint: 'Open Search Fields' }, - 'add' : { type: 'button', id: 'w2ui-add', caption: 'Add New', hint: 'Add new record', img: 'icon-add' }, - 'edit' : { type: 'button', id: 'w2ui-edit', caption: 'Edit', hint: 'Edit selected record', img: 'icon-edit', disabled: true }, - 'delete' : { type: 'button', id: 'w2ui-delete', caption: 'Delete', hint: 'Delete selected records', img: 'icon-delete', disabled: true }, - 'save' : { type: 'button', id: 'w2ui-save', caption: 'Save', hint: 'Save changed records', img: 'icon-save' } - }, - - add: function (record) { - if (!$.isArray(record)) record = [record]; - var added = 0; - for (var o in record) { - if (!this.recid && typeof record[o].recid == 'undefined') record[o].recid = record[o][this.recid]; - if (record[o].recid == null || typeof record[o].recid == 'undefined') { - console.log('ERROR: Cannot add record without recid. (obj: '+ this.name +')'); - continue; - } - this.records.push(record[o]); - added++; - } - this.buffered = this.records.length; - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (!url) { - this.total = this.records.length; - this.localSort(); - this.localSearch(); - } - this.refresh(); // ?? should it be reload? - return added; - }, - - find: function (obj, returnIndex) { - if (typeof obj == 'undefined' || obj == null) obj = {}; - var recs = []; - var hasDots = false; - // check if property is nested - needed for speed - for (var o in obj) if (String(o).indexOf('.') != -1) hasDots = true; - // look for an item - for (var i = 0; i < this.records.length; i++) { - var match = true; - for (var o in obj) { - var val = this.records[i][o]; - if (hasDots && String(o).indexOf('.') != -1) val = this.parseField(this.records[i], o); - if (obj[o] != val) match = false; - } - if (match && returnIndex !== true) recs.push(this.records[i].recid); - if (match && returnIndex === true) recs.push(i); - } - return recs; - }, - - set: function (recid, record, noRefresh) { // does not delete existing, but overrides on top of it - if (typeof recid == 'object') { - noRefresh = record; - record = recid; - recid = null; - } - // update all records - if (recid == null) { - for (var r in this.records) { - $.extend(true, this.records[r], record); // recid is the whole record - } - if (noRefresh !== true) this.refresh(); - } else { // find record to update - var ind = this.get(recid, true); - if (ind == null) return false; - $.extend(true, this.records[ind], record); - if (noRefresh !== true) this.refreshRow(recid); // refresh only that record - } - return true; - }, - - get: function (recid, returnIndex) { - for (var i = 0; i < this.records.length; i++) { - if (this.records[i].recid == recid) { - if (returnIndex === true) return i; else return this.records[i]; - } - } - return null; - }, - - remove: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.records.length-1; r >= 0; r--) { - if (this.records[r].recid == arguments[a]) { this.records.splice(r, 1); removed++; } - } - } - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (!url) { - this.buffered = this.records.length; - this.localSort(); - this.localSearch(); - } - this.refresh(); - return removed; - }, - - addColumn: function (before, columns) { - var added = 0; - if (arguments.length == 1) { - columns = before; - before = this.columns.length; - } else { - if (typeof before == 'string') before = this.getColumn(before, true); - if (before === null) before = this.columns.length; - } - if (!$.isArray(columns)) columns = [columns]; - for (var o in columns) { - this.columns.splice(before, 0, columns[o]); - before++; - added++; - } - this.initColumnOnOff(); - this.refresh(); - return added; - }, - - removeColumn: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.columns.length-1; r >= 0; r--) { - if (this.columns[r].field == arguments[a]) { this.columns.splice(r, 1); removed++; } - } - } - this.initColumnOnOff(); - this.refresh(); - return removed; - }, - - getColumn: function (field, returnIndex) { - for (var i = 0; i < this.columns.length; i++) { - if (this.columns[i].field == field) { - if (returnIndex === true) return i; else return this.columns[i]; - } - } - return null; - }, - - toggleColumn: function () { - var effected = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.columns.length-1; r >= 0; r--) { - if (this.columns[r].field == arguments[a]) { - this.columns[r].hidden = !this.columns[r].hidden; - effected++; - } - } - } - this.refresh(); - return effected; - }, - - showColumn: function () { - var shown = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.columns.length-1; r >= 0; r--) { - if (this.columns[r].field == arguments[a] && this.columns[r].hidden !== false) { - this.columns[r].hidden = false; - shown++; - } - } - } - this.refresh(); - return shown; - }, - - hideColumn: function () { - var hidden = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.columns.length-1; r >= 0; r--) { - if (this.columns[r].field == arguments[a] && this.columns[r].hidden !== true) { - this.columns[r].hidden = true; - hidden++; - } - } - } - this.refresh(); - return hidden; - }, - - addSearch: function (before, search) { - var added = 0; - if (arguments.length == 1) { - search = before; - before = this.searches.length; - } else { - if (typeof before == 'string') before = this.getSearch(before, true); - if (before === null) before = this.searches.length; - } - if (!$.isArray(search)) search = [search]; - for (var o in search) { - this.searches.splice(before, 0, search[o]); - before++; - added++; - } - this.searchClose(); - return added; - }, - - removeSearch: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.searches.length-1; r >= 0; r--) { - if (this.searches[r].field == arguments[a]) { this.searches.splice(r, 1); removed++; } - } - } - this.searchClose(); - return removed; - }, - - getSearch: function (field, returnIndex) { - for (var i = 0; i < this.searches.length; i++) { - if (this.searches[i].field == field) { - if (returnIndex === true) return i; else return this.searches[i]; - } - } - return null; - }, - - toggleSearch: function () { - var effected = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.searches.length-1; r >= 0; r--) { - if (this.searches[r].field == arguments[a]) { - this.searches[r].hidden = !this.searches[r].hidden; - effected++; - } - } - } - this.searchClose(); - return effected; - }, - - showSearch: function () { - var shown = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.searches.length-1; r >= 0; r--) { - if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== false) { - this.searches[r].hidden = false; - shown++; - } - } - } - this.searchClose(); - return shown; - }, - - hideSearch: function () { - var hidden = 0; - for (var a = 0; a < arguments.length; a++) { - for (var r = this.searches.length-1; r >= 0; r--) { - if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== true) { - this.searches[r].hidden = true; - hidden++; - } - } - } - this.searchClose(); - return hidden; - }, - - getSearchData: function (field) { - for (var s in this.searchData) { - if (this.searchData[s].field == field) return this.searchData[s]; - } - return null; - }, - - localSort: function (silent) { - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (url) { - console.log('ERROR: grid.localSort can only be used on local data source, grid.url should be empty.'); - return; - } - if ($.isEmptyObject(this.sortData)) return; - var time = (new Date()).getTime(); - var obj = this; - // process date fields - obj.prepareData(); - // process sortData - for (var s in this.sortData) { - var column = this.getColumn(this.sortData[s].field); - if (!column) return; - if (column.render && ['date', 'age'].indexOf(column.render) != -1) { - this.sortData[s]['field_'] = column.field + '_'; - } - if (column.render && ['time'].indexOf(column.render) != -1) { - this.sortData[s]['field_'] = column.field + '_'; - } - } - // process sort - this.records.sort(function (a, b) { - var ret = 0; - for (var s in obj.sortData) { - var fld = obj.sortData[s].field; - if (obj.sortData[s].field_) fld = obj.sortData[s].field_; - var aa = a[fld]; - var bb = b[fld]; - if (String(fld).indexOf('.') != -1) { - aa = obj.parseField(a, fld); - bb = obj.parseField(b, fld); - } - if (typeof aa == 'string') aa = $.trim(aa.toLowerCase()); - if (typeof bb == 'string') bb = $.trim(bb.toLowerCase()); - if (aa > bb) ret = (obj.sortData[s].direction == 'asc' ? 1 : -1); - if (aa < bb) ret = (obj.sortData[s].direction == 'asc' ? -1 : 1); - if (typeof aa != 'object' && typeof bb == 'object') ret = -1; - if (typeof bb != 'object' && typeof aa == 'object') ret = 1; - if (aa == null && bb != null) ret = 1; // all nuls and undefined on bottom - if (aa != null && bb == null) ret = -1; - if (ret != 0) break; - } - return ret; - }); - time = (new Date()).getTime() - time; - if (silent !== true) setTimeout(function () { obj.status('Sorting took ' + time/1000 + ' sec'); }, 10); - return time; - }, - - localSearch: function (silent) { - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (url) { - console.log('ERROR: grid.localSearch can only be used on local data source, grid.url should be empty.'); - return; - } - var time = (new Date()).getTime(); - var obj = this; - this.total = this.records.length; - // mark all records as shown - this.last.searchIds = []; - // prepare date/time fields - this.prepareData(); - // hide records that did not match - if (this.searchData.length > 0 && !url) { - this.total = 0; - for (var r in this.records) { - var rec = this.records[r]; - var fl = 0; - for (var s in this.searchData) { - var sdata = this.searchData[s]; - var search = this.getSearch(sdata.field); - if (sdata == null) continue; - if (search == null) search = { field: sdata.field, type: sdata.type }; - var val1 = String(obj.parseField(rec, search.field)).toLowerCase(); - if (typeof sdata.value != 'undefined') { - if (!$.isArray(sdata.value)) { - var val2 = String(sdata.value).toLowerCase(); - } else { - var val2 = sdata.value[0]; - var val3 = sdata.value[1]; - } - } - switch (sdata.operator) { - case 'is': - if (rec[search.field] == sdata.value) fl++; // do not hide record - if (search.type == 'date') { - var val1 = w2utils.formatDate(rec[search.field + '_'], 'yyyy-mm-dd'); - var val2 = w2utils.formatDate(val2, 'yyyy-mm-dd'); - if (val1 == val2) fl++; - } - if (search.type == 'time') { - var val1 = w2utils.formatTime(rec[search.field + '_'], 'h24:mi'); - var val2 = w2utils.formatTime(val2, 'h24:mi'); - if (val1 == val2) fl++; - } - break; - case 'between': - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { - if (parseFloat(rec[search.field]) >= parseFloat(val2) && parseFloat(rec[search.field]) <= parseFloat(val3)) fl++; - } - if (search.type == 'date') { - var val1 = rec[search.field + '_']; - var val2 = w2utils.isDate(val2, w2utils.settings.date_format, true); - var val3 = w2utils.isDate(val3, w2utils.settings.date_format, true); - if (val3 != null) val3 = new Date(val3.getTime() + 86400000); // 1 day - if (val1 >= val2 && val1 < val3) fl++; - } - if (search.type == 'time') { - var val1 = rec[search.field + '_']; - var val2 = w2utils.isTime(val2, true); - var val3 = w2utils.isTime(val3, true); - val2 = (new Date()).setHours(val2.hours, val2.minutes, val2.seconds ? val2.seconds : 0, 0); - val3 = (new Date()).setHours(val3.hours, val3.minutes, val3.seconds ? val3.seconds : 0, 0); - if (val1 >= val2 && val1 < val3) fl++; - } - break; - case 'in': - if (sdata.svalue) { - if (sdata.svalue.indexOf(val1) !== -1) fl++; - } else { - if (sdata.value.indexOf(val1) !== -1) fl++; - } - break; - case 'begins': - if (val1.indexOf(val2) == 0) fl++; // do not hide record - break; - case 'contains': - if (val1.indexOf(val2) >= 0) fl++; // do not hide record - break; - case 'ends': - if (val1.indexOf(val2) == val1.length - val2.length) fl++; // do not hide record - break; - } - } - if ((this.last.logic == 'OR' && fl != 0) || (this.last.logic == 'AND' && fl == this.searchData.length)) this.last.searchIds.push(parseInt(r)); - } - this.total = this.last.searchIds.length; - } - this.buffered = this.total; - time = (new Date()).getTime() - time; - if (silent !== true) setTimeout(function () { obj.status('Search took ' + time/1000 + ' sec'); }, 10); - return time; - }, - - getRangeData: function (range, extra) { - var rec1 = this.get(range[0].recid, true); - var rec2 = this.get(range[1].recid, true); - var col1 = range[0].column; - var col2 = range[1].column; - - var res = []; - if (col1 == col2) { // one row - for (var r = rec1; r <= rec2; r++) { - var record = this.records[r]; - var dt = record[this.columns[col1].field] || null; - if (extra !== true) { - res.push(dt); - } else { - res.push({ data: dt, column: col1, index: r, record: record }); - } - } - } else if (rec1 == rec2) { // one line - var record = this.records[rec1]; - for (var i = col1; i <= col2; i++) { - var dt = record[this.columns[i].field] || null; - if (extra !== true) { - res.push(dt); - } else { - res.push({ data: dt, column: i, index: rec1, record: record }); - } - } - } else { - for (var r = rec1; r <= rec2; r++) { - var record = this.records[r]; - res.push([]); - for (var i = col1; i <= col2; i++) { - var dt = record[this.columns[i].field]; - if (extra !== true) { - res[res.length-1].push(dt); - } else { - res[res.length-1].push({ data: dt, column: i, index: r, record: record }); - } - } - } - } - return res; - }, - - addRange: function (ranges) { - var added = 0; - if (this.selectType == 'row') return added; - if (!$.isArray(ranges)) ranges = [ranges]; - // if it is selection - for (var r in ranges) { - if (typeof ranges[r] != 'object') ranges[r] = { name: 'selection' }; - if (ranges[r].name == 'selection') { - if (this.show.selectionBorder === false) continue; - var sel = this.getSelection(); - if (sel.length == 0) { - this.removeRange(ranges[r].name); - continue; - } else { - var first = sel[0]; - var last = sel[sel.length-1]; - var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); - var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); - } - } else { // other range - var first = ranges[r].range[0]; - var last = ranges[r].range[1]; - var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); - var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); - } - if (first) { - var rg = { - name: ranges[r].name, - range: [{ recid: first.recid, column: first.column }, { recid: last.recid, column: last.column }], - style: ranges[r].style || '' - }; - // add range - var ind = false; - for (var t in this.ranges) if (this.ranges[t].name == ranges[r].name) { ind = r; break; } - if (ind !== false) { - this.ranges[ind] = rg; - } else { - this.ranges.push(rg); - } - added++ - } - } - this.refreshRanges(); - return added; - }, - - removeRange: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - var name = arguments[a]; - $('#grid_'+ this.name +'_'+ name).remove(); - for (var r = this.ranges.length-1; r >= 0; r--) { - if (this.ranges[r].name == name) { - this.ranges.splice(r, 1); - removed++; - } - } - } - return removed; - }, - - refreshRanges: function () { - var obj = this; - var time = (new Date()).getTime(); - var rec = $('#grid_'+ this.name +'_records'); - for (var r in this.ranges) { - var rg = this.ranges[r]; - var first = rg.range[0]; - var last = rg.range[1]; - var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); - var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); - if ($('#grid_'+ this.name +'_'+ rg.name).length == 0) { - rec.append('
        '+ - (rg.name == 'selection' ? '
        ' : '')+ - '
        '); - } else { - $('#grid_'+ this.name +'_'+ rg.name).attr('style', rg.style); - } - if (td1.length > 0 && td2.length > 0) { - $('#grid_'+ this.name +'_'+ rg.name).css({ - left : (td1.position().left - 1 + rec.scrollLeft()) + 'px', - top : (td1.position().top - 1 + rec.scrollTop()) + 'px', - width : (td2.position().left - td1.position().left + td2.width() + 3) + 'px', - height : (td2.position().top - td1.position().top + td2.height() + 3) + 'px' - }); - } - } - - // add resizer events - $(this.box).find('#grid_'+ this.name +'_resizer').off('mousedown').on('mousedown', mouseStart); - //$(this.box).find('#grid_'+ this.name +'_resizer').off('selectstart').on('selectstart', function () { return false; }); // fixes chrome cursror bug - - var eventData = { phase: 'before', type: 'selectionExtend', target: obj.name, originalRange: null, newRange: null }; - - function mouseStart (event) { - var sel = obj.getSelection(); - obj.last.move = { - type : 'expand', - x : event.screenX, - y : event.screenY, - divX : 0, - divY : 0, - recid : sel[0].recid, - column : sel[0].column, - originalRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }], - newRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }] - }; - $(document).off('mousemove', mouseMove).on('mousemove', mouseMove); - $(document).off('mouseup', mouseStop).on('mouseup', mouseStop); - } - - function mouseMove (event) { - var mv = obj.last.move; - if (!mv || mv.type != 'expand') return; - mv.divX = (event.screenX - mv.x); - mv.divY = (event.screenY - mv.y); - // find new cell - var recid, column; - var tmp = event.originalEvent.target; - if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; - if (typeof $(tmp).attr('col') != 'undefined') column = parseInt($(tmp).attr('col')); - tmp = $(tmp).parents('tr')[0]; - recid = $(tmp).attr('recid'); - // new range - if (mv.newRange[1].recid == recid && mv.newRange[1].column == column) return; - var prevNewRange = $.extend({}, mv.newRange); - mv.newRange = [{ recid: mv.recid, column: mv.column }, { recid: recid, column: column }]; - // event before - eventData = obj.trigger($.extend(eventData, { originalRange: mv.originalRange, newRange : mv.newRange })); - if (eventData.isCancelled === true) { - mv.newRange = prevNewRange; - eventData.newRange = prevNewRange; - return; - } else { - // default behavior - obj.removeRange('grid-selection-expand'); - obj.addRange({ - name : 'grid-selection-expand', - range : eventData.newRange, - style : 'background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);' - }); - } - } - - function mouseStop (event) { - // default behavior - obj.removeRange('grid-selection-expand'); - delete obj.last.move; - $(document).off('mousemove', mouseMove); - $(document).off('mouseup', mouseStop); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - - return (new Date()).getTime() - time; - }, - - select: function () { - var selected = 0; - var sel = this.last.selection; - if (!this.multiSelect) this.selectNone(); - for (var a = 0; a < arguments.length; a++) { - var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; - var record = this.get(recid); - if (record == null) continue; - var index = this.get(recid, true); - var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); - if (this.selectType == 'row') { - if (sel.indexes.indexOf(index) >= 0) continue; - // event before - var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, recid: recid, index: index }); - if (eventData.isCancelled === true) continue; - // default action - sel.indexes.push(index); - sel.indexes.sort(function(a, b) { return a-b }); - recEl.addClass('w2ui-selected').data('selected', 'yes'); - recEl.find('.w2ui-grid-select-check').prop("checked", true); - selected++; - } else { - var col = arguments[a].column; - if (!w2utils.isInt(col)) { // select all columns - var cols = []; - for (var c in this.columns) { if (this.columns[c].hidden) continue; cols.push({ recid: recid, column: parseInt(c) }); } - if (!this.multiSelect) cols = cols.splice(0, 1); - return this.select.apply(this, cols); - } - var s = sel.columns[index] || []; - if ($.isArray(s) && s.indexOf(col) != -1) continue; - // event before - var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, recid: recid, index: index, column: col }); - if (eventData.isCancelled === true) continue; - // default action - if (sel.indexes.indexOf(index) == -1) { - sel.indexes.push(index); - sel.indexes.sort(function(a, b) { return a-b }); - } - s.push(col); - s.sort(function(a, b) { return a-b }); // sort function must be for numerical sort - recEl.find(' > td[col='+ col +']').addClass('w2ui-selected'); - selected++; - recEl.data('selected', 'yes'); - recEl.find('.w2ui-grid-select-check').prop("checked", true); - // save back to selection object - sel.columns[index] = s; - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - // all selected? - if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { - $('#grid_'+ this.name +'_check_all').prop('checked', true); - } else { - $('#grid_'+ this.name +'_check_all').prop('checked', false); - } - this.status(); - this.addRange('selection'); - return selected; - }, - - unselect: function () { - var unselected = 0; - var sel = this.last.selection; - for (var a = 0; a < arguments.length; a++) { - var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; - var record = this.get(recid); - if (record == null) continue; - var index = this.get(record.recid, true); - var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); - if (this.selectType == 'row') { - if (sel.indexes.indexOf(index) == -1) continue; - // event before - var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, index: index }); - if (eventData.isCancelled === true) continue; - // default action - sel.indexes.splice(sel.indexes.indexOf(index), 1); - recEl.removeClass('w2ui-selected').removeData('selected'); - if (recEl.length != 0) recEl[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl.attr('custom_style'); - recEl.find('.w2ui-grid-select-check').prop("checked", false); - unselected++; - } else { - var col = arguments[a].column; - if (!w2utils.isInt(col)) { // unselect all columns - var cols = []; - for (var c in this.columns) { if (this.columns[c].hidden) continue; cols.push({ recid: recid, column: parseInt(c) }); } - return this.unselect.apply(this, cols); - } - var s = sel.columns[index]; - if (!$.isArray(s) || s.indexOf(col) == -1) continue; - // event before - var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, column: col }); - if (eventData.isCancelled === true) continue; - // default action - s.splice(s.indexOf(col), 1); - $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid) + ' > td[col='+ col +']').removeClass('w2ui-selected'); - unselected++; - if (s.length == 0) { - delete sel.columns[index]; - sel.indexes.splice(sel.indexes.indexOf(index), 1); - recEl.removeData('selected'); - recEl.find('.w2ui-grid-select-check').prop("checked", false); - } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - // all selected? - if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { - $('#grid_'+ this.name +'_check_all').prop('checked', true); - } else { - $('#grid_'+ this.name +'_check_all').prop('checked', false); - } - // show number of selected - this.status(); - this.addRange('selection'); - return unselected; - }, - - selectAll: function () { - if (this.multiSelect === false) return; - // event before - var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, all: true }); - if (eventData.isCancelled === true) return; - // default action - var url = (typeof this.url != 'object' ? this.url : this.url.get); - var sel = this.last.selection; - var cols = []; - for (var c in this.columns) cols.push(parseInt(c)); - // if local data source and searched - sel.indexes = []; - if (!url && this.searchData.length !== 0) { - // local search applied - for (var i = 0; i < this.last.searchIds.length; i++) { - sel.indexes.push(this.last.searchIds[i]); - if (this.selectType != 'row') sel.columns[this.last.searchIds[i]] = cols.slice(); // .slice makes copy of the array - } - } else { - for (var i = 0; i < this.records.length; i++) { - sel.indexes.push(i); - if (this.selectType != 'row') sel.columns[i] = cols.slice(); // .slice makes copy of the array - } - } - this.refresh(); - // enable/disable toolbar buttons - var sel = this.getSelection(); - if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); - if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); - this.addRange('selection'); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - selectNone: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, all: true }); - if (eventData.isCancelled === true) return; - // default action - var sel = this.last.selection; - for (var s in sel.indexes) { - var index = sel.indexes[s]; - var rec = this.records[index]; - var recid = rec ? rec.recid : null; - var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); - recEl.removeClass('w2ui-selected').removeData('selected'); - recEl.find('.w2ui-grid-select-check').prop("checked", false); - // for not rows - if (this.selectType != 'row') { - var cols = sel.columns[index]; - for (var c in cols) recEl.find(' > td[col='+ cols[c] +']').removeClass('w2ui-selected'); - } - } - sel.indexes = []; - sel.columns = {}; - this.toolbar.disable('w2ui-edit', 'w2ui-delete'); - this.removeRange('selection'); - $('#grid_'+ this.name +'_check_all').prop('checked', false); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - getSelection: function (returnIndex) { - var ret = []; - var sel = this.last.selection; - if (this.selectType == 'row') { - for (var s in sel.indexes) { - if (!this.records[sel.indexes[s]]) continue; - if (returnIndex === true) ret.push(sel.indexes[s]); else ret.push(this.records[sel.indexes[s]].recid); - } - return ret; - } else { - for (var s in sel.indexes) { - var cols = sel.columns[sel.indexes[s]]; - if (!this.records[sel.indexes[s]]) continue; - for (var c in cols) { - ret.push({ recid: this.records[sel.indexes[s]].recid, index: parseInt(sel.indexes[s]), column: cols[c] }); - } - } - return ret; - } - }, - - search: function (field, value) { - var obj = this; - var url = (typeof this.url != 'object' ? this.url : this.url.get); - var searchData = []; - var last_multi = this.last.multi; - var last_logic = this.last.logic; - var last_field = this.last.field; - var last_search = this.last.search; - // 1: search() - advanced search (reads from popup) - if (arguments.length == 0) { - last_search = ''; - // advanced search - for (var s in this.searches) { - var search = this.searches[s]; - var operator = $('#grid_'+ this.name + '_operator_'+s).val(); - var field1 = $('#grid_'+ this.name + '_field_'+s); - var field2 = $('#grid_'+ this.name + '_field2_'+s); - var value1 = field1.val(); - var value2 = field2.val(); - var svalue = null; - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { - var fld1 = field1.data('w2field'); - var fld2 = field2.data('w2field'); - if (fld1) value1 = fld1.clean(value1); - if (fld2) value2 = fld2.clean(value2); - } - if (['list', 'enum'].indexOf(search.type) != -1) { - value1 = field1.data('selected') || {}; - if ($.isArray(value1)) { - svalue = []; - for (var v in value1) { - svalue.push(w2utils.isFloat(value1[v].id) ? parseFloat(value1[v].id) : String(value1[v].id).toLowerCase()); - delete value1[v].hidden; - } - } else { - value1 = value1.id || ''; - } - } - if ((value1 != '' && value1 != null) || (typeof value2 != 'undefined' && value2 != '')) { - var tmp = { - field : search.field, - type : search.type, - operator : operator - } - if (operator == 'between') { - $.extend(tmp, { value: [value1, value2] }); - } else if (operator == 'in' && typeof value1 == 'string') { - $.extend(tmp, { value: value1.split(',') }); - } else { - $.extend(tmp, { value: value1 }); - } - if (svalue) $.extend(tmp, { svalue: svalue }); - // conver date to unix time - try { - if (search.type == 'date' && operator == 'between') { - tmp.value[0] = value1; // w2utils.isDate(value1, w2utils.settings.date_format, true).getTime(); - tmp.value[1] = value2; // w2utils.isDate(value2, w2utils.settings.date_format, true).getTime(); - } - if (search.type == 'date' && operator == 'is') { - tmp.value = value1; // w2utils.isDate(value1, w2utils.settings.date_format, true).getTime(); - } - } catch (e) { - - } - searchData.push(tmp); - } - } - if (searchData.length > 0 && !url) { - last_multi = true; - last_logic = 'AND'; - } else { - last_multi = true; - last_logic = 'AND'; - } - } - // 2: search(field, value) - regular search - if (typeof field == 'string') { - last_field = field; - last_search = value; - last_multi = false; - last_logic = 'OR'; - // loop through all searches and see if it applies - if (typeof value != 'undefined') { - if (field.toLowerCase() == 'all') { - // if there are search fields loop thru them - if (this.searches.length > 0) { - for (var s in this.searches) { - var search = this.searches[s]; - if (search.type == 'text' || (search.type == 'alphanumeric' && w2utils.isAlphaNumeric(value)) - || (search.type == 'int' && w2utils.isInt(value)) || (search.type == 'float' && w2utils.isFloat(value)) - || (search.type == 'percent' && w2utils.isFloat(value)) || (search.type == 'hex' && w2utils.isHex(value)) - || (search.type == 'currency' && w2utils.isMoney(value)) || (search.type == 'money' && w2utils.isMoney(value)) - || (search.type == 'date' && w2utils.isDate(value)) ) { - var tmp = { - field : search.field, - type : search.type, - operator : (search.type == 'text' ? 'contains' : 'is'), - value : value - }; - searchData.push(tmp); - } - // range in global search box - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1 && String(value).indexOf('-') != -1) { - var t = String(value).split('-'); - var tmp = { - field : search.field, - type : search.type, - operator : 'between', - value : [t[0], t[1]] - }; - searchData.push(tmp); - } - } - } else { - // no search fields, loop thru columns - for (var c in this.columns) { - var tmp = { - field : this.columns[c].field, - type : 'text', - operator : 'contains', - value : value - }; - searchData.push(tmp); - } - } - } else { - var el = $('#grid_'+ this.name +'_search_all'); - var search = this.getSearch(field); - if (search == null) search = { field: field, type: 'text' }; - if (search.field == field) this.last.caption = search.caption; - if (search.type == 'list') { - var tmp = el.data('selected'); - if (tmp && !$.isEmptyObject(tmp)) value = tmp.id; - } - if (value != '') { - var op = 'contains'; - var val = value; - if (w2utils.isInt(value)) op = 'is'; - if (['date', 'time'].indexOf(search.type) != -1) op = 'is'; - if (search.type == 'int' && value != '') { - if (String(value).indexOf('-') != -1) { - var tmp = value.split('-'); - if (tmp.length == 2) { - op = 'between'; - val = [parseInt(tmp[0]), parseInt(tmp[1])]; - } - } - if (String(value).indexOf(',') != -1) { - var tmp = value.split(','); - op = 'in'; - val = []; - for (var t in tmp) val.push(tmp[t]); - } - } - var tmp = { - field : search.field, - type : search.type, - operator : op, - value : val - } - searchData.push(tmp); - } - } - } - } - // 3: search([ { field, value, [operator,] [type] }, { field, value, [operator,] [type] } ], logic) - submit whole structure - if ($.isArray(field)) { - var logic = 'AND'; - if (typeof value == 'string') { - logic = value.toUpperCase(); - if (logic != 'OR' && logic != 'AND') logic = 'AND'; - } - last_search = ''; - last_multi = true; - last_logic = logic; - for (var f in field) { - var data = field[f]; - var search = this.getSearch(data.field); - if (search == null) search = { type: 'text', operator: 'contains' }; - // merge current field and search if any - searchData.push($.extend(true, {}, search, data)); - } - } - // event before - var eventData = this.trigger({ phase: 'before', type: 'search', target: this.name, searchData: searchData, - searchField: (field ? field : 'multi'), searchValue: (value ? value : 'multi') }); - if (eventData.isCancelled === true) return; - // default action - this.searchData = eventData.searchData; - this.last.field = last_field; - this.last.search = last_search; - this.last.multi = last_multi; - this.last.logic = last_logic; - this.last.scrollTop = 0; - this.last.scrollLeft = 0; - this.last.selection.indexes = []; - this.last.selection.columns = {}; - // -- clear all search field - this.searchClose(); - this.set({ expanded: false }, true); - // apply search - if (url) { - this.last.xhr_offset = 0; - this.reload(); - } else { - // local search - this.localSearch(); - this.refresh(); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - searchOpen: function () { - if (!this.box) return; - if (this.searches.length == 0) return; - var obj = this; - // show search - $('#tb_'+ this.name +'_toolbar_item_w2ui-search-advanced').w2overlay( - this.getSearchesHTML(), { - name : 'searches-'+ this.name, - left : -10, - 'class' : 'w2ui-grid-searches', - onShow : function () { - if (obj.last.logic == 'OR') obj.searchData = []; - obj.initSearches(); - $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches').data('grid-name', obj.name); - var sfields = $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches *[rel=search]'); - if (sfields.length > 0) sfields[0].focus(); - } - } - ); - }, - - searchClose: function () { - if (!this.box) return; - if (this.searches.length == 0) return; - if (this.toolbar) this.toolbar.uncheck('w2ui-search-advanced') - // hide search - if ($('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches').length > 0) { - $().w2overlay('', { name: 'searches-'+ this.name }); - } - }, - - searchShowFields: function () { - var el = $('#grid_'+ this.name +'_search_all'); - var html = '
        '; - for (var s = -1; s < this.searches.length; s++) { - var search = this.searches[s]; - if (s == -1) { - if (!this.multiSearch) continue; - search = { field: 'all', caption: w2utils.lang('All Fields') }; - } else { - if (this.searches[s].hidden === true) continue; - } - html += ''+ - ' '+ - ' '+ - ''; - } - html += "
        '+ search.caption +'
        "; - // need timer otherwise does nto show with list type - setTimeout(function () { - $(el).w2overlay(html, { left: -10 }); - }, 1); - }, - - initAllField: function (field, value) { - var el = $('#grid_'+ this.name +'_search_all'); - var search = this.getSearch(field); - if (field == 'all') { - search = { field: 'all', caption: w2utils.lang('All Fields') }; - el.w2field('clear'); - el.change().focus(); - } else { - var st = search.type; - if (['enum', 'select'].indexOf(st) != -1) st = 'list'; - el.w2field(st, $.extend({}, search.options, { suffix: '', autoFormat: false, selected: value })); - if (['list', 'enum'].indexOf(search.type) != -1) { - this.last.search = ''; - this.last.item = ''; - el.val(''); - } - // set focus - setTimeout(function () { - el.focus(); /* do not do el.change() as it will refresh grid and pull from server */ - }, 1); - } - // update field - if (this.last.search != '') { - this.search(search.field, this.last.search); - } else { - this.last.field = search.field; - this.last.caption = search.caption; - } - el.attr('placeholder', search.caption); - $().w2overlay(); - }, - - searchReset: function (noRefresh) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'search', target: this.name, searchData: [] }); - if (eventData.isCancelled === true) return; - // default action - this.searchData = []; - this.last.search = ''; - this.last.logic = 'OR'; - // --- do not reset to All Fields (I think) - // if (this.last.multi) { - // if (!this.multiSearch) { - // this.last.field = this.searches[0].field; - // this.last.caption = this.searches[0].caption; - // } else { - // this.last.field = 'all'; - // this.last.caption = w2utils.lang('All Fields'); - // } - // } - this.last.multi = false; - this.last.xhr_offset = 0; - // reset scrolling position - this.last.scrollTop = 0; - this.last.scrollLeft = 0; - this.last.selection.indexes = []; - this.last.selection.columns = {}; - // -- clear all search field - this.searchClose(); - $('#grid_'+ this.name +'_search_all').val(''); - // apply search - if (!noRefresh) this.reload(); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - clear: function (noRefresh) { - this.offset = 0; - this.total = 0; - this.buffered = 0; - this.records = []; - this.summary = []; - this.last.scrollTop = 0; - this.last.scrollLeft = 0; - this.last.range_start = null; - this.last.range_end = null; - this.last.xhr_offset = 0; - if (!noRefresh) this.refresh(); - }, - - reset: function (noRefresh) { - // reset last remembered state - this.offset = 0; - this.last.scrollTop = 0; - this.last.scrollLeft = 0; - this.last.selection.indexes = []; - this.last.selection.columns = {}; - this.last.range_start = null; - this.last.range_end = null; - this.last.xhr_offset = 0; - this.searchReset(noRefresh); - // initial sort - if (this.last.sortData != null ) this.sortData = this.last.sortData; - // select none without refresh - this.set({ expanded: false }, true); - // refresh - if (!noRefresh) this.refresh(); - }, - - skip: function (offset) { - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (url) { - this.offset = parseInt(offset); - if (this.offset < 0 || !w2utils.isInt(this.offset)) this.offset = 0; - if (this.offset > this.total) this.offset = this.total - this.limit; - this.records = []; - this.buffered = 0; - this.last.xhr_offset = 0; - this.last.pull_more = true; - this.last.scrollTop = 0; - this.last.scrollLeft = 0; - $('#grid_'+ this.name +'_records').prop('scrollTop', 0); - this.initColumnOnOff(); - this.reload(); - } else { - console.log('ERROR: grid.skip() can only be called when you have remote data source.'); - } - }, - - load: function (url, callBack) { - if (typeof url == 'undefined') { - console.log('ERROR: You need to provide url argument when calling .load() method of "'+ this.name +'" object.'); - return; - } - // default action - this.request('get-records', {}, url, callBack); - }, - - reload: function (callBack) { - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (url) { - this.clear(true); - this.request('get-records', {}, null, callBack); - } else { - this.last.scrollTop = 0; - this.last.scrollLeft = 0; - this.last.range_start = null; - this.last.range_end = null; - this.localSearch(); - this.refresh(); - if (typeof callBack == 'function') callBack({ status: 'success' }); - } - }, - - request: function (cmd, add_params, url, callBack) { - if (typeof add_params == 'undefined') add_params = {}; - if (typeof url == 'undefined' || url == '' || url == null) url = this.url; - if (url == '' || url == null) return; - // build parameters list - var params = {}; - if (!w2utils.isInt(this.offset)) this.offset = 0; - if (!w2utils.isInt(this.last.xhr_offset)) this.last.xhr_offset = 0; - // add list params - params['cmd'] = cmd; - params['selected'] = this.getSelection(); - params['limit'] = this.limit; - params['offset'] = parseInt(this.offset) + this.last.xhr_offset; - params['search'] = this.searchData; - params['searchLogic'] = this.last.logic; - params['sort'] = (this.sortData.length != 0 ? this.sortData : ''); - // append other params - $.extend(params, this.postData); - $.extend(params, add_params); - // event before - if (cmd == 'get-records') { - var eventData = this.trigger({ phase: 'before', type: 'request', target: this.name, url: url, postData: params }); - if (eventData.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } - } else { - var eventData = { url: url, postData: params }; - } - // call server to get data - var obj = this; - if (this.last.xhr_offset == 0) { - this.lock(this.msgRefresh, true); - } else { - var more = $('#grid_'+ this.name +'_rec_more'); - if (this.autoLoad === true) { - more.show().find('td').html('
        '); - } else { - more.find('td').html('
        '+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
        '); - } - } - if (this.last.xhr) try { this.last.xhr.abort(); } catch (e) {}; - var xhr_type = 'GET'; - var url = (typeof eventData.url != 'object' ? eventData.url : eventData.url.get); - if (params.cmd == 'save-records') { - if (typeof eventData.url == 'object') url = eventData.url.save; - xhr_type = 'PUT'; // so far it is always update - } - if (params.cmd == 'delete-records') { - if (typeof eventData.url == 'object') url = eventData.url.remove; - xhr_type = 'DELETE'; - } - if (!w2utils.settings.RESTfull) xhr_type = 'POST'; - if (this.method) xhr_type = this.method; - this.last.xhr_cmd = params.cmd; - this.last.xhr_start = (new Date()).getTime(); - this.last.xhr = $.ajax({ - type : xhr_type, - url : url, - data : (typeof eventData.postData == 'object' ? String($.param(eventData.postData, false)).replace(/%5B/g, '[').replace(/%5D/g, ']') : eventData.postData), - dataType : 'text', - complete : function (xhr, status) { - obj.requestComplete(status, cmd, callBack); - } - }); - if (cmd == 'get-records') { - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - }, - - requestComplete: function(status, cmd, callBack) { - var obj = this; - this.unlock(); - setTimeout(function () { obj.status(w2utils.lang('Server Response') + ' ' + ((new Date()).getTime() - obj.last.xhr_start)/1000 +' ' + w2utils.lang('sec')); }, 10); - this.last.pull_more = false; - this.last.pull_refresh = true; - - // event before - var event_name = 'load'; - if (this.last.xhr_cmd == 'save-records') event_name = 'save'; - if (this.last.xhr_cmd == 'delete-records') event_name = 'deleted'; - var eventData = this.trigger({ phase: 'before', target: this.name, type: event_name, xhr: this.last.xhr, status: status }); - if (eventData.isCancelled === true) { - if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); - return; - } - // parse server response - var data; - var responseText = this.last.xhr.responseText; - if (status != 'error') { - // default action - if (typeof responseText != 'undefined' && responseText != '') { - // check if the onLoad handler has not already parsed the data - if (typeof responseText == "object") { - data = responseText; - } else { - if (typeof obj.parser == 'function') { - data = obj.parser(responseText); - if (typeof data != 'object') { - console.log('ERROR: Your parser did not return proper object'); - } - } else { - // $.parseJSON or $.getJSON did not work because those expect perfect JSON data - where everything is in double quotes - // - // TODO: avoid (potentially malicious) code injection from the response. - try { eval('data = '+ responseText); } catch (e) { } - } - } - // convert recids - if (obj.recid) { - for (var r in data.records) { - data.records[r]['recid'] = data.records[r][obj.recid]; - } - } - if (typeof data == 'undefined') { - data = { - status : 'error', - message : this.msgNotJSON, - responseText : responseText - }; - } - if (data['status'] == 'error') { - obj.error(data['message']); - } else { - if (cmd == 'get-records') { - if (this.last.xhr_offset == 0) { - this.records = []; - this.summary = []; - //data.xhr_status=data.status; - delete data.status; - $.extend(true, this, data); - this.buffered = this.records.length; - } else { - var records = data.records; - delete data.records; - //data.xhr_status=data.status; - delete data.status; - $.extend(true, this, data); - for (var r in records) { - this.records.push(records[r]); - } - this.buffered = this.records.length; - } - } - if (cmd == 'delete-records') { - this.reset(); // unselect old selections - this.reload(); - return; - } - } - } - } else { - data = { - status : 'error', - message : this.msgAJAXerror, - responseText : responseText - }; - obj.error(this.msgAJAXerror); - } - // event after - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (!url) { - this.localSort(); - this.localSearch(); - } - this.total = parseInt(this.total); - this.trigger($.extend(eventData, { phase: 'after' })); - // do not refresh if loading on infinite scroll - if (this.last.xhr_offset == 0) this.refresh(); else this.scroll(); - // call back - if (typeof callBack == 'function') callBack(data); - }, - - error: function (msg) { - var obj = this; - // let the management of the error outside of the grid - var eventData = this.trigger({ target: this.name, type: 'error', message: msg , xhr: this.last.xhr }); - if (eventData.isCancelled === true) { - if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); - return; - } - w2alert(msg, 'Error'); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - getChanges: function () { - var changes = []; - for (var r in this.records) { - var rec = this.records[r]; - if (typeof rec['changes'] != 'undefined') { - changes.push($.extend(true, { recid: rec.recid }, rec.changes)); - } - } - return changes; - }, - - mergeChanges: function () { - var changes = this.getChanges(); - for (var c in changes) { - var record = this.get(changes[c].recid); - for (var s in changes[c]) { - if (s == 'recid') continue; // do not allow to change recid - try { eval('record.' + s + ' = changes[c][s]'); } catch (e) {} - delete record.changes; - } - } - this.refresh(); - }, - - // =================================================== - // -- Action Handlers - - save: function () { - var obj = this; - var changes = this.getChanges(); - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'submit', changes: changes }); - if (eventData.isCancelled === true) return; - var url = (typeof this.url != 'object' ? this.url : this.url.save); - if (url) { - this.request('save-records', { 'changes' : eventData.changes }, null, - function (data) { - if (data.status !== 'error') { - // only merge changes, if save was successful - obj.mergeChanges(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - ); - } else { - this.mergeChanges(); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - }, - - editField: function (recid, column, value, event) { - var obj = this; - var index = obj.get(recid, true); - var rec = obj.records[index]; - var col = obj.columns[column]; - var edit = col ? col.editable : null; - if (!rec || !col || !edit || rec.editable === false) return; - if (['enum', 'file'].indexOf(edit.type) != -1) { - console.log('ERROR: input types "enum" and "file" are not supported in inline editing.'); - return; - } - // event before - var eventData = obj.trigger({ phase: 'before', type: 'editField', target: obj.name, recid: recid, column: column, value: value, - index: index, originalEvent: event }); - if (eventData.isCancelled === true) return; - value = eventData.value; - // default behaviour - this.selectNone(); - this.select({ recid: recid, column: column }); - this.last.edit_col = column; - if (['checkbox', 'check'].indexOf(edit.type) != -1) return; - // create input element - var tr = $('#grid_'+ obj.name +'_rec_'+ w2utils.escapeId(recid)); - var el = tr.find('[col='+ column +'] > div'); - if (typeof edit.inTag == 'undefined') edit.inTag = ''; - if (typeof edit.outTag == 'undefined') edit.outTag = ''; - if (typeof edit.style == 'undefined') edit.style = ''; - if (typeof edit.items == 'undefined') edit.items = []; - var val = (rec.changes && typeof rec.changes[col.field] != 'undefined' ? w2utils.stripTags(rec.changes[col.field]) : w2utils.stripTags(rec[col.field])); - if (val == null || typeof val == 'undefined') val = ''; - if (typeof value != 'undefined' && value != null) val = value; - var addStyle = (typeof col.style != 'undefined' ? col.style + ';' : ''); - if (typeof col.render == 'string' && ['number', 'int', 'float', 'money', 'percent'].indexOf(col.render.split(':')[0]) != -1) { - addStyle += 'text-align: right;'; - } - if (edit.type == 'select') { - var html = ''; - for (var i in edit.items) { - html += ''; - } - el.addClass('w2ui-editable') - .html('' + edit.outTag); - el.find('select').focus() - .on('change', function (event) { - delete obj.last.move; - }) - .on('blur', function (event) { - obj.editChange.call(obj, this, index, column, event); - }); - } else { - el.addClass('w2ui-editable') - .html('' + edit.outTag); - if (value == null) el.find('input').val(val != 'object' ? val : ''); - // init w2field - var input = el.find('input').get(0); - $(input).w2field(edit.type, $.extend(edit, { selected: val })) - // add blur listener - setTimeout(function () { - var tmp = input; - if (edit.type == 'list') { - tmp = $($(input).data('w2field').helpers.focus).find('input'); - if (val != 'object' && val != '') tmp.val(val).css({ opacity: 1 }).prev().css({ opacity: 1 }); - } - $(tmp).on('blur', function (event) { - obj.editChange.call(obj, input, index, column, event); - }); - }, 10); - if (value != null) $(input).val(val != 'object' ? val : ''); - } - setTimeout(function () { - el.find('input, select') - .on('click', function (event) { - event.stopPropagation(); - }) - .on('keydown', function (event) { - var cancel = false; - switch (event.keyCode) { - case 9: // tab - cancel = true; - var next_rec = recid; - var next_col = event.shiftKey ? obj.prevCell(column, true) : obj.nextCell(column, true); - // next or prev row - if (next_col === false) { - var tmp = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); - if (tmp != null && tmp != index) { - next_rec = obj.records[tmp].recid; - // find first editable row - for (var c in obj.columns) { - var tmp = obj.columns[c].editable; - if (typeof tmp != 'undefined' && ['checkbox', 'check'].indexOf(tmp.type) == -1) { - next_col = parseInt(c); - if (!event.shiftKey) break; - } - } - } - - } - if (next_rec === false) next_rec = recid; - if (next_col === false) next_col = column; - // init new or same record - this.blur(); - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: next_rec, column: next_col }); - } else { - obj.editField(next_rec, next_col, null, event); - } - }, 1); - break; - - case 13: // enter - this.blur(); - var next = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); - if (next != null && next != index) { - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: obj.records[next].recid, column: column }); - } else { - obj.editField(obj.records[next].recid, column, null, event); - } - }, 100); - } - break; - - case 38: // up arrow - if (!event.shiftKey) break; - cancel = true; - var next = obj.prevRow(index); - if (next != index) { - this.blur(); - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: obj.records[next].recid, column: column }); - } else { - obj.editField(obj.records[next].recid, column, null, event); - } - }, 1); - } - break; - - case 40: // down arrow - if (!event.shiftKey) break; - cancel = true; - var next = obj.nextRow(index); - if (next != null && next != index) { - this.blur(); - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: obj.records[next].recid, column: column }); - } else { - obj.editField(obj.records[next].recid, column, null, event); - } - }, 1); - } - break; - - case 27: // escape - var old = obj.parseField(rec, col.field); - if (rec.changes && typeof rec.changes[col.field] != 'undefined') old = rec.changes[col.field]; - this.value = typeof old != 'undefined' ? old : ''; - this.blur(); - setTimeout(function () { obj.select({ recid: recid, column: column }) }, 1); - break; - } - if (cancel) if (event.preventDefault) event.preventDefault(); - }); - // focus and select - var tmp = el.find('input').focus(); - if (value != null) { - // set cursor to the end - tmp[0].setSelectionRange(tmp.val().length, tmp.val().length); - } else { - tmp.select(); - } - - }, 1); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - editChange: function (el, index, column, event) { - // all other fields - var summary = index < 0; - index = index < 0 ? -index - 1 : index; - var records = summary ? this.summary : this.records; - var rec = records[index]; - var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)); - var col = this.columns[column]; - var new_val = el.value; - var old_val = this.parseField(rec, col.field); - var tmp = $(el).data('w2field'); - if (tmp) { - new_val = tmp.clean(new_val); - if (tmp.type == 'list' && new_val != '') new_val = $(el).data('selected'); - } - if (el.type == 'checkbox') new_val = el.checked; - // change/restore event - var eventData = { - phase: 'before', type: 'change', target: this.name, input_id: el.id, recid: rec.recid, index: index, column: column, - value_new: new_val, value_previous: (rec.changes && rec.changes.hasOwnProperty(col.field) ? rec.changes[col.field]: old_val), value_original: old_val - }; - while (true) { - new_val = eventData.value_new; - if (( typeof old_val == 'undefined' || old_val === null ? '' : String(old_val)) !== String(new_val)) { - // change event - eventData = this.trigger($.extend(eventData, { type: 'change', phase: 'before' })); - if (eventData.isCancelled !== true) { - if (new_val !== eventData.value_new) { - // re-evaluate the type of change to be made - continue; - } - // default action - rec.changes = rec.changes || {}; - rec.changes[col.field] = eventData.value_new; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - } else { - // restore event - eventData = this.trigger($.extend(eventData, { type: 'restore', phase: 'before' })); - if (eventData.isCancelled !== true) { - if (new_val !== eventData.value_new) { - // re-evaluate the type of change to be made - continue; - } - // default action - if (rec.changes) delete rec.changes[col.field]; - if ($.isEmptyObject(rec.changes)) delete rec.changes; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - } - break; - } - // refresh cell - var cell = this.getCellHTML(index, column, summary); - if (!summary) { - if (rec.changes && typeof rec.changes[col.field] != 'undefined') { - $(tr).find('[col='+ column +']').addClass('w2ui-changed').html(cell); - } else { - $(tr).find('[col='+ column +']').removeClass('w2ui-changed').html(cell); - } - } - }, - - delete: function (force) { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'delete', force: force }); - if (eventData.isCancelled === true) return; - force = eventData.force; - // default action - var recs = this.getSelection(); - if (recs.length == 0) return; - if (this.msgDelete != '' && !force) { - w2confirm({ - title : w2utils.lang('Delete Confirmation'), - msg : obj.msgDelete, - callBack: function (result) { - console.log('result', result); - if (result == 'Yes') w2ui[obj.name].delete(true); - } - }); - return; - } - // call delete script - var url = (typeof this.url != 'object' ? this.url : this.url.remove); - if (url) { - this.request('delete-records'); - } else { - this.selectNone(); - if (typeof recs[0] != 'object') { - this.remove.apply(this, recs); - } else { - // clear cells - for (var r in recs) { - var fld = this.columns[recs[r].column].field; - var ind = this.get(recs[r].recid, true); - if (ind != null && fld != 'recid') { - this.records[ind][fld] = ''; - if (this.records[ind].changes) delete this.records[ind].changes[fld]; - } - } - this.refresh(); - } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - click: function (recid, event) { - var time = (new Date()).getTime(); - var column = null; - if (this.last.cancelClick == true) return; - if (typeof recid == 'object') { - column = recid.column; - recid = recid.recid; - } - if (typeof event == 'undefined') event = {}; - // check for double click - if (time - parseInt(this.last.click_time) < 250 && event.type == 'click') { - this.dblClick(recid, event); - return; - } - this.last.click_time = time; - // column user clicked on - if (column == null && event.target) { - var tmp = event.target; - if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; - if (typeof $(tmp).attr('col') != 'undefined') column = parseInt($(tmp).attr('col')); - } - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'click', recid: recid, column: column, originalEvent: event }); - if (eventData.isCancelled === true) return; - // if it is subgrid unselect top grid - var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)).parents('tr'); - if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var grid = parent.parents('.w2ui-grid').attr('name'); - w2ui[grid].selectNone(); - // all subgrids - parent.parents('.w2ui-grid').find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { - var grid = $(el).attr('name'); - if (w2ui[grid]) w2ui[grid].selectNone(); - }); - } - // unselect all subgrids - $(this.box).find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { - var grid = $(el).attr('name'); - if (w2ui[grid]) w2ui[grid].selectNone(); - }); - // default action - var obj = this; - var sel = this.getSelection(); - $('#grid_'+ this.name +'_check_all').prop("checked", false); - var ind = this.get(recid, true); - var record = this.records[ind]; - var selectColumns = []; - obj.last.sel_ind = ind; - obj.last.sel_col = column; - obj.last.sel_recid = recid; - obj.last.sel_type = 'click'; - // multi select with shif key - if (event.shiftKey && sel.length > 0 && obj.multiSelect) { - if (sel[0].recid) { - var start = this.get(sel[0].recid, true); - var end = this.get(recid, true); - if (column > sel[0].column) { - var t1 = sel[0].column; - var t2 = column; - } else { - var t1 = column; - var t2 = sel[0].column; - } - for (var c = t1; c <= t2; c++) selectColumns.push(c); - } else { - var start = this.get(sel[0], true); - var end = this.get(recid, true); - } - var sel_add = [] - if (start > end) { var tmp = start; start = end; end = tmp; } - var url = (typeof this.url != 'object' ? this.url : this.url.get); - for (var i = start; i <= end; i++) { - if (this.searchData.length > 0 && !url && $.inArray(i, this.last.searchIds) == -1) continue; - if (this.selectType == 'row') { - sel_add.push(this.records[i].recid); - } else { - for (var sc in selectColumns) sel_add.push({ recid: this.records[i].recid, column: selectColumns[sc] }); - } - //sel.push(this.records[i].recid); - } - this.select.apply(this, sel_add); - } else { - var last = this.last.selection; - var flag = (last.indexes.indexOf(ind) != -1 ? true : false); - // clear other if necessary - if (((!event.ctrlKey && !event.shiftKey && !event.metaKey) || !this.multiSelect) && !this.showSelectColumn) { - if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; - if (sel.length > 300) this.selectNone(); else this.unselect.apply(this, sel); - if (flag === true) { - this.unselect({ recid: recid, column: column }); - } else { - this.select({ recid: recid, column: column }); - } - } else { - if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; - if (flag === true) { - this.unselect({ recid: recid, column: column }); - } else { - this.select({ recid: recid, column: column }); - } - } - } - this.status(); - obj.initResize(); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - columnClick: function (field, event) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'columnClick', target: this.name, field: field, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behaviour - var column = this.getColumn(field); - if (column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false) ); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - keydown: function (event) { - // this method is called from w2utils - var obj = this; - if (obj.keyboard !== true) return; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behavior - var empty = false; - var records = $('#grid_'+ obj.name +'_records'); - var sel = obj.getSelection(); - if (sel.length == 0) empty = true; - var recid = sel[0] || null; - var columns = []; - var recid2 = sel[sel.length-1]; - if (typeof recid == 'object' && recid != null) { - recid = sel[0].recid; - columns = []; - var ii = 0; - while (true) { - if (!sel[ii] || sel[ii].recid != recid) break; - columns.push(sel[ii].column); - ii++; - } - recid2 = sel[sel.length-1].recid; - } - var ind = obj.get(recid, true); - var ind2 = obj.get(recid2, true); - var rec = obj.get(recid); - var recEL = $('#grid_'+ obj.name +'_rec_'+ (ind !== null ? w2utils.escapeId(obj.records[ind].recid) : 'none')); - var cancel = false; - var key = event.keyCode; - var shiftKey= event.shiftKey; - if (key == 9) { // tab key - if (event.shiftKey) key = 37; else key = 39; // replace with arrows - shiftKey = false; - cancel = true; - } - switch (key) { - case 8: // backspace - case 46: // delete - obj.delete(); - cancel = true; - event.stopPropagation(); - break; - - case 27: // escape - obj.selectNone(); - if (sel.length > 0 && typeof sel[0] == 'object') { - obj.select({ recid: sel[0].recid, column: sel[0].column }); - } - cancel = true; - break; - - case 65: // cmd + A - if (!event.metaKey && !event.ctrlKey) break; - obj.selectAll(); - cancel = true; - break; - - case 70: // cmd + F - if (!event.metaKey && !event.ctrlKey) break; - $('#grid_'+ obj.name + '_search_all').focus(); - cancel = true; - break; - - case 13: // enter - // if expandable columns - expand it - if (this.selectType == 'row' && obj.show.expandColumn === true) { - if (recEL.length <= 0) break; - obj.toggle(recid, event); - cancel = true; - } else { // or enter edit - for (var c in this.columns) { - if (this.columns[c].editable) { - columns.push(parseInt(c)); - break; - } - } - // edit last column that was edited - if (this.selectType == 'row' && this.last.edit_col) columns = [this.last.edit_col]; - if (columns.length > 0) { - obj.editField(recid, columns[0], null, event); - cancel = true; - } - } - break; - - case 37: // left - if (empty) break; - // check if this is subgrid - var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind].recid)).parents('tr'); - if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var recid = parent.prev().attr('recid'); - var grid = parent.parents('.w2ui-grid').attr('name'); - obj.selectNone(); - w2utils.keyboard.active(grid); - w2ui[grid].set(recid, { expanded: false }); - w2ui[grid].collapse(recid); - w2ui[grid].click(recid); - cancel = true; - break; - } - if (this.selectType == 'row') { - if (recEL.length <= 0 || rec.expanded !== true ) break; - obj.set(recid, { expanded: false }, true); - obj.collapse(recid, event); - } else { - var prev = obj.prevCell(columns[0]); - if (prev !== false) { - if (shiftKey && obj.multiSelect) { - if (tmpUnselect()) return; - var tmp = []; - var newSel = []; - var unSel = []; - if (columns.indexOf(this.last.sel_col) == 0 && columns.length > 1) { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - unSel.push({ recid: sel[i].recid, column: columns[columns.length-1] }); - } - } else { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - newSel.push({ recid: sel[i].recid, column: prev }); - } - } - obj.unselect.apply(obj, unSel); - obj.select.apply(obj, newSel); - } else { - event.shiftKey = false; - obj.click({ recid: recid, column: prev }, event); - } - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=1; s 1) { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - unSel.push({ recid: sel[i].recid, column: columns[0] }); - } - } else { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - newSel.push({ recid: sel[i].recid, column: next }); - } - } - obj.unselect.apply(obj, unSel); - obj.select.apply(obj, newSel); - } else { - obj.click({ recid: recid, column: next }, event); - } - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=0; s 0 && w2ui[subgrid.attr('name')]) { - obj.selectNone(); - var grid = subgrid.attr('name'); - var recs = w2ui[grid].records; - w2utils.keyboard.active(grid); - w2ui[grid].click(recs[recs.length-1].recid); - cancel = true; - break; - } - } - if (shiftKey && obj.multiSelect) { // expand selection - if (tmpUnselect()) return; - if (obj.selectType == 'row') { - if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { - obj.unselect(obj.records[ind2].recid); - } else { - obj.select(obj.records[prev].recid); - } - } else { - if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { - prev = ind2; - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); - obj.unselect.apply(obj, tmp); - } else { - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); - obj.select.apply(obj, tmp); - } - } - } else { // move selected record - obj.selectNone(); - obj.click({ recid: obj.records[prev].recid, column: columns[0] }, event); - } - obj.scrollIntoView(prev); - if (event.preventDefault) event.preventDefault(); - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=1; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var recid = parent.prev().attr('recid'); - var grid = parent.parents('.w2ui-grid').attr('name'); - obj.selectNone(); - w2utils.keyboard.active(grid); - w2ui[grid].click(recid); - cancel = true; - break; - } - } - break; - - case 40: // down - if (empty) selectTopRecord(); - if (recEL.length <= 0) break; - // jump into subgrid - if (obj.records[ind2].expanded) { - var subgrid = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind2].recid) +'_expanded_row').find('.w2ui-grid'); - if (subgrid.length > 0 && w2ui[subgrid.attr('name')]) { - obj.selectNone(); - var grid = subgrid.attr('name'); - var recs = w2ui[grid].records; - w2utils.keyboard.active(grid); - w2ui[grid].click(recs[0].recid); - cancel = true; - break; - } - } - // move to the next record - var next = obj.nextRow(ind2); - if (next != null) { - if (shiftKey && obj.multiSelect) { // expand selection - if (tmpUnselect()) return; - if (obj.selectType == 'row') { - if (this.last.sel_ind < next && this.last.sel_ind != ind) { - obj.unselect(obj.records[ind].recid); - } else { - obj.select(obj.records[next].recid); - } - } else { - if (this.last.sel_ind < next && this.last.sel_ind != ind) { - next = ind; - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); - obj.unselect.apply(obj, tmp); - } else { - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); - obj.select.apply(obj, tmp); - } - } - } else { // move selected record - obj.selectNone(); - obj.click({ recid: obj.records[next].recid, column: columns[0] }, event); - } - obj.scrollIntoView(next); - cancel = true; - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=0; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var recid = parent.next().attr('recid'); - var grid = parent.parents('.w2ui-grid').attr('name'); - obj.selectNone(); - w2utils.keyboard.active(grid); - w2ui[grid].click(recid); - cancel = true; - break; - } - } - break; - - case 86: // v - paste - if (empty) break; - if (event.ctrlKey || event.metaKey) { - $('body').append(''); - $('#_tmp_copy_data').focus(); - setTimeout(function () { - obj.paste($('#_tmp_copy_data').val()); - $('#_tmp_copy_data').remove(); - }, 50); // need timer to allow paste - } - break; - - case 88: // x - cut - if (empty) break; - if (event.ctrlKey || event.metaKey) { - setTimeout(function () { obj.delete(true); }, 100); - } - case 67: // c - copy - if (empty) break; - if (event.ctrlKey || event.metaKey) { - var text = obj.copy(); - $('body').append(''); - $('#_tmp_copy_data').focus().select(); - setTimeout(function () { $('#_tmp_copy_data').remove(); }, 50); - } - break; - } - var tmp = [187, 189, 32]; // =-spacebar - for (var i=48; i<=90; i++) tmp.push(i); // 0-9,a-z,A-Z - if (tmp.indexOf(key) != -1 && !event.ctrlKey && !event.metaKey && !cancel) { - if (columns.length == 0) columns.push(0); - var tmp = String.fromCharCode(key); - if (key == 187) tmp = '='; - if (key == 189) tmp = '-'; - if (!shiftKey) tmp = tmp.toLowerCase(); - obj.editField(recid, columns[0], tmp, event); - cancel = true; - } - if (cancel) { // cancel default behaviour - if (event.preventDefault) event.preventDefault(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - - function selectTopRecord() { - var ind = Math.floor((records[0].scrollTop + (records.height() / 2.1)) / obj.recordHeight); - if (!obj.records[ind]) ind = 0; - obj.select({ recid: obj.records[ind].recid, column: 0}); - } - - function tmpUnselect () { - if (obj.last.sel_type != 'click') return false; - if (obj.selectType != 'row') { - obj.last.sel_type = 'key'; - if (sel.length > 1) { - for (var s in sel) { - if (sel[s].recid == obj.last.sel_recid && sel[s].column == obj.last.sel_col) { - sel.splice(s, 1); - break; - } - } - obj.unselect.apply(obj, sel); - return true; - } - return false; - } else { - obj.last.sel_type = 'key'; - if (sel.length > 1) { - sel.splice(sel.indexOf(obj.records[obj.last.sel_ind].recid), 1); - obj.unselect.apply(obj, sel); - return true; - } - return false; - } - } - }, - - scrollIntoView: function (ind) { - if (typeof ind == 'undefined') { - var sel = this.getSelection(); - if (sel.length == 0) return; - ind = this.get(sel[0], true); - } - var records = $('#grid_'+ this.name +'_records'); - if (records.length == 0) return; - // if all records in view - var len = this.last.searchIds.length; - if (records.height() > this.recordHeight * (len > 0 ? len : this.records.length)) return; - if (len > 0) ind = this.last.searchIds.indexOf(ind); // if seach is applied - // scroll to correct one - var t1 = Math.floor(records[0].scrollTop / this.recordHeight); - var t2 = t1 + Math.floor(records.height() / this.recordHeight); - if (ind == t1) records.animate({ 'scrollTop': records.scrollTop() - records.height() / 1.3 }, 250, 'linear'); - if (ind == t2) records.animate({ 'scrollTop': records.scrollTop() + records.height() / 1.3 }, 250, 'linear'); - if (ind < t1 || ind > t2) records.animate({ 'scrollTop': (ind - 1) * this.recordHeight }); - }, - - dblClick: function (recid, event) { - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // find columns - var column = null; - if (typeof recid == 'object') { - column = recid.column; - recid = recid.recid; - } - if (typeof event == 'undefined') event = {}; - // column user clicked on - if (column == null && event.target) { - var tmp = event.target; - if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; - column = parseInt($(tmp).attr('col')); - } - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'dblClick', recid: recid, column: column, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - this.selectNone(); - var col = this.columns[column]; - if (col && $.isPlainObject(col.editable)) { - this.editField(recid, column, null, event); - } else { - this.select({ recid: recid, column: column }); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - contextMenu: function (recid, event) { - var obj = this; - if (typeof event.offsetX === 'undefined') { - event.offsetX = event.layerX - event.target.offsetLeft; - event.offsetY = event.layerY - event.target.offsetTop; - } - if (w2utils.isFloat(recid)) recid = parseFloat(recid); - if (this.getSelection().indexOf(recid) == -1) obj.click(recid); - // need timeout to allow click to finish first - setTimeout(function () { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: obj.name, originalEvent: event, recid: recid }); - if (eventData.isCancelled === true) return; - // default action - if (obj.menu.length > 0) { - $(obj.box).find(event.target) - .w2menu(obj.menu, { - left : event.offsetX, - onSelect: function (event) { - obj.menuClick(recid, parseInt(event.index), event.originalEvent); - } - } - ); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 150); // need timer 150 for FF - }, - - menuClick: function (recid, index, event) { - var obj = this; - // event before - var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: obj.name, originalEvent: event, - recid: recid, menuIndex: index, menuItem: obj.menu[index] }); - if (eventData.isCancelled === true) return; - // default action - // -- empty - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - toggle: function (recid) { - var rec = this.get(recid); - if (rec.expanded === true) return this.collapse(recid); else return this.expand(recid); - }, - - expand: function (recid) { - var rec = this.get(recid); - var obj = this; - var id = w2utils.escapeId(recid); - if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length > 0) return false; - if (rec.expanded == 'none') return false; - // insert expand row - var tmp = 1 + (this.show.selectColumn ? 1 : 0); - var addClass = ''; // ($('#grid_'+this.name +'_rec_'+ w2utils.escapeId(recid)).hasClass('w2ui-odd') ? 'w2ui-odd' : 'w2ui-even'); - $('#grid_'+ this.name +'_rec_'+ id).after( - ''+ - (this.show.lineNumbers ? '' : '') + - '
        '+ - ' '+ - '
        '+ - ' '+ - ''); - // event before - var eventData = this.trigger({ phase: 'before', type: 'expand', target: this.name, recid: recid, - box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded', ready: ready }); - if (eventData.isCancelled === true) { - $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove(); - return; - } - // default action - $('#grid_'+ this.name +'_rec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded'); - $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').show(); - $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('
        '); - rec.expanded = true; - // check if height of expanded row > 5 then remove spinner - setTimeout(ready, 300); - function ready() { - var div1 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded'); - var div2 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row .w2ui-expanded1 > div'); - if (div1.height() < 5) return; - div1.css('opacity', 1); - div2.show().css('opacity', 1); - $('#grid_'+ obj.name +'_cell_'+ obj.get(recid, true) +'_expand div').html('-'); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.resizeRecords(); - return true; - }, - - collapse: function (recid) { - var rec = this.get(recid); - var obj = this; - var id = w2utils.escapeId(recid); - if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length == 0) return false; - // event before - var eventData = this.trigger({ phase: 'before', type: 'collapse', target: this.name, recid: recid, - box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded' }); - if (eventData.isCancelled === true) return; - // default action - $('#grid_'+ this.name +'_rec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded'); - $('#grid_'+ this.name +'_rec_'+ id +'_expanded').css('opacity', 0); - $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('+'); - setTimeout(function () { - $('#grid_'+ obj.name +'_rec_'+ id +'_expanded').height('0px'); - setTimeout(function () { - $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row').remove(); - delete rec.expanded; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resizeRecords(); - }, 300); - }, 200); - return true; - }, - - sort: function (field, direction, multiField) { // if no params - clears sort - // event before - var eventData = this.trigger({ phase: 'before', type: 'sort', target: this.name, field: field, direction: direction, multiField: multiField }); - if (eventData.isCancelled === true) return; - // check if needed to quit - if (typeof field != 'undefined') { - // default action - var sortIndex = this.sortData.length; - for (var s in this.sortData) { - if (this.sortData[s].field == field) { sortIndex = s; break; } - } - if (typeof direction == 'undefined' || direction == null) { - if (typeof this.sortData[sortIndex] == 'undefined') { - direction = 'asc'; - } else { - switch (String(this.sortData[sortIndex].direction)) { - case 'asc' : direction = 'desc'; break; - case 'desc' : direction = 'asc'; break; - default : direction = 'asc'; break; - } - } - } - if (this.multiSort === false) { this.sortData = []; sortIndex = 0; } - if (multiField != true) { this.sortData = []; sortIndex = 0; } - // set new sort - if (typeof this.sortData[sortIndex] == 'undefined') this.sortData[sortIndex] = {}; - this.sortData[sortIndex].field = field; - this.sortData[sortIndex].direction = direction; - } else { - this.sortData = []; - } - this.selectNone(); - // if local - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (!url) { - this.localSort(); - if (this.searchData.length > 0) this.localSearch(true); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(); - } else { - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.last.xhr_offset = 0; - this.reload(); - } - }, - - copy: function () { - var sel = this.getSelection(); - if (sel.length == 0) return ''; - var text = ''; - if (typeof sel[0] == 'object') { // cell copy - // find min/max column - var minCol = sel[0].column; - var maxCol = sel[0].column; - var recs = []; - for (var s in sel) { - if (sel[s].column < minCol) minCol = sel[s].column; - if (sel[s].column > maxCol) maxCol = sel[s].column; - if (recs.indexOf(sel[s].index) == -1) recs.push(sel[s].index); - } - recs.sort(); - for (var r in recs) { - var ind = recs[r]; - for (var c = minCol; c <= maxCol; c++) { - var col = this.columns[c]; - if (col.hidden === true) continue; - text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; - } - text = text.substr(0, text.length-1); // remove last \t - text += '\n'; - } - } else { // row copy - for (var s in sel) { - var ind = this.get(sel[s], true); - for (var c in this.columns) { - var col = this.columns[c]; - if (col.hidden === true) continue; - text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; - } - text = text.substr(0, text.length-1); // remove last \t - text += '\n'; - } - } - text = text.substr(0, text.length - 1); - // before event - var eventData = this.trigger({ phase: 'before', type: 'copy', target: this.name, text: text }); - if (eventData.isCancelled === true) return ''; - text = eventData.text; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return text; - }, - - paste: function (text) { - var sel = this.getSelection(); - var ind = this.get(sel[0].recid, true); - var col = sel[0].column; - // before event - var eventData = this.trigger({ phase: 'before', type: 'paste', target: this.name, text: text, index: ind, column: col }); - if (eventData.isCancelled === true) return; - text = eventData.text; - // default action - if (this.selectType == 'row' || sel.length == 0) { - console.log('ERROR: You can paste only if grid.selectType = \'cell\' and when at least one cell selected.'); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return; - } - var newSel = []; - var text = text.split('\n'); - for (var t in text) { - var tmp = text[t].split('\t'); - var cnt = 0; - var rec = this.records[ind]; - var cols = []; - for (var dt in tmp) { - if (!this.columns[col + cnt]) continue; - var field = this.columns[col + cnt].field; - rec.changes = rec.changes || {}; - rec.changes[field] = tmp[dt]; - cols.push(col + cnt); - cnt++; - } - for (var c in cols) newSel.push({ recid: rec.recid, column: cols[c] }); - ind++; - } - this.selectNone(); - this.select.apply(this, newSel); - this.refresh(); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - // ================================================== - // --- Common functions - - resize: function () { - var obj = this; - var time = (new Date()).getTime(); - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // make sure the box is right - if (!this.box || $(this.box).attr('name') != this.name) return; - // determine new width and height - $(this.box).find('> div') - .css('width', $(this.box).width()) - .css('height', $(this.box).height()); - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; - // resize - obj.resizeBoxes(); - obj.resizeRecords(); - // init editable - // $('#grid_'+ obj.name + '_records .w2ui-editable input').each(function (index, el) { - // var column = obj.columns[$(el).attr('column')]; - // if (column && column.editable) $(el).w2field(column.editable); - // }); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - refreshCell: function (recid, field) { - var index = this.get(recid, true); - var col_ind = this.getColumn(field, true); - var rec = this.records[index]; - var col = this.columns[col_ind]; - var cell = $('#grid_'+ this.name + '_rec_'+ recid +' [col='+ col_ind +']'); - // set cell html and changed flag - cell.html(this.getCellHTML(index, col_ind)); - if (rec.changes && typeof rec.changes[col.field] != 'undefined') { - cell.addClass('w2ui-changed'); - } else { - cell.removeClass('w2ui-changed'); - } - }, - - refreshRow: function (recid) { - var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); - if (tr.length != 0) { - var ind = this.get(recid, true); - var line = tr.attr('line'); - // if it is searched, find index in search array - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (this.searchData.length > 0 && !url) for (var s in this.last.searchIds) if (this.last.searchIds[s] == ind) ind = s; - $(tr).replaceWith(this.getRecordHTML(ind, line)); - } - - }, - - refresh: function () { - var obj = this; - var time = (new Date()).getTime(); - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (this.total <= 0 && !url && this.searchData.length == 0) { - this.total = this.records.length; - this.buffered = this.total; - } - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - this.toolbar.disable('w2ui-edit', 'w2ui-delete'); - if (!this.box) return; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'refresh' }); - if (eventData.isCancelled === true) return; - // -- header - if (this.show.header) { - $('#grid_'+ this.name +'_header').html(this.header +' ').show(); - } else { - $('#grid_'+ this.name +'_header').hide(); - } - // -- toolbar - if (this.show.toolbar) { - // if select-collumn is checked - no toolbar refresh - if (this.toolbar && this.toolbar.get('w2ui-column-on-off') && this.toolbar.get('w2ui-column-on-off').checked) { - // no action - } else { - $('#grid_'+ this.name +'_toolbar').show(); - // refresh toolbar all but search field - if (typeof this.toolbar == 'object') { - var tmp = this.toolbar.items; - for (var t in tmp) { - if (tmp[t].id == 'w2ui-search' || tmp[t].type == 'break') continue; - this.toolbar.refresh(tmp[t].id); - } - } - } - } else { - $('#grid_'+ this.name +'_toolbar').hide(); - } - // -- make sure search is closed - this.searchClose(); - // search placeholder - var el = $('#grid_'+ obj.name +'_search_all'); - if (!this.multiSearch && this.last.field == 'all' && this.searches.length > 0) { - this.last.field = this.searches[0].field; - this.last.caption = this.searches[0].caption; - } - for (var s in this.searches) { - if (this.searches[s].field == this.last.field) this.last.caption = this.searches[s].caption; - } - if (this.last.multi) { - el.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']'); - } else { - el.attr('placeholder', this.last.caption); - } - if (el.val() != this.last.search) { - var val = this.last.search; - var tmp = el.data('w2field'); - if (tmp) val = tmp.format(val); - el.val(val); - } - - // -- separate summary - var tmp = this.find({ summary: true }, true); - if (tmp.length > 0) { - for (var t in tmp) this.summary.push(this.records[tmp[t]]); - for (var t=tmp.length-1; t>=0; t--) this.records.splice(tmp[t], 1); - this.total = this.total - tmp.length; - this.buffered = this.buffered - tmp.length; - } - - // -- body - var bodyHTML = ''; - bodyHTML += '
        '+ - this.getRecordsHTML() + - '
        '+ - '
        '+ - ' '+ this.getColumnsHTML() +'
        '+ - '
        '; // Columns need to be after to be able to overlap - $('#grid_'+ this.name +'_body').html(bodyHTML); - // show summary records - if (this.summary.length > 0) { - $('#grid_'+ this.name +'_summary').html(this.getSummaryHTML()).show(); - } else { - $('#grid_'+ this.name +'_summary').hide(); - } - // -- footer - if (this.show.footer) { - $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()).show(); - } else { - $('#grid_'+ this.name +'_footer').hide(); - } - // show/hide clear search link - if (this.searchData.length > 0) { - $('#grid_'+ this.name +'_searchClear').show(); - } else { - $('#grid_'+ this.name +'_searchClear').hide(); - } - // all selected? - var sel = this.last.selection; - if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { - $('#grid_'+ this.name +'_check_all').prop('checked', true); - } else { - $('#grid_'+ this.name +'_check_all').prop('checked', false); - } - // show number of selected - this.status(); - // collapse all records - var rows = obj.find({ expanded: true }, true); - for (var r in rows) obj.records[rows[r]].expanded = false; - // mark selection - setTimeout(function () { - var str = $.trim($('#grid_'+ obj.name +'_search_all').val()); - if (str != '') $(obj.box).find('.w2ui-grid-data > div').w2marker(str); - }, 50); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - obj.addRange('selection'); - setTimeout(function () { obj.resize(); obj.scroll(); }, 1); // allow to render first - - if ( obj.reorderColumns && !obj.last.columnDrag ) { - obj.last.columnDrag = obj.initColumnDrag(); - } else if ( !obj.reorderColumns && obj.last.columnDrag ) { - obj.last.columnDrag.remove(); - } - - return (new Date()).getTime() - time; - }, - - render: function (box) { - var obj = this; - var time = (new Date()).getTime(); - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (typeof box != 'undefined' && box != null) { - if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-grid') - .html(''); - } - this.box = box; - } - if (!this.box) return; - if (this.last.sortData == null) this.last.sortData = this.sortData; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'render', box: box }); - if (eventData.isCancelled === true) return; - // insert Elements - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-grid') - .html('
        '+ - '
        '+ - '
        '+ - '
        '+ - '
        '+ - ' '+ - '
        '); - if (this.selectType != 'row') $(this.box).addClass('w2ui-ss'); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // init toolbar - this.initToolbar(); - if (this.toolbar != null) this.toolbar.render($('#grid_'+ this.name +'_toolbar')[0]); - // reinit search_all - if (this.last.field && this.last.field != 'all') { - var sd = this.searchData; - this.initAllField(this.last.field, (sd.length == 1 ? sd[0].value : null)); - } - // init footer - $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()); - // refresh - if (this.url) this.refresh(); // show empty grid (need it) - should it be only for remote data source - this.reload(); - - // init mouse events for mouse selection - $(this.box).on('mousedown', mouseStart); - $(this.box).on('selectstart', function () { return false; }); // fixes chrome cursor bug - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - // attach to resize event - if ($('.w2ui-layout').length == 0) { // if there is layout, it will send a resize event - this.tmp_resize = function (event) { w2ui[obj.name].resize(); } - $(window).off('resize', this.tmp_resize).on('resize', this.tmp_resize); - } - return (new Date()).getTime() - time; - - function mouseStart (event) { - if ($(event.target).parents().hasClass('w2ui-head') || $(event.target).hasClass('w2ui-head')) return; - if (obj.last.move && obj.last.move.type == 'expand') return; - if (!obj.multiSelect) return; - obj.last.move = { - x : event.screenX, - y : event.screenY, - divX : 0, - divY : 0, - recid : $(event.target).parents('tr').attr('recid'), - column : (event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')), - type : 'select', - ghost : false, - start : true - }; - $(document).on('mousemove', mouseMove); - $(document).on('mouseup', mouseStop); - } - - function mouseMove (event) { - var mv = obj.last.move; - if (!mv || mv.type != 'select') return; - mv.divX = (event.screenX - mv.x); - mv.divY = (event.screenY - mv.y); - if (Math.abs(mv.divX) <= 1 && Math.abs(mv.divY) <= 1) return; // only if moved more then 1px - obj.last.cancelClick = true; - if (obj.reorderRows == true) { - if (!mv.ghost) { - var row = $('#grid_'+ obj.name + '_rec_'+ mv.recid); - var tmp = row.parents('table').find('tr:first-child').clone(); - mv.offsetY = event.offsetY; - mv.from = mv.recid; - mv.pos = row.position(); - mv.ghost = $(row).clone(true); - mv.ghost.removeAttr('id'); - row.find('td:first-child').replaceWith(''); - var recs = $(obj.box).find('.w2ui-grid-records'); - recs.append('
        '); - $('#grid_'+ obj.name + '_ghost').append(tmp).append(mv.ghost); - } - var recid = $(event.target).parents('tr').attr('recid'); - if (recid != mv.from) { - var row1 = $('#grid_'+ obj.name + '_rec_'+ mv.recid); - var row2 = $('#grid_'+ obj.name + '_rec_'+ recid); - if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); - mv.lastY = event.screenY; - mv.to = recid; - } - var ghost = $('#grid_'+ obj.name + '_ghost'); - var recs = $(obj.box).find('.w2ui-grid-records'); - ghost.css({ - top : mv.pos.top + mv.divY + recs.scrollTop(), // + mv.offsetY - obj.recordHeight / 2, - left : mv.pos.left - }); - return; - } - if (mv.start && mv.recid) { - obj.selectNone(); - mv.start = false; - } - var newSel= []; - var recid = (event.target.tagName == 'TR' ? $(event.target).attr('recid') : $(event.target).parents('tr').attr('recid')); - if (typeof recid == 'undefined') return; - var ind1 = obj.get(mv.recid, true); - // |:wolfmanx:| this happens when selection is started on summary row - if (ind1 === null) return; - var ind2 = obj.get(recid, true); - // this happens when selection is extended into summary row (a good place to implement scrolling) - if (ind2 === null) return; - var col1 = parseInt(mv.column); - var col2 = parseInt(event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')); - if (ind1 > ind2) { var tmp = ind1; ind1 = ind2; ind2 = tmp; } - // check if need to refresh - var tmp = 'ind1:'+ ind1 +',ind2;'+ ind2 +',col1:'+ col1 +',col2:'+ col2; - if (mv.range == tmp) return; - mv.range = tmp; - for (var i = ind1; i <= ind2; i++) { - if (obj.last.searchIds.length > 0 && obj.last.searchIds.indexOf(i) == -1) continue; - if (obj.selectType != 'row') { - if (col1 > col2) { var tmp = col1; col1 = col2; col2 = tmp; } - var tmp = []; - for (var c = col1; c <= col2; c++) { - if (obj.columns[c].hidden) continue; - newSel.push({ recid: obj.records[i].recid, column: parseInt(c) }); - } - } else { - newSel.push(obj.records[i].recid); - } - } - if (obj.selectType != 'row') { - var sel = obj.getSelection(); - // add more items - var tmp = []; - for (var ns in newSel) { - var flag = false; - for (var s in sel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; - if (!flag) tmp.push({ recid: newSel[ns].recid, column: newSel[ns].column }); - } - obj.select.apply(obj, tmp); - // remove items - var tmp = []; - for (var s in sel) { - var flag = false; - for (var ns in newSel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; - if (!flag) tmp.push({ recid: sel[s].recid, column: sel[s].column }); - } - obj.unselect.apply(obj, tmp); - } else { - if (obj.multiSelect) { - var sel = obj.getSelection(); - for (var ns in newSel) if (sel.indexOf(newSel[ns]) == -1) obj.select(newSel[ns]); // add more items - for (var s in sel) if (newSel.indexOf(sel[s]) == -1) obj.unselect(sel[s]); // remove items - } - } - } - - function mouseStop (event) { - var mv = obj.last.move; - setTimeout(function () { delete obj.last.cancelClick; }, 1); - if ($(event.target).parents().hasClass('.w2ui-head') || $(event.target).hasClass('.w2ui-head')) return; - if (!mv || mv.type != 'select') return; - if (obj.reorderRows == true) { - var ind1 = obj.get(mv.from, true); - var tmp = obj.records[ind1]; - obj.records.splice(ind1, 1); - var ind2 = obj.get(mv.to, true); - if (ind1 > ind2) obj.records.splice(ind2, 0, tmp); else obj.records.splice(ind2+1, 0, tmp); - $('#grid_'+ obj.name + '_ghost').remove(); - obj.refresh(); - } - delete obj.last.move; - $(document).off('mousemove', mouseMove); - $(document).off('mouseup', mouseStop); - } - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'destroy' }); - if (eventData.isCancelled === true) return; - // remove events - $(window).off('resize', this.tmp_resize); - // clean up - if (typeof this.toolbar == 'object' && this.toolbar.destroy) this.toolbar.destroy(); - if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-grid') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - // =========================================== - // --- Internal Functions - - initColumnOnOff: function () { - if (!this.show.toolbarColumns) return; - var obj = this; - var col_html = '
        '+ - ''; - for (var c in this.columns) { - var col = this.columns[c]; - var tmp = this.columns[c].caption; - if (!tmp && this.columns[c].hint) tmp = this.columns[c].hint; - if (!tmp) tmp = '- column '+ (parseInt(c) + 1) +' -'; - col_html += ''+ - ''+ - ''+ - ''; - } - col_html += ''; - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (url) { - col_html += - ''; - } - col_html += ''+ - ''; - col_html += "
        '+ - ' '+ - ''+ - ' '+ - '
        '+ - '
        '+ w2utils.lang('Skip') + - ' '+ w2utils.lang('Records')+ - '
        '+ - '
        '+ - '
        '+ w2utils.lang('Toggle Line Numbers') +'
        '+ - '
        '+ - '
        '+ w2utils.lang('Reset Column Size') + '
        '+ - '
        "; - this.toolbar.get('w2ui-column-on-off').html = col_html; - }, - - /** - * - * @param box, grid object - * @returns {{remove: Function}} contains a closure around all events to ensure they are removed from the dom - */ - initColumnDrag: function( box ){ - //throw error if using column groups - if ( this.columnGroups && this.columnGroups.length ) throw 'Draggable columns are not currently supported with column groups.'; - - var obj = this, - _dragData = {}; - _dragData.lastInt = null; - _dragData.pressed = false; - _dragData.timeout = null;_dragData.columnHead = null; - - //attach orginal event listener - $( obj.box).on( 'mousedown', dragColStart ); - $( obj.box ).on( 'mouseup', catchMouseup ); - - function catchMouseup(){ - _dragData.pressed = false; - clearTimeout( _dragData.timeout ); - } - /** - * - * @param event, mousedown - * @returns {boolean} false, preventsDefault - */ - function dragColStart ( event ) { - if ( _dragData.timeout ) clearTimeout( _dragData.timeout ); - var self = this; - _dragData.pressed = true; - - _dragData.timeout = setTimeout(function(){ - if ( !_dragData.pressed ) return; - - var eventData, - columns, - selectedCol, - origColumn, - origColumnNumber, - invalidPreColumns = [ 'w2ui-col-number', 'w2ui-col-expand', 'w2ui-col-select' ], - invalidPostColumns = [ 'w2ui-head-last' ], - invalidColumns = invalidPreColumns.concat( invalidPostColumns ), - preColumnsSelector = '.w2ui-col-number, .w2ui-col-expand, .w2ui-col-select', - preColHeadersSelector = '.w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select'; - - // do nothing if it is not a header - if ( !$( event.originalEvent.target ).parents().hasClass( 'w2ui-head' ) ) return; - - // do nothing if it is an invalid column - for ( var i = 0, l = invalidColumns.length; i < l; i++ ){ - if ( $( event.originalEvent.target ).parents().hasClass( invalidColumns[ i ] ) ) return; - } - - _dragData.numberPreColumnsPresent = $( obj.box ).find( preColHeadersSelector ).length; - - //start event for drag start - _dragData.columnHead = origColumn = $( event.originalEvent.target ).parents( '.w2ui-head' ); - origColumnNumber = parseInt( origColumn.attr( 'col' ), 10); - eventData = obj.trigger({ type: 'columnDragStart', phase: 'before', originalEvent: event, origColumnNumber: origColumnNumber, target: origColumn[0] }); - if ( eventData.isCancelled === true ) return false; - - columns = _dragData.columns = $( obj.box ).find( '.w2ui-head:not(.w2ui-head-last)' ); - - //add events - $( document ).on( 'mouseup', dragColEnd ); - $( document ).on( 'mousemove', dragColOver ); - - _dragData.originalPos = parseInt( $( event.originalEvent.target ).parent( '.w2ui-head' ).attr( 'col' ), 10 ); - //_dragData.columns.css({ overflow: 'visible' }).children( 'div' ).css({ overflow: 'visible' }); - - //configure and style ghost image - _dragData.ghost = $( self ).clone( true ); - - //hide other elements on ghost except the grid body - $( _dragData.ghost ).find( '[col]:not([col="' + _dragData.originalPos + '"]), .w2ui-toolbar, .w2ui-grid-header' ).remove(); - $( _dragData.ghost ).find( preColumnsSelector ).remove(); - $( _dragData.ghost ).find( '.w2ui-grid-body' ).css({ top: 0 }); - - selectedCol = $( _dragData.ghost ).find( '[col="' + _dragData.originalPos + '"]' ); - $( document.body ).append( _dragData.ghost ); - - $( _dragData.ghost ).css({ - width: 0, - height: 0, - margin: 0, - position: 'fixed', - zIndex: 999999, - opacity: 0 - }).addClass( '.w2ui-grid-ghost' ).animate({ - width: selectedCol.width(), - height: $(obj.box).find('.w2ui-grid-body:first').height(), - left : event.pageX, - top : event.pageY, - opacity: .8 - }, 0 ); - - //establish current offsets - _dragData.offsets = []; - for ( var i = 0, l = columns.length; i < l; i++ ) { - _dragData.offsets.push( $( columns[ i ] ).offset().left ); - } - - //conclude event - obj.trigger( $.extend( eventData, { phase: 'after' } ) ); - }, 150 );//end timeout wrapper - } - - function dragColOver ( event ) { - if ( !_dragData.pressed ) return; - - var cursorX = event.originalEvent.pageX, - cursorY = event.originalEvent.pageY, - offsets = _dragData.offsets, - lastWidth = $( '.w2ui-head:not(.w2ui-head-last)' ).width(); - - _dragData.targetInt = targetIntersection( cursorX, offsets, lastWidth ); - markIntersection( _dragData.targetInt ); - trackGhost( cursorX, cursorY ); - } - - function dragColEnd ( event ) { - _dragData.pressed = false; - - var eventData, - target, - selected, - columnConfig, - columnNum, - targetColumn, - ghosts = $( '.w2ui-grid-ghost' ); - - //start event for drag start - eventData = obj.trigger({ type: 'columnDragEnd', phase: 'before', originalEvent: event, target: _dragData.columnHead[0] }); - if ( eventData.isCancelled === true ) return false; - - selected = obj.columns[ _dragData.originalPos ]; - columnConfig = obj.columns; - columnNum = ( _dragData.targetInt >= obj.columns.length ) ? obj.columns.length - 1 : - ( _dragData.targetInt < _dragData.originalPos ) ? _dragData.targetInt : _dragData.targetInt - 1; - target = ( _dragData.numberPreColumnsPresent ) ? - ( _dragData.targetInt - _dragData.numberPreColumnsPresent < 0 ) ? 0 : _dragData.targetInt - _dragData.numberPreColumnsPresent : - _dragData.targetInt; - targetColumn = $( '.w2ui-head[col="' + columnNum + '"]' ); - - if ( target !== _dragData.originalPos + 1 && target !== _dragData.originalPos && targetColumn && targetColumn.length ) { - $( _dragData.ghost ).animate({ - top: $( obj.box ).offset().top, - left: targetColumn.offset().left, - width: 0, - height: 0, - opacity:.2 - }, 300, function(){ - $( this ).remove(); - ghosts.remove(); - }); - - columnConfig.splice( target, 0, $.extend( {}, selected ) ); - columnConfig.splice( columnConfig.indexOf( selected ), 1); - } else { - $( _dragData.ghost ).remove(); - ghosts.remove(); - } - - //_dragData.columns.css({ overflow: '' }).children( 'div' ).css({ overflow: '' }); - - $( document ).off( 'mouseup', dragColEnd ); - $( document ).off( 'mousemove', dragColOver ); - if ( _dragData.marker ) _dragData.marker.remove(); - _dragData = {}; - - obj.refresh(); - - //conclude event - obj.trigger( $.extend( eventData, { phase: 'after', targetColumnNumber: target - 1 } ) ); - } - - function markIntersection( intersection ){ - if ( !_dragData.marker && !_dragData.markerLeft ) { - _dragData.marker = $('
        ' + - '
        ' + - '
        ' + - '
        '); - _dragData.markerLeft = $('
        ' + - '
        ' + - '
        ' + - '
        '); - } - - if ( !_dragData.lastInt || _dragData.lastInt !== intersection ){ - _dragData.lastInt = intersection; - _dragData.marker.remove(); - _dragData.markerLeft.remove(); - $('.w2ui-head').removeClass('w2ui-col-intersection'); - - //if the current intersection is greater than the number of columns add the marker to the end of the last column only - if ( intersection >= _dragData.columns.length ) { - $( _dragData.columns[ _dragData.columns.length - 1 ] ).children( 'div:last' ).append( _dragData.marker.addClass( 'right' ).removeClass( 'left' ) ); - $( _dragData.columns[ _dragData.columns.length - 1 ] ).addClass('w2ui-col-intersection'); - } else if ( intersection <= _dragData.numberPreColumnsPresent ) { - //if the current intersection is on the column numbers place marker on first available column only - $( '.w2ui-head[col="0"]' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ).css({ position: 'relative' }); - $( '.w2ui-head[col="0"]').prev().addClass('w2ui-col-intersection'); - } else { - //otherwise prepend the marker to the targeted column and append it to the previous column - $( _dragData.columns[intersection] ).children( 'div:last' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ); - $( _dragData.columns[intersection] ).prev().children( 'div:last' ).append( _dragData.markerLeft.addClass( 'right' ).removeClass( 'left' ) ).css({ position: 'relative' }); - $( _dragData.columns[intersection - 1] ).addClass('w2ui-col-intersection'); - } - } - } - - function targetIntersection( cursorX, offsets, lastWidth ){ - if ( cursorX <= offsets[0] ) { - return 0; - } else if ( cursorX >= offsets[offsets.length - 1] + lastWidth ) { - return offsets.length; - } else { - for ( var i = 0, l = offsets.length; i < l; i++ ) { - var thisOffset = offsets[ i ]; - var nextOffset = offsets[ i + 1 ] || offsets[ i ] + lastWidth; - var midpoint = ( nextOffset - offsets[ i ]) / 2 + offsets[ i ]; - - if ( cursorX > thisOffset && cursorX <= midpoint ) { - return i; - } else if ( cursorX > midpoint && cursorX <= nextOffset ) { - return i + 1; - } - } - return intersection; - } - } - - function trackGhost( cursorX, cursorY ){ - $( _dragData.ghost ).css({ - left: cursorX - 10, - top: cursorY - 10 - }); - } - - //return an object to remove drag if it has ever been enabled - return { - remove: function(){ - $( obj.box ).off( 'mousedown', dragColStart ); - $( obj.box ).off( 'mouseup', catchMouseup ); - $( obj.box ).find( '.w2ui-head' ).removeAttr( 'draggable' ); - obj.last.columnDrag = false; - } - } - }, - - columnOnOff: function (el, event, field, value) { - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'columnOnOff', checkbox: el, field: field, originalEvent: event }); - if (eventData.isCancelled === true) return; - // regular processing - var obj = this; - // collapse expanded rows - for (var r in this.records) { - if (this.records[r].expanded === true) this.records[r].expanded = false - } - // show/hide - var hide = true; - if (field == 'line-numbers') { - this.show.lineNumbers = !this.show.lineNumbers; - this.refresh(); - } else if (field == 'skip') { - if (!w2utils.isInt(value)) value = 0; - obj.skip(value); - } else if (field == 'resize') { - // restore sizes - for (var c in this.columns) { - if (typeof this.columns[c].sizeOriginal != 'undefined') { - this.columns[c].size = this.columns[c].sizeOriginal; - } - } - this.initResize(); - this.resize(); - } else { - var col = this.getColumn(field); - if (col.hidden) { - $(el).prop('checked', true); - this.showColumn(col.field); - } else { - $(el).prop('checked', false); - this.hideColumn(col.field); - } - hide = false; - } - this.initColumnOnOff(); - if (hide) { - setTimeout(function () { - $().w2overlay('', { name: 'searches-'+ this.name }); - obj.toolbar.uncheck('column-on-off'); - }, 100); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - initToolbar: function () { - // -- if toolbar is true - if (typeof this.toolbar['render'] == 'undefined') { - var tmp_items = this.toolbar.items; - this.toolbar.items = []; - this.toolbar = $().w2toolbar($.extend(true, {}, this.toolbar, { name: this.name +'_toolbar', owner: this })); - - // ============================================= - // ------ Toolbar Generic buttons - - if (this.show.toolbarReload) { - this.toolbar.items.push($.extend(true, {}, this.buttons['reload'])); - } - if (this.show.toolbarColumns) { - this.toolbar.items.push($.extend(true, {}, this.buttons['columns'])); - this.initColumnOnOff(); - } - if (this.show.toolbarReload || this.show.toolbarColumn) { - this.toolbar.items.push({ type: 'break', id: 'w2ui-break0' }); - } - if (this.show.toolbarSearch) { - var html = - ''; - this.toolbar.items.push({ type: 'html', id: 'w2ui-search', html: html }); - if (this.multiSearch && this.searches.length > 0) { - this.toolbar.items.push($.extend(true, {}, this.buttons['search-go'])); - } - } - if (this.show.toolbarSearch && (this.show.toolbarAdd || this.show.toolbarEdit || this.show.toolbarDelete || this.show.toolbarSave)) { - this.toolbar.items.push({ type: 'break', id: 'w2ui-break1' }); - } - if (this.show.toolbarAdd) { - this.toolbar.items.push($.extend(true, {}, this.buttons['add'])); - } - if (this.show.toolbarEdit) { - this.toolbar.items.push($.extend(true, {}, this.buttons['edit'])); - } - if (this.show.toolbarDelete) { - this.toolbar.items.push($.extend(true, {}, this.buttons['delete'])); - } - if (this.show.toolbarSave) { - if (this.show.toolbarAdd || this.show.toolbarDelete || this.show.toolbarEdit) { - this.toolbar.items.push({ type: 'break', id: 'w2ui-break2' }); - } - this.toolbar.items.push($.extend(true, {}, this.buttons['save'])); - } - // add original buttons - for (var i in tmp_items) this.toolbar.items.push(tmp_items[i]); - - // ============================================= - // ------ Toolbar onClick processing - - var obj = this; - this.toolbar.on('click', function (event) { - var eventData = obj.trigger({ phase: 'before', type: 'toolbar', target: event.target, originalEvent: event }); - if (eventData.isCancelled === true) return; - var id = event.target; - switch (id) { - case 'w2ui-reload': - var eventData2 = obj.trigger({ phase: 'before', type: 'reload', target: obj.name }); - if (eventData2.isCancelled === true) return false; - obj.reload(); - obj.trigger($.extend(eventData2, { phase: 'after' })); - break; - case 'w2ui-column-on-off': - for (var c in obj.columns) { - if (obj.columns[c].hidden) { - $("#grid_"+ obj.name +"_column_"+ c + "_check").prop("checked", false); - } else { - $("#grid_"+ obj.name +"_column_"+ c + "_check").prop('checked', true); - } - } - obj.initResize(); - obj.resize(); - break; - case 'w2ui-search-advanced': - var tb = this; - var it = this.get(id); - if (it.checked) { - obj.searchClose(); - setTimeout(function () { tb.uncheck(id); }, 1); - } else { - obj.searchOpen(); - event.originalEvent.stopPropagation(); - function tmp_close() { - if ($('#w2ui-overlay-searches-'+ obj.name).data('keepOpen') === true) return; - tb.uncheck(id); - $(document).off('click', 'body', tmp_close); - } - $(document).on('click', 'body', tmp_close); - } - break; - case 'w2ui-add': - // events - var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'add', recid: null }); - obj.trigger($.extend(eventData, { phase: 'after' })); - break; - case 'w2ui-edit': - var sel = obj.getSelection(); - var recid = null; - if (sel.length == 1) recid = sel[0]; - // events - var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'edit', recid: recid }); - obj.trigger($.extend(eventData, { phase: 'after' })); - break; - case 'w2ui-delete': - obj.delete(); - break; - case 'w2ui-save': - obj.save(); - break; - } - // no default action - obj.trigger($.extend(eventData, { phase: 'after' })); - }); - } - return; - }, - - initResize: function () { - var obj = this; - //if (obj.resizing === true) return; - $(this.box).find('.w2ui-resizer') - .off('click') - .on('click', function (event) { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - if (event.preventDefault) event.preventDefault(); - }) - .off('mousedown') - .on('mousedown', function (event) { - if (!event) event = window.event; - if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } - obj.resizing = true; - obj.last.tmp = { - x : event.screenX, - y : event.screenY, - gx : event.screenX, - gy : event.screenY, - col : parseInt($(this).attr('name')) - }; - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - if (event.preventDefault) event.preventDefault(); - // fix sizes - for (var c in obj.columns) { - if (typeof obj.columns[c].sizeOriginal == 'undefined') obj.columns[c].sizeOriginal = obj.columns[c].size; - obj.columns[c].size = obj.columns[c].sizeCalculated; - } - var eventData = { phase: 'before', type: 'columnResize', target: obj.name, column: obj.last.tmp.col, field: obj.columns[obj.last.tmp.col].field }; - eventData = obj.trigger($.extend(eventData, { resizeBy: 0, originalEvent: event })); - // set move event - var mouseMove = function (event) { - if (obj.resizing != true) return; - if (!event) event = window.event; - // event before - eventData = obj.trigger($.extend(eventData, { resizeBy: (event.screenX - obj.last.tmp.gx), originalEvent: event })); - if (eventData.isCancelled === true) { eventData.isCancelled = false; return; } - // default action - obj.last.tmp.x = (event.screenX - obj.last.tmp.x); - obj.last.tmp.y = (event.screenY - obj.last.tmp.y); - obj.columns[obj.last.tmp.col].size = (parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px'; - obj.resizeRecords(); - // reset - obj.last.tmp.x = event.screenX; - obj.last.tmp.y = event.screenY; - } - var mouseUp = function (event) { - delete obj.resizing; - $(document).off('mousemove', 'body'); - $(document).off('mouseup', 'body'); - obj.resizeRecords(); - // event before - obj.trigger($.extend(eventData, { phase: 'after', originalEvent: event })); - } - $(document).on('mousemove', 'body', mouseMove); - $(document).on('mouseup', 'body', mouseUp); - }) - .each(function (index, el) { - var td = $(el).parent(); - $(el).css({ - "height" : '25px', - "margin-left" : (td.width() - 3) + 'px' - }) - }); - }, - - resizeBoxes: function () { - // elements - var main = $(this.box).find('> div'); - var header = $('#grid_'+ this.name +'_header'); - var toolbar = $('#grid_'+ this.name +'_toolbar'); - var summary = $('#grid_'+ this.name +'_summary'); - var footer = $('#grid_'+ this.name +'_footer'); - var body = $('#grid_'+ this.name +'_body'); - var columns = $('#grid_'+ this.name +'_columns'); - var records = $('#grid_'+ this.name +'_records'); - - if (this.show.header) { - header.css({ - top: '0px', - left: '0px', - right: '0px' - }); - } - - if (this.show.toolbar) { - toolbar.css({ - top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) ) + 'px', - left: '0px', - right: '0px' - }); - } - if (this.show.footer) { - footer.css({ - bottom: '0px', - left: '0px', - right: '0px' - }); - } - if (this.summary.length > 0) { - summary.css({ - bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) ) + 'px', - left: '0px', - right: '0px' - }); - } - body.css({ - top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) ) + 'px', - bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + (this.summary.length > 0 ? w2utils.getSize(summary, 'height') : 0) ) + 'px', - left: '0px', - right: '0px' - }); - }, - - resizeRecords: function () { - var obj = this; - // remove empty records - $(this.box).find('.w2ui-empty-record').remove(); - // -- Calculate Column size in PX - var box = $(this.box); - var grid = $(this.box).find('> div'); - var header = $('#grid_'+ this.name +'_header'); - var toolbar = $('#grid_'+ this.name +'_toolbar'); - var summary = $('#grid_'+ this.name +'_summary'); - var footer = $('#grid_'+ this.name +'_footer'); - var body = $('#grid_'+ this.name +'_body'); - var columns = $('#grid_'+ this.name +'_columns'); - var records = $('#grid_'+ this.name +'_records'); - - // body might be expanded by data - if (!this.fixedBody) { - // allow it to render records, then resize - var calculatedHeight = w2utils.getSize(columns, 'height') - + w2utils.getSize($('#grid_'+ obj.name +'_records table'), 'height'); - obj.height = calculatedHeight - + w2utils.getSize(grid, '+height') - + (obj.show.header ? w2utils.getSize(header, 'height') : 0) - + (obj.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) - + (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) - + (obj.show.footer ? w2utils.getSize(footer, 'height') : 0); - grid.css('height', obj.height); - body.css('height', calculatedHeight); - box.css('height', w2utils.getSize(grid, 'height') + w2utils.getSize(box, '+height')); - } else { - // fixed body height - var calculatedHeight = grid.height() - - (this.show.header ? w2utils.getSize(header, 'height') : 0) - - (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) - - (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) - - (this.show.footer ? w2utils.getSize(footer, 'height') : 0); - body.css('height', calculatedHeight); - } - - // check overflow - var bodyOverflowX = false; - var bodyOverflowY = false; - if (body.width() < $(records).find('>table').width()) bodyOverflowX = true; - if (body.height() - columns.height() < $(records).find('>table').height() + (bodyOverflowX ? w2utils.scrollBarSize() : 0)) bodyOverflowY = true; - if (!this.fixedBody) { bodyOverflowY = false; bodyOverflowX = false; } - if (bodyOverflowX || bodyOverflowY) { - columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); - records.css({ - top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', - "-webkit-overflow-scrolling": "touch", - "overflow-x": (bodyOverflowX ? 'auto' : 'hidden'), - "overflow-y": (bodyOverflowY ? 'auto' : 'hidden') }); - } else { - columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').hide(); - records.css({ - top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', - overflow: 'hidden' - }); - if (records.length > 0) { this.last.scrollTop = 0; this.last.scrollLeft = 0; } // if no scrollbars, always show top - } - if (this.show.emptyRecords && !bodyOverflowY) { - var max = Math.floor(records.height() / this.recordHeight) + 1; - if (this.fixedBody) { - for (var di = this.buffered; di <= max; di++) { - var html = ''; - html += ''; - if (this.show.lineNumbers) html += ''; - if (this.show.selectColumn) html += ''; - if (this.show.expandColumn) html += ''; - var j = 0; - while (true && this.columns.length > 0) { - var col = this.columns[j]; - if (col.hidden) { j++; if (typeof this.columns[j] == 'undefined') break; else continue; } - html += ''; - j++; - if (typeof this.columns[j] == 'undefined') break; - } - html += ''; - html += ''; - $('#grid_'+ this.name +'_records > table').append(html); - } - } - } - if (body.length > 0) { - var width_max = parseInt(body.width()) - - (bodyOverflowY ? w2utils.scrollBarSize() : 0) - - (this.show.lineNumbers ? 34 : 0) - - (this.show.selectColumn ? 26 : 0) - - (this.show.expandColumn ? 26 : 0); - var width_box = width_max; - var percent = 0; - // gridMinWidth processiong - var restart = false; - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (typeof col.gridMinWidth != 'undefined') { - if (col.gridMinWidth > width_box && col.hidden !== true) { - col.hidden = true; - restart = true; - } - if (col.gridMinWidth < width_box && col.hidden === true) { - col.hidden = false; - restart = true; - } - } - } - if (restart === true) { - this.refresh(); - return; - } - // assign PX column s - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (String(col.size).substr(String(col.size).length-2).toLowerCase() == 'px') { - width_max -= parseFloat(col.size); - this.columns[i].sizeCalculated = col.size; - this.columns[i].sizeType = 'px'; - } else { - percent += parseFloat(col.size); - this.columns[i].sizeType = '%'; - delete col.sizeCorrected; - } - } - // if sum != 100% -- reassign proportionally - if (percent != 100 && percent > 0) { - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (col.sizeType == '%') { - col.sizeCorrected = Math.round(parseFloat(col.size) * 100 * 100 / percent) / 100 + '%'; - } - } - } - // calculate % columns - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (col.sizeType == '%') { - if (typeof this.columns[i].sizeCorrected != 'undefined') { - // make it 1px smaller, so margin of error can be calculated correctly - this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.sizeCorrected) / 100) - 1 + 'px'; - } else { - // make it 1px smaller, so margin of error can be calculated correctly - this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.size) / 100) - 1 + 'px'; - } - } - } - } - // fix margin of error that is due percentage calculations - var width_cols = 0; - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (typeof col.min == 'undefined') col.min = 20; - if (parseInt(col.sizeCalculated) < parseInt(col.min)) col.sizeCalculated = col.min + 'px'; - if (parseInt(col.sizeCalculated) > parseInt(col.max)) col.sizeCalculated = col.max + 'px'; - width_cols += parseInt(col.sizeCalculated); - } - var width_diff = parseInt(width_box) - parseInt(width_cols); - if (width_diff > 0 && percent > 0) { - var i = 0; - while (true) { - var col = this.columns[i]; - if (typeof col == 'undefined') { i = 0; continue; } - if (col.hidden || col.sizeType == 'px') { i++; continue; } - col.sizeCalculated = (parseInt(col.sizeCalculated) + 1) + 'px'; - width_diff--; - if (width_diff == 0) break; - i++; - } - } else if (width_diff > 0) { - columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); - } - // resize columns - columns.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { - var ind = $(el).attr('col'); - if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); - // last column - if ($(el).hasClass('w2ui-head-last')) { - $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); - } - }); - // if there are column groups - hide first row (needed for sizing) - if (columns.find('> table > tbody > tr').length == 3) { - columns.find('> table > tbody > tr:nth-child(1) td').html('').css({ - 'height' : '0px', - 'border' : '0px', - 'padding' : '0px', - 'margin' : '0px' - }); - } - // resize records - records.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { - var ind = $(el).attr('col'); - if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); - // last column - if ($(el).hasClass('w2ui-grid-data-last')) { - $(el).css('width', (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); - } - }); - // resize summary - summary.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { - var ind = $(el).attr('col'); - if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); - // last column - if ($(el).hasClass('w2ui-grid-data-last')) { - $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); - } - }); - this.initResize(); - this.refreshRanges(); - // apply last scroll if any - if (this.last.scrollTop != '' && records.length > 0) { - columns.prop('scrollLeft', this.last.scrollLeft); - records.prop('scrollTop', this.last.scrollTop); - records.prop('scrollLeft', this.last.scrollLeft); - } - }, - - getSearchesHTML: function () { - var html = ''; - var showBtn = false; - for (var i = 0; i < this.searches.length; i++) { - var s = this.searches[i]; - s.type = String(s.type).toLowerCase(); - if (s.hidden) continue; - var btn = ''; - if (showBtn == false) { - btn = ''+ - ' ' + - ' ' + - ' '+ - ' ' + - ''; - } - html += ''+ - ' '+ - '
        '+ btn +''+ s.caption +''+ operator + - '
        '+ - '
        '; - - switch (s.type) { - case 'text': - case 'alphanumeric': - case 'hex': - case 'list': - case 'combo': - case 'enum': - html += ''; - break; - - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'date': - case 'time': - html += ''+ - ''; - break; - - case 'select': - html += ''; - break; - - } - html += s.outTag + - '
        '+ - '
        '+ - ' '+ - ' '+ - '
        '+ - '
        '; - return html; - }, - - initOperator: function (el, search_ind) { - var obj = this; - var search = obj.searches[search_ind]; - var range = $('#grid_'+ obj.name + '_range_'+ search_ind); - var fld1 = $('#grid_'+ obj.name +'_field_'+ search_ind); - var fld2 = fld1.parent().find('span input'); - if ($(el).val() == 'in') { fld1.w2field('clear'); } else { fld1.w2field(search.type); } - if ($(el).val() == 'between') { range.show(); fld2.w2field(search.type); } else { range.hide(); } - }, - - initSearches: function () { - var obj = this; - // init searches - for (var s in this.searches) { - var search = this.searches[s]; - var sdata = this.getSearchData(search.field); - search.type = String(search.type).toLowerCase(); - if (typeof search.options != 'object') search.options = {}; - // init types - switch (search.type) { - case 'text': - case 'alphanumeric': - $('#grid_'+ this.name +'_operator_'+s).val('begins'); - if (['alphanumeric', 'hex'].indexOf(search.type) != -1) { - $('#grid_'+ this.name +'_field_' + s).w2field(search.type, search.options); - } - break; - - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'date': - case 'time': - if (sdata && sdata.type == 'int' && sdata.operator == 'in') break; - $('#grid_'+ this.name +'_field_'+s).w2field(search.type, search.options); - $('#grid_'+ this.name +'_field2_'+s).w2field(search.type, search.options); - setTimeout(function () { // convert to date if it is number - $('#grid_'+ obj.name +'_field_'+s).keydown(); - $('#grid_'+ obj.name +'_field2_'+s).keydown(); - }, 1); - break; - - case 'hex': - break; - - case 'list': - case 'combo': - case 'enum': - var options = search.options; - if (search.type == 'list') options.selected = {}; - if (search.type == 'enum') options.selected = []; - if (sdata) options.selected = sdata.value; - $('#grid_'+ this.name +'_field_'+s).w2field(search.type, options); - if (search.type == 'combo') { - $('#grid_'+ this.name +'_operator_'+s).val('begins'); - } - break; - - case 'select': - // build options - var options = ''; - for (var i in search.options.items) { - var si = search.options.items[i]; - if ($.isPlainObject(search.options.items[i])) { - var val = si.id; - var txt = si.text; - if (typeof val == 'undefined' && typeof si.value != 'undefined') val = si.value; - if (typeof txt == 'undefined' && typeof si.caption != 'undefined') txt = si.caption; - if (val == null) val = ''; - options += ''; - } else { - options += ''; - } - } - $('#grid_'+ this.name +'_field_'+s).html(options); - break; - } - if (sdata != null) { - if (sdata.type == 'int' && sdata.operator == 'in') { - $('#grid_'+ this.name +'_field_'+ s).w2field('clear').val(sdata.value); - } - $('#grid_'+ this.name +'_operator_'+ s).val(sdata.operator).trigger('change'); - if (!$.isArray(sdata.value)) { - if (typeof sdata.value != 'udefined') $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); - } else { - if (sdata.operator == 'in') { - $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); - } else { - $('#grid_'+ this.name +'_field_'+ s).val(sdata.value[0]).trigger('change'); - $('#grid_'+ this.name +'_field2_'+ s).val(sdata.value[1]).trigger('change'); - } - } - } - } - // add on change event - $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches *[rel=search]').on('keypress', function (evnt) { - if (evnt.keyCode == 13 && (evnt.ctrlKey || evnt.metaKey)) { - obj.search(); - $().w2overlay(); - } - }); - }, - - getColumnsHTML: function () { - var obj = this; - var html = ''; - if (this.show.columnHeaders) { - if (this.columnGroups.length > 0) { - html = getColumns(true) + getGroups() + getColumns(false); - } else { - html = getColumns(true); - } - } - return html; - - function getGroups () { - var html = ''; - // add empty group at the end - if (obj.columnGroups[obj.columnGroups.length-1].caption != '') obj.columnGroups.push({ caption: '' }); - - if (obj.show.lineNumbers) { - html += ''+ - '
         
        '+ - ''; - } - if (obj.show.selectColumn) { - html += ''+ - '
         
        '+ - ''; - } - if (obj.show.expandColumn) { - html += ''+ - '
         
        '+ - ''; - } - var ii = 0; - for (var i=0; i
        '; - } - html += ''+ - resizer + - '
        '+ - '
        '+ - (!col.caption ? ' ' : col.caption) + - '
        '+ - ''; - } else { - html += ''+ - '
        '+ - (!colg.caption ? ' ' : colg.caption) + - '
        '+ - ''; - } - ii += colg.span; - } - html += ''; - return html; - } - - function getColumns (master) { - var html = '', - reorderCols = (obj.reorderColumns && (!obj.columnGroups || !obj.columnGroups.length)) ? ' w2ui-reorder-cols-head ' : ''; - if (obj.show.lineNumbers) { - html += ''+ - '
        #
        '+ - ''; - } - if (obj.show.selectColumn) { - html += ''+ - '
        '+ - ' '+ - '
        '+ - ''; - } - if (obj.show.expandColumn) { - html += ''+ - '
         
        '+ - ''; - } - var ii = 0; - var id = 0; - for (var i=0; i
      '; - } - html += ''+ - resizer + - '
      '+ - '
      '+ - (!col.caption ? ' ' : col.caption) + - '
      '+ - ''; - } - } - html += '
       
      '; - html += ''; - return html; - } - }, - - getRecordsHTML: function () { - // larget number works better with chrome, smaller with FF. - if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; - var records = $('#grid_'+ this.name +'_records'); - var limit = Math.floor(records.height() / this.recordHeight) + this.show_extra + 1; - if (!this.fixedBody) limit = this.buffered; - // always need first record for resizing purposes - var html = '' + this.getRecordHTML(-1, 0); - // first empty row with height - html += ''+ - ' '+ - ''; - for (var i = 0; i < limit; i++) { - html += this.getRecordHTML(i, i+1); - } - html += ''+ - ' '+ - ''+ - ''+ - ' '+ - ''+ - '
      '; - this.last.range_start = 0; - this.last.range_end = limit; - return html; - }, - - getSummaryHTML: function () { - if (this.summary.length == 0) return; - var html = ''; - for (var i = 0; i < this.summary.length; i++) { - html += this.getRecordHTML(i, i+1, true); - } - html += '
      '; - return html; - }, - - scroll: function (event) { - var time = (new Date()).getTime(); - var obj = this; - var records = $('#grid_'+ this.name +'_records'); - if (this.records.length == 0 || records.length == 0 || records.height() == 0) return; - if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; - // need this to enable scrolling when this.limit < then a screen can fit - if (records.height() < this.buffered * this.recordHeight && records.css('overflow-y') == 'hidden') { - if (this.total > 0) this.refresh(); - return; - } - // update footer - var t1 = Math.round(records[0].scrollTop / this.recordHeight + 1); - var t2 = t1 + (Math.round(records.height() / this.recordHeight) - 1); - if (t1 > this.buffered) t1 = this.buffered; - if (t2 > this.buffered) t2 = this.buffered; - var url = (typeof this.url != 'object' ? this.url : this.url.get); - $('#grid_'+ this.name + '_footer .w2ui-footer-right').html(w2utils.formatNumber(this.offset + t1) + '-' + w2utils.formatNumber(this.offset + t2) + ' ' + w2utils.lang('of') + ' ' + w2utils.formatNumber(this.total) + - (url ? ' ('+ w2utils.lang('buffered') + ' '+ w2utils.formatNumber(this.buffered) + (this.offset > 0 ? ', skip ' + w2utils.formatNumber(this.offset) : '') + ')' : '') - ); - // only for local data source, else no extra records loaded - if (!url && (!this.fixedBody || this.total <= 300)) return; - // regular processing - var start = Math.floor(records[0].scrollTop / this.recordHeight) - this.show_extra; - var end = start + Math.floor(records.height() / this.recordHeight) + this.show_extra * 2 + 1; - // var div = start - this.last.range_start; - if (start < 1) start = 1; - if (end > this.total) end = this.total; - var tr1 = records.find('#grid_'+ this.name +'_rec_top'); - var tr2 = records.find('#grid_'+ this.name +'_rec_bottom'); - // if row is expanded - if (String(tr1.next().prop('id')).indexOf('_expanded_row') != -1) tr1.next().remove(); - if (this.total > end && String(tr2.prev().prop('id')).indexOf('_expanded_row') != -1) tr2.prev().remove(); - var first = parseInt(tr1.next().attr('line')); - var last = parseInt(tr2.prev().attr('line')); - //$('#log').html('buffer: '+ this.buffered +' start-end: ' + start + '-'+ end + ' ===> first-last: ' + first + '-' + last); - if (first < start || first == 1 || this.last.pull_refresh) { // scroll down - // console.log('end', end, 'last', last, 'show_extre', this.show_extra, this.last.pull_refresh); - if (end <= last + this.show_extra - 2 && end != this.total) return; - this.last.pull_refresh = false; - // remove from top - while (true) { - var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); - if (tmp.attr('line') == 'bottom') break; - if (parseInt(tmp.attr('line')) < start) tmp.remove(); else break; - } - // add at bottom - var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); - var rec_start = tmp.attr('line'); - if (rec_start == 'top') rec_start = start; - for (var i = parseInt(rec_start) + 1; i <= end; i++) { - if (!this.records[i-1]) continue; - if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; - tr2.before(this.getRecordHTML(i-1, i)); - } - markSearch(); - setTimeout(function() { obj.refreshRanges(); }, 0); - } else { // scroll up - if (start >= first - this.show_extra + 2 && start > 1) return; - // remove from bottom - while (true) { - var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); - if (tmp.attr('line') == 'top') break; - if (parseInt(tmp.attr('line')) > end) tmp.remove(); else break; - } - // add at top - var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); - var rec_start = tmp.attr('line'); - if (rec_start == 'bottom') rec_start = end; - for (var i = parseInt(rec_start) - 1; i >= start; i--) { - if (!this.records[i-1]) continue; - if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; - tr1.after(this.getRecordHTML(i-1, i)); - } - markSearch(); - setTimeout(function() { obj.refreshRanges(); }, 0); - } - // first/last row size - var h1 = (start - 1) * obj.recordHeight; - var h2 = (this.buffered - end) * obj.recordHeight; - if (h2 < 0) h2 = 0; - tr1.css('height', h1 + 'px'); - tr2.css('height', h2 + 'px'); - obj.last.range_start = start; - obj.last.range_end = end; - // load more if needed - var s = Math.floor(records[0].scrollTop / this.recordHeight); - var e = s + Math.floor(records.height() / this.recordHeight); - if (e + 10 > this.buffered && this.last.pull_more !== true && this.buffered < this.total - this.offset) { - if (this.autoLoad === true) { - this.last.pull_more = true; - this.last.xhr_offset += this.limit; - this.request('get-records'); - } else { - var more = $('#grid_'+ this.name +'_rec_more'); - if (more.css('display') == 'none') { - more.show() - .on('click', function () { - obj.last.pull_more = true; - obj.last.xhr_offset += obj.limit; - obj.request('get-records'); - // show spinner the last - $(this).find('td').html('
      '); - }); - } - if (more.find('td').text().indexOf('Load') == -1) { - more.find('td').html('
      '+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
      '); - } - } - } - // check for grid end - if (this.buffered >= this.total - this.offset) $('#grid_'+ this.name +'_rec_more').hide(); - return; - - function markSearch() { - // mark search - if(obj.markSearch === false) return; - clearTimeout(obj.last.marker_timer); - obj.last.marker_timer = setTimeout(function () { - // mark all search strings - var str = []; - for (var s in obj.searchData) { - var tmp = obj.searchData[s]; - if ($.inArray(tmp.value, str) == -1) str.push(tmp.value); - } - if (str.length > 0) $(obj.box).find('.w2ui-grid-data > div').w2marker(str); - }, 50); - } - }, - - getRecordHTML: function (ind, lineNum, summary) { - var rec_html = ''; - var sel = this.last.selection; - var record; - // first record needs for resize purposes - if (ind == -1) { - rec_html += ''; - if (this.show.lineNumbers) rec_html += ''; - if (this.show.selectColumn) rec_html += ''; - if (this.show.expandColumn) rec_html += ''; - for (var i in this.columns) { - if (this.columns[i].hidden) continue; - rec_html += ''; - } - rec_html += ''; - rec_html += ''; - return rec_html; - } - // regular record - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (summary !== true) { - if (this.searchData.length > 0 && !url) { - if (ind >= this.last.searchIds.length) return ''; - ind = this.last.searchIds[ind]; - record = this.records[ind]; - } else { - if (ind >= this.records.length) return ''; - record = this.records[ind]; - } - } else { - if (ind >= this.summary.length) return ''; - record = this.summary[ind]; - } - if (!record) return ''; - var id = w2utils.escapeId(record.recid); - var isRowSelected = false; - if (sel.indexes.indexOf(ind) != -1) isRowSelected = true; - // render TR - rec_html += ''; - if (this.show.lineNumbers) { - rec_html += ''+ - (summary !== true ? '
      '+ lineNum +'
      ' : '') + - ''; - } - if (this.show.selectColumn) { - rec_html += - ''+ - (summary !== true ? - '
      '+ - ' '+ - '
      ' - : - '' ) + - ''; - } - if (this.show.expandColumn) { - var tmp_img = ''; - if (record.expanded === true) tmp_img = '-'; else tmp_img = '+'; - if (record.expanded == 'none') tmp_img = ''; - if (record.expanded == 'spinner') tmp_img = '
      '; - rec_html += - ''+ - (summary !== true ? - '
      '+ - ' '+ tmp_img +'
      ' - : - '' ) + - ''; - } - var col_ind = 0; - while (true) { - var col = this.columns[col_ind]; - if (col.hidden) { col_ind++; if (typeof this.columns[col_ind] == 'undefined') break; else continue; } - var isChanged = !summary && record.changes && typeof record.changes[col.field] != 'undefined'; - var rec_cell = this.getCellHTML(ind, col_ind, summary); - var addStyle = ''; - if (typeof col.render == 'string') { - var tmp = col.render.toLowerCase().split(':'); - if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) addStyle += 'text-align: right;'; - } - if (typeof record.style == 'object' && typeof record.style[col_ind] == 'string') { - addStyle += record.style[col_ind] + ';'; - } - var isCellSelected = false; - if (isRowSelected && $.inArray(col_ind, sel.columns[ind]) != -1) isCellSelected = true; - rec_html += ''+ - rec_cell + - ''; - col_ind++; - if (typeof this.columns[col_ind] == 'undefined') break; - } - rec_html += ''; - rec_html += ''; - return rec_html; - }, - - getCellHTML: function (ind, col_ind, summary) { - var col = this.columns[col_ind]; - var record = (summary !== true ? this.records[ind] : this.summary[ind]); - var data = this.getCellValue(ind, col_ind, summary); - var edit = col.editable; - // various renderers - if (typeof col.render != 'undefined') { - if (typeof col.render == 'function') { - data = $.trim(col.render.call(this, record, ind, col_ind)); - if (data.length < 4 || data.substr(0, 4).toLowerCase() != ''; - } - if (typeof col.render == 'object') data = '
      ' + col.render[data] + '
      '; - if (typeof col.render == 'string') { - var tmp = col.render.toLowerCase().split(':'); - var prefix = ''; - var suffix = ''; - if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) { - if (typeof tmp[1] == 'undefined' || !w2utils.isInt(tmp[1])) tmp[1] = 0; - if (tmp[1] > 20) tmp[1] = 20; - if (tmp[1] < 0) tmp[1] = 0; - if (['money', 'currency'].indexOf(tmp[0]) != -1) { tmp[1] = w2utils.settings.currencyPrecision; prefix = w2utils.settings.currencyPrefix; suffix = w2utils.settings.currencySuffix } - if (tmp[0] == 'percent') { suffix = '%'; if (tmp[1] !== '0') tmp[1] = 1; } - if (tmp[0] == 'int') { tmp[1] = 0; } - // format - data = '
      ' + (data !== '' ? prefix + w2utils.formatNumber(Number(data).toFixed(tmp[1])) + suffix : '') + '
      '; - } - if (tmp[0] == 'time') { - if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.time_format; - data = '
      ' + prefix + w2utils.formatTime(data, tmp[1] == 'h12' ? 'hh:mi pm': 'h24:min') + suffix + '
      '; - } - if (tmp[0] == 'date') { - if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.date_display; - data = '
      ' + prefix + w2utils.formatDate(data, tmp[1]) + suffix + '
      '; - } - if (tmp[0] == 'age') { - data = '
      ' + prefix + w2utils.age(data) + suffix + '
      '; - } - } - } else { - // if editable checkbox - var addStyle = ''; - if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { - var changeInd = summary ? -(ind + 1) : ind; - addStyle = 'text-align: center'; - data = ''; - } - if (!this.show.recordTitles) { - var data = '
      '+ data +'
      '; - } else { - // title overwrite - var title = String(data).replace(/"/g, "''"); - if (typeof col.title != 'undefined') { - if (typeof col.title == 'function') title = col.title.call(this, record, ind, col_ind); - if (typeof col.title == 'string') title = col.title; - } - var data = '
      '+ data +'
      '; - } - } - if (data == null || typeof data == 'undefined') data = ''; - return data; - }, - - getCellValue: function (ind, col_ind, summary) { - var col = this.columns[col_ind]; - var record = (summary !== true ? this.records[ind] : this.summary[ind]); - var data = this.parseField(record, col.field); - if (record.changes && typeof record.changes[col.field] != 'undefined') data = record.changes[col.field]; - if (data == null || typeof data == 'undefined') data = ''; - return data; - }, - - getFooterHTML: function () { - return '
      '+ - ' '+ - ' '+ - ' '+ - '
      '; - }, - - status: function (msg) { - if (typeof msg != 'undefined') { - $('#grid_'+ this.name +'_footer').find('.w2ui-footer-left').html(msg); - } else { - // show number of selected - var msgLeft = ''; - var sel = this.getSelection(); - if (sel.length > 0) { - msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") + ' ' + w2utils.lang('selected'); - var tmp = sel[0]; - if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column; - if (sel.length == 1) msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' '; - } - $('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft); - // toolbar - if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); - if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); - } - }, - - lock: function (msg, showSpinner) { - var box = $(this.box).find('> div:first-child'); - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(box); - setTimeout(function () { w2utils.lock.apply(window, args); }, 10); - }, - - unlock: function () { - var box = this.box; - setTimeout(function () { w2utils.unlock(box); }, 25); // needed timer so if server fast, it will not flash - }, - - parseField: function (obj, field) { - var val = ''; - try { // need this to make sure no error in fields - val = obj; - var tmp = String(field).split('.'); - for (var i in tmp) { - val = val[tmp[i]]; - } - } catch (event) { - val = ''; - } - return val; - }, - - prepareData: function () { - // loops thru records and prepares date and time objects - for (var r in this.records) { - var rec = this.records[r]; - for (var c in this.columns) { - var column = this.columns[c]; - if (rec[column.field] == null || typeof column.render != 'string') continue; - // number - if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { - if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]); - } - // date - if (['date', 'age'].indexOf(column.render) != -1) { - if (!rec[column.field + '_']) { - var dt = rec[column.field]; - if (w2utils.isInt(dt)) dt = parseInt(dt); - rec[column.field + '_'] = new Date(dt); - } - } - // time - if (['time'].indexOf(column.render) != -1) { - if (w2utils.isTime(rec[column.field])) { // if string - var tmp = w2utils.isTime(rec[column.field], true); - var dt = new Date(); - dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0); // sets hours, min, sec, mills - if (!rec[column.field + '_']) rec[column.field + '_'] = dt; - } else { // if date object - var tmp = rec[column.field]; - if (w2utils.isInt(tmp)) tmp = parseInt(tmp); - var tmp = (tmp != null ? new Date(tmp) : new Date()); - var dt = new Date(); - dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0); // sets hours, min, sec, mills - if (!rec[column.field + '_']) rec[column.field + '_'] = dt; - } - } - } - } - }, - - nextCell: function (col_ind, editable) { - var check = col_ind + 1; - if (this.columns.length == check) return false; - if (editable === true) { - var edit = this.columns[check].editable; - if (this.columns[check].hidden || typeof edit == 'undefined' - || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.nextCell(check, editable); - } - return check; - }, - - prevCell: function (col_ind, editable) { - var check = col_ind - 1; - if (check < 0) return false; - if (editable === true) { - var edit = this.columns[check].editable; - if (this.columns[check].hidden || typeof edit == 'undefined' - || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.prevCell(check, editable); - } - return check; - }, - - nextRow: function (ind) { - if ((ind + 1 < this.records.length && this.last.searchIds.length == 0) // if there are more records - || (this.last.searchIds.length > 0 && ind < this.last.searchIds[this.last.searchIds.length-1])) { - ind++; - if (this.last.searchIds.length > 0) { - while (true) { - if ($.inArray(ind, this.last.searchIds) != -1 || ind > this.records.length) break; - ind++; - } - } - return ind; - } else { - return null; - } - }, - - prevRow: function (ind) { - if ((ind > 0 && this.last.searchIds.length == 0) // if there are more records - || (this.last.searchIds.length > 0 && ind > this.last.searchIds[0])) { - ind--; - if (this.last.searchIds.length > 0) { - while (true) { - if ($.inArray(ind, this.last.searchIds) != -1 || ind < 0) break; - ind--; - } - } - return ind; - } else { - return null; - } - } - }; - - $.extend(w2grid.prototype, w2utils.event); - w2obj.grid = w2grid; + var w2grid = function(options) { + + // public properties + this.name = null; + this.box = null; // HTML element that hold this element + this.header = ''; + this.url = ''; + this.columns = []; // { field, caption, size, attr, render, hidden, gridMinWidth, [editable: {type, inTag, outTag, style, items}] } + this.columnGroups = []; // { span: int, caption: 'string', master: true/false } + this.records = []; // { recid: int(requied), field1: 'value1', ... fieldN: 'valueN', style: 'string', editable: true/false, summary: true/false, changes: object } + this.summary = []; // arry of summary records, same structure as records array + this.searches = []; // { type, caption, field, inTag, outTag, default, items, hidden } + this.searchData = []; + this.sortData = []; + this.postData = {}; + this.toolbar = {}; // if not empty object; then it is toolbar object + + this.show = { + header : false, + toolbar : false, + footer : false, + columnHeaders : true, + lineNumbers : false, + expandColumn : false, + selectColumn : false, + emptyRecords : true, + toolbarReload : true, + toolbarColumns : true, + toolbarSearch : true, + toolbarAdd : false, + toolbarEdit : false, + toolbarDelete : false, + toolbarSave : false, + selectionBorder : true, + recordTitles : true + }; + + this.autoLoad = true; // for infinite scroll + this.fixedBody = true; // if false; then grid grows with data + this.recordHeight = 24; + this.keyboard = true; + this.selectType = 'row'; // can be row|cell + this.multiSearch = true; + this.multiSelect = true; + this.multiSort = true; + this.reorderColumns = false; + this.reorderRows = false; + this.markSearch = true; + + this.total = 0; // server total + this.buffered = 0; // number of records in the records array + this.limit = 100; + this.offset = 0; // how many records to skip (for infinite scroll) when pulling from server + this.style = ''; + this.ranges = []; + this.menu = []; + this.method; // if defined, then overwrited ajax method + this.recid; + this.parser; + + // events + this.onAdd = null; + this.onEdit = null; + this.onRequest = null; // called on any server event + this.onLoad = null; + this.onDelete = null; + this.onDeleted = null; + this.onSubmit = null; + this.onSave = null; + this.onSelect = null; + this.onUnselect = null; + this.onClick = null; + this.onDblClick = null; + this.onContextMenu = null; + this.onMenuClick = null; // when context menu item selected + this.onColumnClick = null; + this.onColumnResize = null; + this.onSort = null; + this.onSearch = null; + this.onChange = null; // called when editable record is changed + this.onRestore = null; // called when editable record is restored + this.onExpand = null; + this.onCollapse = null; + this.onError = null; + this.onKeydown = null; + this.onToolbar = null; // all events from toolbar + this.onColumnOnOff = null; + this.onCopy = null; + this.onPaste = null; + this.onSelectionExtend = null; + this.onEditField = null; + this.onRender = null; + this.onRefresh = null; + this.onReload = null; + this.onResize = null; + this.onDestroy = null; + + // internal + this.last = { + field : 'all', + caption : w2utils.lang('All Fields'), + logic : 'OR', + search : '', + searchIds : [], + selection : { + indexes : [], + columns : {}, + }, + multi : false, + scrollTop : 0, + scrollLeft : 0, + sortData : null, + sortCount : 0, + xhr : null, + range_start : null, + range_end : null, + sel_ind : null, + sel_col : null, + sel_type : null, + edit_col : null + }; + + this.isIOS = (navigator.userAgent.toLowerCase().indexOf('iphone') != -1 || + navigator.userAgent.toLowerCase().indexOf('ipod') != -1 || + navigator.userAgent.toLowerCase().indexOf('ipad') != -1) ? true : false; + + $.extend(true, this, w2obj.grid, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2grid = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2grid')) return; + // remember items + var columns = method.columns; + var columnGroups = method.columnGroups; + var records = method.records; + var searches = method.searches; + var searchData = method.searchData; + var sortData = method.sortData; + var postData = method.postData; + var toolbar = method.toolbar; + // extend items + var object = new w2grid(method); + $.extend(object, { postData: {}, records: [], columns: [], searches: [], toolbar: {}, sortData: [], searchData: [], handlers: [] }); + if (object.onExpand != null) object.show.expandColumn = true; + $.extend(true, object.toolbar, toolbar); + // reassign variables + for (var p in columns) object.columns[p] = $.extend(true, {}, columns[p]); + for (var p in columnGroups) object.columnGroups[p] = $.extend(true, {}, columnGroups[p]); + for (var p in searches) object.searches[p] = $.extend(true, {}, searches[p]); + for (var p in searchData) object.searchData[p] = $.extend(true, {}, searchData[p]); + for (var p in sortData) object.sortData[p] = $.extend(true, {}, sortData[p]); + object.postData = $.extend(true, {}, postData); + + // check if there are records without recid + for (var r in records) { + if (records[r].recid == null || typeof records[r].recid == 'undefined') { + console.log('ERROR: Cannot add records without recid. (obj: '+ object.name +')'); + return; + } + object.records[r] = $.extend(true, {}, records[r]); + } + if (object.records.length > 0) object.buffered = object.records.length; + // add searches + for (var c in object.columns) { + var col = object.columns[c]; + if (typeof col.searchable == 'undefined' || object.getSearch(col.field) != null) continue; + var stype = col.searchable; + var attr = ''; + if (col.searchable === true) { stype = 'text'; attr = 'size="20"'; } + object.addSearch({ field: col.field, caption: col.caption, type: stype, attr: attr }); + } + // init toolbar + object.initToolbar(); + // render if necessary + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + return object; + + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2grid'); + } + } + + // ==================================================== + // -- Implementation of core functionality + + w2grid.prototype = { + // ---- + // properties that need to be in prototype + + msgDelete : 'Are you sure you want to delete selected records?', + msgNotJSON : 'Returned data is not in valid JSON format.', + msgAJAXerror : 'AJAX error. See console for more details.', + msgRefresh : 'Refreshing...', + + // for easy button overwrite + buttons: { + 'reload' : { type: 'button', id: 'w2ui-reload', img: 'icon-reload', hint: 'Reload data in the list' }, + 'columns' : { type: 'drop', id: 'w2ui-column-on-off', img: 'icon-columns', hint: 'Show/hide columns', arrow: false, html: '' }, + 'search' : { type: 'html', id: 'w2ui-search', + html: '
      ' + }, + 'search-go': { type: 'check', id: 'w2ui-search-advanced', caption: 'Search...', hint: 'Open Search Fields' }, + 'add' : { type: 'button', id: 'w2ui-add', caption: 'Add New', hint: 'Add new record', img: 'icon-add' }, + 'edit' : { type: 'button', id: 'w2ui-edit', caption: 'Edit', hint: 'Edit selected record', img: 'icon-edit', disabled: true }, + 'delete' : { type: 'button', id: 'w2ui-delete', caption: 'Delete', hint: 'Delete selected records', img: 'icon-delete', disabled: true }, + 'save' : { type: 'button', id: 'w2ui-save', caption: 'Save', hint: 'Save changed records', img: 'icon-save' } + }, + + add: function (record) { + if (!$.isArray(record)) record = [record]; + var added = 0; + for (var o in record) { + if (!this.recid && typeof record[o].recid == 'undefined') record[o].recid = record[o][this.recid]; + if (record[o].recid == null || typeof record[o].recid == 'undefined') { + console.log('ERROR: Cannot add record without recid. (obj: '+ this.name +')'); + continue; + } + this.records.push(record[o]); + added++; + } + this.buffered = this.records.length; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.total = this.records.length; + this.localSort(); + this.localSearch(); + } + this.refresh(); // ?? should it be reload? + return added; + }, + + find: function (obj, returnIndex) { + if (typeof obj == 'undefined' || obj == null) obj = {}; + var recs = []; + var hasDots = false; + // check if property is nested - needed for speed + for (var o in obj) if (String(o).indexOf('.') != -1) hasDots = true; + // look for an item + for (var i = 0; i < this.records.length; i++) { + var match = true; + for (var o in obj) { + var val = this.records[i][o]; + if (hasDots && String(o).indexOf('.') != -1) val = this.parseField(this.records[i], o); + if (obj[o] != val) match = false; + } + if (match && returnIndex !== true) recs.push(this.records[i].recid); + if (match && returnIndex === true) recs.push(i); + } + return recs; + }, + + set: function (recid, record, noRefresh) { // does not delete existing, but overrides on top of it + if (typeof recid == 'object') { + noRefresh = record; + record = recid; + recid = null; + } + // update all records + if (recid == null) { + for (var r in this.records) { + $.extend(true, this.records[r], record); // recid is the whole record + } + if (noRefresh !== true) this.refresh(); + } else { // find record to update + var ind = this.get(recid, true); + if (ind == null) return false; + $.extend(true, this.records[ind], record); + if (noRefresh !== true) this.refreshRow(recid); // refresh only that record + } + return true; + }, + + get: function (recid, returnIndex) { + for (var i = 0; i < this.records.length; i++) { + if (this.records[i].recid == recid) { + if (returnIndex === true) return i; else return this.records[i]; + } + } + return null; + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.records.length-1; r >= 0; r--) { + if (this.records[r].recid == arguments[a]) { this.records.splice(r, 1); removed++; } + } + } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.buffered = this.records.length; + this.localSort(); + this.localSearch(); + } + this.refresh(); + return removed; + }, + + addColumn: function (before, columns) { + var added = 0; + if (arguments.length == 1) { + columns = before; + before = this.columns.length; + } else { + if (typeof before == 'string') before = this.getColumn(before, true); + if (before === null) before = this.columns.length; + } + if (!$.isArray(columns)) columns = [columns]; + for (var o in columns) { + this.columns.splice(before, 0, columns[o]); + before++; + added++; + } + this.initColumnOnOff(); + this.refresh(); + return added; + }, + + removeColumn: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a]) { this.columns.splice(r, 1); removed++; } + } + } + this.initColumnOnOff(); + this.refresh(); + return removed; + }, + + getColumn: function (field, returnIndex) { + for (var i = 0; i < this.columns.length; i++) { + if (this.columns[i].field == field) { + if (returnIndex === true) return i; else return this.columns[i]; + } + } + return null; + }, + + toggleColumn: function () { + var effected = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a]) { + this.columns[r].hidden = !this.columns[r].hidden; + effected++; + } + } + } + this.refresh(); + return effected; + }, + + showColumn: function () { + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a] && this.columns[r].hidden !== false) { + this.columns[r].hidden = false; + shown++; + } + } + } + this.refresh(); + return shown; + }, + + hideColumn: function () { + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a] && this.columns[r].hidden !== true) { + this.columns[r].hidden = true; + hidden++; + } + } + } + this.refresh(); + return hidden; + }, + + addSearch: function (before, search) { + var added = 0; + if (arguments.length == 1) { + search = before; + before = this.searches.length; + } else { + if (typeof before == 'string') before = this.getSearch(before, true); + if (before === null) before = this.searches.length; + } + if (!$.isArray(search)) search = [search]; + for (var o in search) { + this.searches.splice(before, 0, search[o]); + before++; + added++; + } + this.searchClose(); + return added; + }, + + removeSearch: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { this.searches.splice(r, 1); removed++; } + } + } + this.searchClose(); + return removed; + }, + + getSearch: function (field, returnIndex) { + for (var i = 0; i < this.searches.length; i++) { + if (this.searches[i].field == field) { + if (returnIndex === true) return i; else return this.searches[i]; + } + } + return null; + }, + + toggleSearch: function () { + var effected = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { + this.searches[r].hidden = !this.searches[r].hidden; + effected++; + } + } + } + this.searchClose(); + return effected; + }, + + showSearch: function () { + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== false) { + this.searches[r].hidden = false; + shown++; + } + } + } + this.searchClose(); + return shown; + }, + + hideSearch: function () { + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== true) { + this.searches[r].hidden = true; + hidden++; + } + } + } + this.searchClose(); + return hidden; + }, + + getSearchData: function (field) { + for (var s in this.searchData) { + if (this.searchData[s].field == field) return this.searchData[s]; + } + return null; + }, + + localSort: function (silent) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + console.log('ERROR: grid.localSort can only be used on local data source, grid.url should be empty.'); + return; + } + if ($.isEmptyObject(this.sortData)) return; + var time = (new Date()).getTime(); + var obj = this; + // process date fields + obj.prepareData(); + // process sortData + for (var s in this.sortData) { + var column = this.getColumn(this.sortData[s].field); + if (!column) return; + if (column.render && ['date', 'age'].indexOf(column.render) != -1) { + this.sortData[s]['field_'] = column.field + '_'; + } + if (column.render && ['time'].indexOf(column.render) != -1) { + this.sortData[s]['field_'] = column.field + '_'; + } + } + // process sort + this.records.sort(function (a, b) { + var ret = 0; + for (var s in obj.sortData) { + var fld = obj.sortData[s].field; + if (obj.sortData[s].field_) fld = obj.sortData[s].field_; + var aa = a[fld]; + var bb = b[fld]; + if (String(fld).indexOf('.') != -1) { + aa = obj.parseField(a, fld); + bb = obj.parseField(b, fld); + } + if (typeof aa == 'string') aa = $.trim(aa.toLowerCase()); + if (typeof bb == 'string') bb = $.trim(bb.toLowerCase()); + if (aa > bb) ret = (obj.sortData[s].direction == 'asc' ? 1 : -1); + if (aa < bb) ret = (obj.sortData[s].direction == 'asc' ? -1 : 1); + if (typeof aa != 'object' && typeof bb == 'object') ret = -1; + if (typeof bb != 'object' && typeof aa == 'object') ret = 1; + if (aa == null && bb != null) ret = 1; // all nuls and undefined on bottom + if (aa != null && bb == null) ret = -1; + if (ret != 0) break; + } + return ret; + }); + time = (new Date()).getTime() - time; + if (silent !== true) setTimeout(function () { obj.status('Sorting took ' + time/1000 + ' sec'); }, 10); + return time; + }, + + localSearch: function (silent) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + console.log('ERROR: grid.localSearch can only be used on local data source, grid.url should be empty.'); + return; + } + var time = (new Date()).getTime(); + var obj = this; + this.total = this.records.length; + // mark all records as shown + this.last.searchIds = []; + // prepare date/time fields + this.prepareData(); + // hide records that did not match + if (this.searchData.length > 0 && !url) { + this.total = 0; + for (var r in this.records) { + var rec = this.records[r]; + var fl = 0; + for (var s in this.searchData) { + var sdata = this.searchData[s]; + var search = this.getSearch(sdata.field); + if (sdata == null) continue; + if (search == null) search = { field: sdata.field, type: sdata.type }; + var val1 = String(obj.parseField(rec, search.field)).toLowerCase(); + if (typeof sdata.value != 'undefined') { + if (!$.isArray(sdata.value)) { + var val2 = String(sdata.value).toLowerCase(); + } else { + var val2 = sdata.value[0]; + var val3 = sdata.value[1]; + } + } + switch (sdata.operator) { + case 'is': + if (rec[search.field] == sdata.value) fl++; // do not hide record + if (search.type == 'date') { + var val1 = w2utils.formatDate(rec[search.field + '_'], 'yyyy-mm-dd'); + var val2 = w2utils.formatDate(val2, 'yyyy-mm-dd'); + if (val1 == val2) fl++; + } + if (search.type == 'time') { + var val1 = w2utils.formatTime(rec[search.field + '_'], 'h24:mi'); + var val2 = w2utils.formatTime(val2, 'h24:mi'); + if (val1 == val2) fl++; + } + break; + case 'between': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + if (parseFloat(rec[search.field]) >= parseFloat(val2) && parseFloat(rec[search.field]) <= parseFloat(val3)) fl++; + } + if (search.type == 'date') { + var val1 = rec[search.field + '_']; + var val2 = w2utils.isDate(val2, w2utils.settings.date_format, true); + var val3 = w2utils.isDate(val3, w2utils.settings.date_format, true); + if (val3 != null) val3 = new Date(val3.getTime() + 86400000); // 1 day + if (val1 >= val2 && val1 < val3) fl++; + } + if (search.type == 'time') { + var val1 = rec[search.field + '_']; + var val2 = w2utils.isTime(val2, true); + var val3 = w2utils.isTime(val3, true); + val2 = (new Date()).setHours(val2.hours, val2.minutes, val2.seconds ? val2.seconds : 0, 0); + val3 = (new Date()).setHours(val3.hours, val3.minutes, val3.seconds ? val3.seconds : 0, 0); + if (val1 >= val2 && val1 < val3) fl++; + } + break; + case 'in': + if (sdata.svalue) { + if (sdata.svalue.indexOf(val1) !== -1) fl++; + } else { + if (sdata.value.indexOf(val1) !== -1) fl++; + } + break; + case 'begins': + if (val1.indexOf(val2) == 0) fl++; // do not hide record + break; + case 'contains': + if (val1.indexOf(val2) >= 0) fl++; // do not hide record + break; + case 'ends': + if (val1.indexOf(val2) == val1.length - val2.length) fl++; // do not hide record + break; + } + } + if ((this.last.logic == 'OR' && fl != 0) || (this.last.logic == 'AND' && fl == this.searchData.length)) this.last.searchIds.push(parseInt(r)); + } + this.total = this.last.searchIds.length; + } + this.buffered = this.total; + time = (new Date()).getTime() - time; + if (silent !== true) setTimeout(function () { obj.status('Search took ' + time/1000 + ' sec'); }, 10); + return time; + }, + + getRangeData: function (range, extra) { + var rec1 = this.get(range[0].recid, true); + var rec2 = this.get(range[1].recid, true); + var col1 = range[0].column; + var col2 = range[1].column; + + var res = []; + if (col1 == col2) { // one row + for (var r = rec1; r <= rec2; r++) { + var record = this.records[r]; + var dt = record[this.columns[col1].field] || null; + if (extra !== true) { + res.push(dt); + } else { + res.push({ data: dt, column: col1, index: r, record: record }); + } + } + } else if (rec1 == rec2) { // one line + var record = this.records[rec1]; + for (var i = col1; i <= col2; i++) { + var dt = record[this.columns[i].field] || null; + if (extra !== true) { + res.push(dt); + } else { + res.push({ data: dt, column: i, index: rec1, record: record }); + } + } + } else { + for (var r = rec1; r <= rec2; r++) { + var record = this.records[r]; + res.push([]); + for (var i = col1; i <= col2; i++) { + var dt = record[this.columns[i].field]; + if (extra !== true) { + res[res.length-1].push(dt); + } else { + res[res.length-1].push({ data: dt, column: i, index: r, record: record }); + } + } + } + } + return res; + }, + + addRange: function (ranges) { + var added = 0; + if (this.selectType == 'row') return added; + if (!$.isArray(ranges)) ranges = [ranges]; + // if it is selection + for (var r in ranges) { + if (typeof ranges[r] != 'object') ranges[r] = { name: 'selection' }; + if (ranges[r].name == 'selection') { + if (this.show.selectionBorder === false) continue; + var sel = this.getSelection(); + if (sel.length == 0) { + this.removeRange(ranges[r].name); + continue; + } else { + var first = sel[0]; + var last = sel[sel.length-1]; + var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); + var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); + } + } else { // other range + var first = ranges[r].range[0]; + var last = ranges[r].range[1]; + var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); + var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); + } + if (first) { + var rg = { + name: ranges[r].name, + range: [{ recid: first.recid, column: first.column }, { recid: last.recid, column: last.column }], + style: ranges[r].style || '' + }; + // add range + var ind = false; + for (var t in this.ranges) if (this.ranges[t].name == ranges[r].name) { ind = r; break; } + if (ind !== false) { + this.ranges[ind] = rg; + } else { + this.ranges.push(rg); + } + added++ + } + } + this.refreshRanges(); + return added; + }, + + removeRange: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var name = arguments[a]; + $('#grid_'+ this.name +'_'+ name).remove(); + for (var r = this.ranges.length-1; r >= 0; r--) { + if (this.ranges[r].name == name) { + this.ranges.splice(r, 1); + removed++; + } + } + } + return removed; + }, + + refreshRanges: function () { + var obj = this; + var time = (new Date()).getTime(); + var rec = $('#grid_'+ this.name +'_records'); + for (var r in this.ranges) { + var rg = this.ranges[r]; + var first = rg.range[0]; + var last = rg.range[1]; + var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); + var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); + if ($('#grid_'+ this.name +'_'+ rg.name).length == 0) { + rec.append('
      '+ + (rg.name == 'selection' ? '
      ' : '')+ + '
      '); + } else { + $('#grid_'+ this.name +'_'+ rg.name).attr('style', rg.style); + } + if (td1.length > 0 && td2.length > 0) { + $('#grid_'+ this.name +'_'+ rg.name).css({ + left : (td1.position().left - 1 + rec.scrollLeft()) + 'px', + top : (td1.position().top - 1 + rec.scrollTop()) + 'px', + width : (td2.position().left - td1.position().left + td2.width() + 3) + 'px', + height : (td2.position().top - td1.position().top + td2.height() + 3) + 'px' + }); + } + } + + // add resizer events + $(this.box).find('#grid_'+ this.name +'_resizer').off('mousedown').on('mousedown', mouseStart); + //$(this.box).find('#grid_'+ this.name +'_resizer').off('selectstart').on('selectstart', function () { return false; }); // fixes chrome cursror bug + + var eventData = { phase: 'before', type: 'selectionExtend', target: obj.name, originalRange: null, newRange: null }; + + function mouseStart (event) { + var sel = obj.getSelection(); + obj.last.move = { + type : 'expand', + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + recid : sel[0].recid, + column : sel[0].column, + originalRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }], + newRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }] + }; + $(document).off('mousemove', mouseMove).on('mousemove', mouseMove); + $(document).off('mouseup', mouseStop).on('mouseup', mouseStop); + } + + function mouseMove (event) { + var mv = obj.last.move; + if (!mv || mv.type != 'expand') return; + mv.divX = (event.screenX - mv.x); + mv.divY = (event.screenY - mv.y); + // find new cell + var recid, column; + var tmp = event.originalEvent.target; + if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; + if (typeof $(tmp).attr('col') != 'undefined') column = parseInt($(tmp).attr('col')); + tmp = $(tmp).parents('tr')[0]; + recid = $(tmp).attr('recid'); + // new range + if (mv.newRange[1].recid == recid && mv.newRange[1].column == column) return; + var prevNewRange = $.extend({}, mv.newRange); + mv.newRange = [{ recid: mv.recid, column: mv.column }, { recid: recid, column: column }]; + // event before + eventData = obj.trigger($.extend(eventData, { originalRange: mv.originalRange, newRange : mv.newRange })); + if (eventData.isCancelled === true) { + mv.newRange = prevNewRange; + eventData.newRange = prevNewRange; + return; + } else { + // default behavior + obj.removeRange('grid-selection-expand'); + obj.addRange({ + name : 'grid-selection-expand', + range : eventData.newRange, + style : 'background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);' + }); + } + } + + function mouseStop (event) { + // default behavior + obj.removeRange('grid-selection-expand'); + delete obj.last.move; + $(document).off('mousemove', mouseMove); + $(document).off('mouseup', mouseStop); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + + return (new Date()).getTime() - time; + }, + + select: function () { + var selected = 0; + var sel = this.last.selection; + if (!this.multiSelect) this.selectNone(); + for (var a = 0; a < arguments.length; a++) { + var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; + var record = this.get(recid); + if (record == null) continue; + var index = this.get(recid, true); + var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) >= 0) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, recid: recid, index: index }); + if (eventData.isCancelled === true) continue; + // default action + sel.indexes.push(index); + sel.indexes.sort(function(a, b) { return a-b }); + recEl.addClass('w2ui-selected').data('selected', 'yes'); + recEl.find('.w2ui-grid-select-check').prop("checked", true); + selected++; + } else { + var col = arguments[a].column; + if (!w2utils.isInt(col)) { // select all columns + var cols = []; + for (var c in this.columns) { if (this.columns[c].hidden) continue; cols.push({ recid: recid, column: parseInt(c) }); } + if (!this.multiSelect) cols = cols.splice(0, 1); + return this.select.apply(this, cols); + } + var s = sel.columns[index] || []; + if ($.isArray(s) && s.indexOf(col) != -1) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, recid: recid, index: index, column: col }); + if (eventData.isCancelled === true) continue; + // default action + if (sel.indexes.indexOf(index) == -1) { + sel.indexes.push(index); + sel.indexes.sort(function(a, b) { return a-b }); + } + s.push(col); + s.sort(function(a, b) { return a-b }); // sort function must be for numerical sort + recEl.find(' > td[col='+ col +']').addClass('w2ui-selected'); + selected++; + recEl.data('selected', 'yes'); + recEl.find('.w2ui-grid-select-check').prop("checked", true); + // save back to selection object + sel.columns[index] = s; + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + // all selected? + if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { + $('#grid_'+ this.name +'_check_all').prop('checked', true); + } else { + $('#grid_'+ this.name +'_check_all').prop('checked', false); + } + this.status(); + this.addRange('selection'); + return selected; + }, + + unselect: function () { + var unselected = 0; + var sel = this.last.selection; + for (var a = 0; a < arguments.length; a++) { + var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; + var record = this.get(recid); + if (record == null) continue; + var index = this.get(record.recid, true); + var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) == -1) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, index: index }); + if (eventData.isCancelled === true) continue; + // default action + sel.indexes.splice(sel.indexes.indexOf(index), 1); + recEl.removeClass('w2ui-selected').removeData('selected'); + if (recEl.length != 0) recEl[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl.attr('custom_style'); + recEl.find('.w2ui-grid-select-check').prop("checked", false); + unselected++; + } else { + var col = arguments[a].column; + if (!w2utils.isInt(col)) { // unselect all columns + var cols = []; + for (var c in this.columns) { if (this.columns[c].hidden) continue; cols.push({ recid: recid, column: parseInt(c) }); } + return this.unselect.apply(this, cols); + } + var s = sel.columns[index]; + if (!$.isArray(s) || s.indexOf(col) == -1) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, column: col }); + if (eventData.isCancelled === true) continue; + // default action + s.splice(s.indexOf(col), 1); + $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid) + ' > td[col='+ col +']').removeClass('w2ui-selected'); + unselected++; + if (s.length == 0) { + delete sel.columns[index]; + sel.indexes.splice(sel.indexes.indexOf(index), 1); + recEl.removeData('selected'); + recEl.find('.w2ui-grid-select-check').prop("checked", false); + } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + // all selected? + if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { + $('#grid_'+ this.name +'_check_all').prop('checked', true); + } else { + $('#grid_'+ this.name +'_check_all').prop('checked', false); + } + // show number of selected + this.status(); + this.addRange('selection'); + return unselected; + }, + + selectAll: function () { + if (this.multiSelect === false) return; + // event before + var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, all: true }); + if (eventData.isCancelled === true) return; + // default action + var url = (typeof this.url != 'object' ? this.url : this.url.get); + var sel = this.last.selection; + var cols = []; + for (var c in this.columns) cols.push(parseInt(c)); + // if local data source and searched + sel.indexes = []; + if (!url && this.searchData.length !== 0) { + // local search applied + for (var i = 0; i < this.last.searchIds.length; i++) { + sel.indexes.push(this.last.searchIds[i]); + if (this.selectType != 'row') sel.columns[this.last.searchIds[i]] = cols.slice(); // .slice makes copy of the array + } + } else { + for (var i = 0; i < this.records.length; i++) { + sel.indexes.push(i); + if (this.selectType != 'row') sel.columns[i] = cols.slice(); // .slice makes copy of the array + } + } + this.refresh(); + // enable/disable toolbar buttons + var sel = this.getSelection(); + if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); + if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); + this.addRange('selection'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + selectNone: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, all: true }); + if (eventData.isCancelled === true) return; + // default action + var sel = this.last.selection; + for (var s in sel.indexes) { + var index = sel.indexes[s]; + var rec = this.records[index]; + var recid = rec ? rec.recid : null; + var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + recEl.removeClass('w2ui-selected').removeData('selected'); + recEl.find('.w2ui-grid-select-check').prop("checked", false); + // for not rows + if (this.selectType != 'row') { + var cols = sel.columns[index]; + for (var c in cols) recEl.find(' > td[col='+ cols[c] +']').removeClass('w2ui-selected'); + } + } + sel.indexes = []; + sel.columns = {}; + this.toolbar.disable('w2ui-edit', 'w2ui-delete'); + this.removeRange('selection'); + $('#grid_'+ this.name +'_check_all').prop('checked', false); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + getSelection: function (returnIndex) { + var ret = []; + var sel = this.last.selection; + if (this.selectType == 'row') { + for (var s in sel.indexes) { + if (!this.records[sel.indexes[s]]) continue; + if (returnIndex === true) ret.push(sel.indexes[s]); else ret.push(this.records[sel.indexes[s]].recid); + } + return ret; + } else { + for (var s in sel.indexes) { + var cols = sel.columns[sel.indexes[s]]; + if (!this.records[sel.indexes[s]]) continue; + for (var c in cols) { + ret.push({ recid: this.records[sel.indexes[s]].recid, index: parseInt(sel.indexes[s]), column: cols[c] }); + } + } + return ret; + } + }, + + search: function (field, value) { + var obj = this; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + var searchData = []; + var last_multi = this.last.multi; + var last_logic = this.last.logic; + var last_field = this.last.field; + var last_search = this.last.search; + // 1: search() - advanced search (reads from popup) + if (arguments.length == 0) { + last_search = ''; + // advanced search + for (var s in this.searches) { + var search = this.searches[s]; + var operator = $('#grid_'+ this.name + '_operator_'+s).val(); + var field1 = $('#grid_'+ this.name + '_field_'+s); + var field2 = $('#grid_'+ this.name + '_field2_'+s); + var value1 = field1.val(); + var value2 = field2.val(); + var svalue = null; + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + var fld1 = field1.data('w2field'); + var fld2 = field2.data('w2field'); + if (fld1) value1 = fld1.clean(value1); + if (fld2) value2 = fld2.clean(value2); + } + if (['list', 'enum'].indexOf(search.type) != -1) { + value1 = field1.data('selected') || {}; + if ($.isArray(value1)) { + svalue = []; + for (var v in value1) { + svalue.push(w2utils.isFloat(value1[v].id) ? parseFloat(value1[v].id) : String(value1[v].id).toLowerCase()); + delete value1[v].hidden; + } + } else { + value1 = value1.id || ''; + } + } + if ((value1 != '' && value1 != null) || (typeof value2 != 'undefined' && value2 != '')) { + var tmp = { + field : search.field, + type : search.type, + operator : operator + } + if (operator == 'between') { + $.extend(tmp, { value: [value1, value2] }); + } else if (operator == 'in' && typeof value1 == 'string') { + $.extend(tmp, { value: value1.split(',') }); + } else { + $.extend(tmp, { value: value1 }); + } + if (svalue) $.extend(tmp, { svalue: svalue }); + // conver date to unix time + try { + if (search.type == 'date' && operator == 'between') { + tmp.value[0] = value1; // w2utils.isDate(value1, w2utils.settings.date_format, true).getTime(); + tmp.value[1] = value2; // w2utils.isDate(value2, w2utils.settings.date_format, true).getTime(); + } + if (search.type == 'date' && operator == 'is') { + tmp.value = value1; // w2utils.isDate(value1, w2utils.settings.date_format, true).getTime(); + } + } catch (e) { + + } + searchData.push(tmp); + } + } + if (searchData.length > 0 && !url) { + last_multi = true; + last_logic = 'AND'; + } else { + last_multi = true; + last_logic = 'AND'; + } + } + // 2: search(field, value) - regular search + if (typeof field == 'string') { + last_field = field; + last_search = value; + last_multi = false; + last_logic = 'OR'; + // loop through all searches and see if it applies + if (typeof value != 'undefined') { + if (field.toLowerCase() == 'all') { + // if there are search fields loop thru them + if (this.searches.length > 0) { + for (var s in this.searches) { + var search = this.searches[s]; + if (search.type == 'text' || (search.type == 'alphanumeric' && w2utils.isAlphaNumeric(value)) + || (search.type == 'int' && w2utils.isInt(value)) || (search.type == 'float' && w2utils.isFloat(value)) + || (search.type == 'percent' && w2utils.isFloat(value)) || (search.type == 'hex' && w2utils.isHex(value)) + || (search.type == 'currency' && w2utils.isMoney(value)) || (search.type == 'money' && w2utils.isMoney(value)) + || (search.type == 'date' && w2utils.isDate(value)) ) { + var tmp = { + field : search.field, + type : search.type, + operator : (search.type == 'text' ? 'contains' : 'is'), + value : value + }; + searchData.push(tmp); + } + // range in global search box + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1 && String(value).indexOf('-') != -1) { + var t = String(value).split('-'); + var tmp = { + field : search.field, + type : search.type, + operator : 'between', + value : [t[0], t[1]] + }; + searchData.push(tmp); + } + } + } else { + // no search fields, loop thru columns + for (var c in this.columns) { + var tmp = { + field : this.columns[c].field, + type : 'text', + operator : 'contains', + value : value + }; + searchData.push(tmp); + } + } + } else { + var el = $('#grid_'+ this.name +'_search_all'); + var search = this.getSearch(field); + if (search == null) search = { field: field, type: 'text' }; + if (search.field == field) this.last.caption = search.caption; + if (search.type == 'list') { + var tmp = el.data('selected'); + if (tmp && !$.isEmptyObject(tmp)) value = tmp.id; + } + if (value != '') { + var op = 'contains'; + var val = value; + if (w2utils.isInt(value)) op = 'is'; + if (['date', 'time'].indexOf(search.type) != -1) op = 'is'; + if (search.type == 'int' && value != '') { + if (String(value).indexOf('-') != -1) { + var tmp = value.split('-'); + if (tmp.length == 2) { + op = 'between'; + val = [parseInt(tmp[0]), parseInt(tmp[1])]; + } + } + if (String(value).indexOf(',') != -1) { + var tmp = value.split(','); + op = 'in'; + val = []; + for (var t in tmp) val.push(tmp[t]); + } + } + var tmp = { + field : search.field, + type : search.type, + operator : op, + value : val + } + searchData.push(tmp); + } + } + } + } + // 3: search([ { field, value, [operator,] [type] }, { field, value, [operator,] [type] } ], logic) - submit whole structure + if ($.isArray(field)) { + var logic = 'AND'; + if (typeof value == 'string') { + logic = value.toUpperCase(); + if (logic != 'OR' && logic != 'AND') logic = 'AND'; + } + last_search = ''; + last_multi = true; + last_logic = logic; + for (var f in field) { + var data = field[f]; + var search = this.getSearch(data.field); + if (search == null) search = { type: 'text', operator: 'contains' }; + // merge current field and search if any + searchData.push($.extend(true, {}, search, data)); + } + } + // event before + var eventData = this.trigger({ phase: 'before', type: 'search', target: this.name, searchData: searchData, + searchField: (field ? field : 'multi'), searchValue: (value ? value : 'multi') }); + if (eventData.isCancelled === true) return; + // default action + this.searchData = eventData.searchData; + this.last.field = last_field; + this.last.search = last_search; + this.last.multi = last_multi; + this.last.logic = last_logic; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + // -- clear all search field + this.searchClose(); + this.set({ expanded: false }, true); + // apply search + if (url) { + this.last.xhr_offset = 0; + this.reload(); + } else { + // local search + this.localSearch(); + this.refresh(); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + searchOpen: function () { + if (!this.box) return; + if (this.searches.length == 0) return; + var obj = this; + // show search + $('#tb_'+ this.name +'_toolbar_item_w2ui-search-advanced').w2overlay( + this.getSearchesHTML(), { + name : 'searches-'+ this.name, + left : -10, + 'class' : 'w2ui-grid-searches', + onShow : function () { + if (obj.last.logic == 'OR') obj.searchData = []; + obj.initSearches(); + $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches').data('grid-name', obj.name); + var sfields = $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches *[rel=search]'); + if (sfields.length > 0) sfields[0].focus(); + } + } + ); + }, + + searchClose: function () { + if (!this.box) return; + if (this.searches.length == 0) return; + if (this.toolbar) this.toolbar.uncheck('w2ui-search-advanced') + // hide search + if ($('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches').length > 0) { + $().w2overlay('', { name: 'searches-'+ this.name }); + } + }, + + searchShowFields: function () { + var el = $('#grid_'+ this.name +'_search_all'); + var html = '
      '; + for (var s = -1; s < this.searches.length; s++) { + var search = this.searches[s]; + if (s == -1) { + if (!this.multiSearch) continue; + search = { field: 'all', caption: w2utils.lang('All Fields') }; + } else { + if (this.searches[s].hidden === true) continue; + } + html += ''+ + ' '+ + ' '+ + ''; + } + html += "
      '+ search.caption +'
      "; + // need timer otherwise does nto show with list type + setTimeout(function () { + $(el).w2overlay(html, { left: -10 }); + }, 1); + }, + + initAllField: function (field, value) { + var el = $('#grid_'+ this.name +'_search_all'); + var search = this.getSearch(field); + if (field == 'all') { + search = { field: 'all', caption: w2utils.lang('All Fields') }; + el.w2field('clear'); + el.change().focus(); + } else { + var st = search.type; + if (['enum', 'select'].indexOf(st) != -1) st = 'list'; + el.w2field(st, $.extend({}, search.options, { suffix: '', autoFormat: false, selected: value })); + if (['list', 'enum'].indexOf(search.type) != -1) { + this.last.search = ''; + this.last.item = ''; + el.val(''); + } + // set focus + setTimeout(function () { + el.focus(); /* do not do el.change() as it will refresh grid and pull from server */ + }, 1); + } + // update field + if (this.last.search != '') { + this.search(search.field, this.last.search); + } else { + this.last.field = search.field; + this.last.caption = search.caption; + } + el.attr('placeholder', search.caption); + $().w2overlay(); + }, + + searchReset: function (noRefresh) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'search', target: this.name, searchData: [] }); + if (eventData.isCancelled === true) return; + // default action + this.searchData = []; + this.last.search = ''; + this.last.logic = 'OR'; + // --- do not reset to All Fields (I think) + // if (this.last.multi) { + // if (!this.multiSearch) { + // this.last.field = this.searches[0].field; + // this.last.caption = this.searches[0].caption; + // } else { + // this.last.field = 'all'; + // this.last.caption = w2utils.lang('All Fields'); + // } + // } + this.last.multi = false; + this.last.xhr_offset = 0; + // reset scrolling position + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + // -- clear all search field + this.searchClose(); + $('#grid_'+ this.name +'_search_all').val(''); + // apply search + if (!noRefresh) this.reload(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + clear: function (noRefresh) { + this.offset = 0; + this.total = 0; + this.buffered = 0; + this.records = []; + this.summary = []; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.range_start = null; + this.last.range_end = null; + this.last.xhr_offset = 0; + if (!noRefresh) this.refresh(); + }, + + reset: function (noRefresh) { + // reset last remembered state + this.offset = 0; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + this.last.range_start = null; + this.last.range_end = null; + this.last.xhr_offset = 0; + this.searchReset(noRefresh); + // initial sort + if (this.last.sortData != null ) this.sortData = this.last.sortData; + // select none without refresh + this.set({ expanded: false }, true); + // refresh + if (!noRefresh) this.refresh(); + }, + + skip: function (offset) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + this.offset = parseInt(offset); + if (this.offset < 0 || !w2utils.isInt(this.offset)) this.offset = 0; + if (this.offset > this.total) this.offset = this.total - this.limit; + this.records = []; + this.buffered = 0; + this.last.xhr_offset = 0; + this.last.pull_more = true; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + $('#grid_'+ this.name +'_records').prop('scrollTop', 0); + this.initColumnOnOff(); + this.reload(); + } else { + console.log('ERROR: grid.skip() can only be called when you have remote data source.'); + } + }, + + load: function (url, callBack) { + if (typeof url == 'undefined') { + console.log('ERROR: You need to provide url argument when calling .load() method of "'+ this.name +'" object.'); + return; + } + // default action + this.request('get-records', {}, url, callBack); + }, + + reload: function (callBack) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + this.clear(true); + this.request('get-records', {}, null, callBack); + } else { + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.range_start = null; + this.last.range_end = null; + this.localSearch(); + this.refresh(); + if (typeof callBack == 'function') callBack({ status: 'success' }); + } + }, + + request: function (cmd, add_params, url, callBack) { + if (typeof add_params == 'undefined') add_params = {}; + if (typeof url == 'undefined' || url == '' || url == null) url = this.url; + if (url == '' || url == null) return; + // build parameters list + var params = {}; + if (!w2utils.isInt(this.offset)) this.offset = 0; + if (!w2utils.isInt(this.last.xhr_offset)) this.last.xhr_offset = 0; + // add list params + params['cmd'] = cmd; + params['selected'] = this.getSelection(); + params['limit'] = this.limit; + params['offset'] = parseInt(this.offset) + this.last.xhr_offset; + params['search'] = this.searchData; + params['searchLogic'] = this.last.logic; + params['sort'] = (this.sortData.length != 0 ? this.sortData : ''); + // append other params + $.extend(params, this.postData); + $.extend(params, add_params); + // event before + if (cmd == 'get-records') { + var eventData = this.trigger({ phase: 'before', type: 'request', target: this.name, url: url, postData: params }); + if (eventData.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } + } else { + var eventData = { url: url, postData: params }; + } + // call server to get data + var obj = this; + if (this.last.xhr_offset == 0) { + this.lock(this.msgRefresh, true); + } else { + var more = $('#grid_'+ this.name +'_rec_more'); + if (this.autoLoad === true) { + more.show().find('td').html('
      '); + } else { + more.find('td').html('
      '+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
      '); + } + } + if (this.last.xhr) try { this.last.xhr.abort(); } catch (e) {}; + var xhr_type = 'GET'; + var url = (typeof eventData.url != 'object' ? eventData.url : eventData.url.get); + if (params.cmd == 'save-records') { + if (typeof eventData.url == 'object') url = eventData.url.save; + xhr_type = 'PUT'; // so far it is always update + } + if (params.cmd == 'delete-records') { + if (typeof eventData.url == 'object') url = eventData.url.remove; + xhr_type = 'DELETE'; + } + if (!w2utils.settings.RESTfull) xhr_type = 'POST'; + if (this.method) xhr_type = this.method; + this.last.xhr_cmd = params.cmd; + this.last.xhr_start = (new Date()).getTime(); + this.last.xhr = $.ajax({ + type : xhr_type, + url : url, + data : (typeof eventData.postData == 'object' ? String($.param(eventData.postData, false)).replace(/%5B/g, '[').replace(/%5D/g, ']') : eventData.postData), + dataType : 'text', + complete : function (xhr, status) { + obj.requestComplete(status, cmd, callBack); + } + }); + if (cmd == 'get-records') { + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + }, + + requestComplete: function(status, cmd, callBack) { + var obj = this; + this.unlock(); + setTimeout(function () { obj.status(w2utils.lang('Server Response') + ' ' + ((new Date()).getTime() - obj.last.xhr_start)/1000 +' ' + w2utils.lang('sec')); }, 10); + this.last.pull_more = false; + this.last.pull_refresh = true; + + // event before + var event_name = 'load'; + if (this.last.xhr_cmd == 'save-records') event_name = 'save'; + if (this.last.xhr_cmd == 'delete-records') event_name = 'deleted'; + var eventData = this.trigger({ phase: 'before', target: this.name, type: event_name, xhr: this.last.xhr, status: status }); + if (eventData.isCancelled === true) { + if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); + return; + } + // parse server response + var data; + var responseText = this.last.xhr.responseText; + if (status != 'error') { + // default action + if (typeof responseText != 'undefined' && responseText != '') { + // check if the onLoad handler has not already parsed the data + if (typeof responseText == "object") { + data = responseText; + } else { + if (typeof obj.parser == 'function') { + data = obj.parser(responseText); + if (typeof data != 'object') { + console.log('ERROR: Your parser did not return proper object'); + } + } else { + // $.parseJSON or $.getJSON did not work because those expect perfect JSON data - where everything is in double quotes + // + // TODO: avoid (potentially malicious) code injection from the response. + try { eval('data = '+ responseText); } catch (e) { } + } + } + // convert recids + if (obj.recid) { + for (var r in data.records) { + data.records[r]['recid'] = data.records[r][obj.recid]; + } + } + if (typeof data == 'undefined') { + data = { + status : 'error', + message : this.msgNotJSON, + responseText : responseText + }; + } + if (data['status'] == 'error') { + obj.error(data['message']); + } else { + if (cmd == 'get-records') { + if (this.last.xhr_offset == 0) { + this.records = []; + this.summary = []; + //data.xhr_status=data.status; + delete data.status; + $.extend(true, this, data); + this.buffered = this.records.length; + } else { + var records = data.records; + delete data.records; + //data.xhr_status=data.status; + delete data.status; + $.extend(true, this, data); + for (var r in records) { + this.records.push(records[r]); + } + this.buffered = this.records.length; + } + } + if (cmd == 'delete-records') { + this.reset(); // unselect old selections + this.reload(); + return; + } + } + } + } else { + data = { + status : 'error', + message : this.msgAJAXerror, + responseText : responseText + }; + obj.error(this.msgAJAXerror); + } + // event after + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(); + this.localSearch(); + } + this.total = parseInt(this.total); + this.trigger($.extend(eventData, { phase: 'after' })); + // do not refresh if loading on infinite scroll + if (this.last.xhr_offset == 0) this.refresh(); else this.scroll(); + // call back + if (typeof callBack == 'function') callBack(data); + }, + + error: function (msg) { + var obj = this; + // let the management of the error outside of the grid + var eventData = this.trigger({ target: this.name, type: 'error', message: msg , xhr: this.last.xhr }); + if (eventData.isCancelled === true) { + if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); + return; + } + w2alert(msg, 'Error'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + getChanges: function () { + var changes = []; + for (var r in this.records) { + var rec = this.records[r]; + if (typeof rec['changes'] != 'undefined') { + changes.push($.extend(true, { recid: rec.recid }, rec.changes)); + } + } + return changes; + }, + + mergeChanges: function () { + var changes = this.getChanges(); + for (var c in changes) { + var record = this.get(changes[c].recid); + for (var s in changes[c]) { + if (s == 'recid') continue; // do not allow to change recid + try { eval('record.' + s + ' = changes[c][s]'); } catch (e) {} + delete record.changes; + } + } + this.refresh(); + }, + + // =================================================== + // -- Action Handlers + + save: function () { + var obj = this; + var changes = this.getChanges(); + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'submit', changes: changes }); + if (eventData.isCancelled === true) return; + var url = (typeof this.url != 'object' ? this.url : this.url.save); + if (url) { + this.request('save-records', { 'changes' : eventData.changes }, null, + function (data) { + if (data.status !== 'error') { + // only merge changes, if save was successful + obj.mergeChanges(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + ); + } else { + this.mergeChanges(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + }, + + editField: function (recid, column, value, event) { + var obj = this; + var index = obj.get(recid, true); + var rec = obj.records[index]; + var col = obj.columns[column]; + var edit = col ? col.editable : null; + if (!rec || !col || !edit || rec.editable === false) return; + if (['enum', 'file'].indexOf(edit.type) != -1) { + console.log('ERROR: input types "enum" and "file" are not supported in inline editing.'); + return; + } + // event before + var eventData = obj.trigger({ phase: 'before', type: 'editField', target: obj.name, recid: recid, column: column, value: value, + index: index, originalEvent: event }); + if (eventData.isCancelled === true) return; + value = eventData.value; + // default behaviour + this.selectNone(); + this.select({ recid: recid, column: column }); + this.last.edit_col = column; + if (['checkbox', 'check'].indexOf(edit.type) != -1) return; + // create input element + var tr = $('#grid_'+ obj.name +'_rec_'+ w2utils.escapeId(recid)); + var el = tr.find('[col='+ column +'] > div'); + if (typeof edit.inTag == 'undefined') edit.inTag = ''; + if (typeof edit.outTag == 'undefined') edit.outTag = ''; + if (typeof edit.style == 'undefined') edit.style = ''; + if (typeof edit.items == 'undefined') edit.items = []; + var val = (rec.changes && typeof rec.changes[col.field] != 'undefined' ? w2utils.stripTags(rec.changes[col.field]) : w2utils.stripTags(rec[col.field])); + if (val == null || typeof val == 'undefined') val = ''; + if (typeof value != 'undefined' && value != null) val = value; + var addStyle = (typeof col.style != 'undefined' ? col.style + ';' : ''); + if (typeof col.render == 'string' && ['number', 'int', 'float', 'money', 'percent'].indexOf(col.render.split(':')[0]) != -1) { + addStyle += 'text-align: right;'; + } + if (edit.type == 'select') { + var html = ''; + for (var i in edit.items) { + html += ''; + } + el.addClass('w2ui-editable') + .html('' + edit.outTag); + el.find('select').focus() + .on('change', function (event) { + delete obj.last.move; + }) + .on('blur', function (event) { + obj.editChange.call(obj, this, index, column, event); + }); + } else { + el.addClass('w2ui-editable') + .html('' + edit.outTag); + if (value == null) el.find('input').val(val != 'object' ? val : ''); + // init w2field + var input = el.find('input').get(0); + $(input).w2field(edit.type, $.extend(edit, { selected: val })) + // add blur listener + setTimeout(function () { + var tmp = input; + if (edit.type == 'list') { + tmp = $($(input).data('w2field').helpers.focus).find('input'); + if (val != 'object' && val != '') tmp.val(val).css({ opacity: 1 }).prev().css({ opacity: 1 }); + } + $(tmp).on('blur', function (event) { + obj.editChange.call(obj, input, index, column, event); + }); + }, 10); + if (value != null) $(input).val(val != 'object' ? val : ''); + } + setTimeout(function () { + el.find('input, select') + .on('click', function (event) { + event.stopPropagation(); + }) + .on('keydown', function (event) { + var cancel = false; + switch (event.keyCode) { + case 9: // tab + cancel = true; + var next_rec = recid; + var next_col = event.shiftKey ? obj.prevCell(column, true) : obj.nextCell(column, true); + // next or prev row + if (next_col === false) { + var tmp = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); + if (tmp != null && tmp != index) { + next_rec = obj.records[tmp].recid; + // find first editable row + for (var c in obj.columns) { + var tmp = obj.columns[c].editable; + if (typeof tmp != 'undefined' && ['checkbox', 'check'].indexOf(tmp.type) == -1) { + next_col = parseInt(c); + if (!event.shiftKey) break; + } + } + } + + } + if (next_rec === false) next_rec = recid; + if (next_col === false) next_col = column; + // init new or same record + this.blur(); + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: next_rec, column: next_col }); + } else { + obj.editField(next_rec, next_col, null, event); + } + }, 1); + break; + + case 13: // enter + this.blur(); + var next = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); + if (next != null && next != index) { + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: obj.records[next].recid, column: column }); + } else { + obj.editField(obj.records[next].recid, column, null, event); + } + }, 100); + } + break; + + case 38: // up arrow + if (!event.shiftKey) break; + cancel = true; + var next = obj.prevRow(index); + if (next != index) { + this.blur(); + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: obj.records[next].recid, column: column }); + } else { + obj.editField(obj.records[next].recid, column, null, event); + } + }, 1); + } + break; + + case 40: // down arrow + if (!event.shiftKey) break; + cancel = true; + var next = obj.nextRow(index); + if (next != null && next != index) { + this.blur(); + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: obj.records[next].recid, column: column }); + } else { + obj.editField(obj.records[next].recid, column, null, event); + } + }, 1); + } + break; + + case 27: // escape + var old = obj.parseField(rec, col.field); + if (rec.changes && typeof rec.changes[col.field] != 'undefined') old = rec.changes[col.field]; + this.value = typeof old != 'undefined' ? old : ''; + this.blur(); + setTimeout(function () { obj.select({ recid: recid, column: column }) }, 1); + break; + } + if (cancel) if (event.preventDefault) event.preventDefault(); + }); + // focus and select + var tmp = el.find('input').focus(); + if (value != null) { + // set cursor to the end + tmp[0].setSelectionRange(tmp.val().length, tmp.val().length); + } else { + tmp.select(); + } + + }, 1); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + editChange: function (el, index, column, event) { + // all other fields + var summary = index < 0; + index = index < 0 ? -index - 1 : index; + var records = summary ? this.summary : this.records; + var rec = records[index]; + var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)); + var col = this.columns[column]; + var new_val = el.value; + var old_val = this.parseField(rec, col.field); + var tmp = $(el).data('w2field'); + if (tmp) { + new_val = tmp.clean(new_val); + if (tmp.type == 'list' && new_val != '') new_val = $(el).data('selected'); + } + if (el.type == 'checkbox') new_val = el.checked; + // change/restore event + var eventData = { + phase: 'before', type: 'change', target: this.name, input_id: el.id, recid: rec.recid, index: index, column: column, + value_new: new_val, value_previous: (rec.changes && rec.changes.hasOwnProperty(col.field) ? rec.changes[col.field]: old_val), value_original: old_val + }; + while (true) { + new_val = eventData.value_new; + if (( typeof old_val == 'undefined' || old_val === null ? '' : String(old_val)) !== String(new_val)) { + // change event + eventData = this.trigger($.extend(eventData, { type: 'change', phase: 'before' })); + if (eventData.isCancelled !== true) { + if (new_val !== eventData.value_new) { + // re-evaluate the type of change to be made + continue; + } + // default action + rec.changes = rec.changes || {}; + rec.changes[col.field] = eventData.value_new; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + } else { + // restore event + eventData = this.trigger($.extend(eventData, { type: 'restore', phase: 'before' })); + if (eventData.isCancelled !== true) { + if (new_val !== eventData.value_new) { + // re-evaluate the type of change to be made + continue; + } + // default action + if (rec.changes) delete rec.changes[col.field]; + if ($.isEmptyObject(rec.changes)) delete rec.changes; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + } + break; + } + // refresh cell + var cell = this.getCellHTML(index, column, summary); + if (!summary) { + if (rec.changes && typeof rec.changes[col.field] != 'undefined') { + $(tr).find('[col='+ column +']').addClass('w2ui-changed').html(cell); + } else { + $(tr).find('[col='+ column +']').removeClass('w2ui-changed').html(cell); + } + } + }, + + delete: function (force) { + var obj = this; + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'delete', force: force }); + if (eventData.isCancelled === true) return; + force = eventData.force; + // default action + var recs = this.getSelection(); + if (recs.length == 0) return; + if (this.msgDelete != '' && !force) { + w2confirm({ + title : w2utils.lang('Delete Confirmation'), + msg : obj.msgDelete, + callBack: function (result) { + console.log('result', result); + if (result == 'Yes') w2ui[obj.name].delete(true); + } + }); + return; + } + // call delete script + var url = (typeof this.url != 'object' ? this.url : this.url.remove); + if (url) { + this.request('delete-records'); + } else { + this.selectNone(); + if (typeof recs[0] != 'object') { + this.remove.apply(this, recs); + } else { + // clear cells + for (var r in recs) { + var fld = this.columns[recs[r].column].field; + var ind = this.get(recs[r].recid, true); + if (ind != null && fld != 'recid') { + this.records[ind][fld] = ''; + if (this.records[ind].changes) delete this.records[ind].changes[fld]; + } + } + this.refresh(); + } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + click: function (recid, event) { + var time = (new Date()).getTime(); + var column = null; + if (this.last.cancelClick == true) return; + if (typeof recid == 'object') { + column = recid.column; + recid = recid.recid; + } + if (typeof event == 'undefined') event = {}; + // check for double click + if (time - parseInt(this.last.click_time) < 250 && event.type == 'click') { + this.dblClick(recid, event); + return; + } + this.last.click_time = time; + // column user clicked on + if (column == null && event.target) { + var tmp = event.target; + if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; + if (typeof $(tmp).attr('col') != 'undefined') column = parseInt($(tmp).attr('col')); + } + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'click', recid: recid, column: column, originalEvent: event }); + if (eventData.isCancelled === true) return; + // if it is subgrid unselect top grid + var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)).parents('tr'); + if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var grid = parent.parents('.w2ui-grid').attr('name'); + w2ui[grid].selectNone(); + // all subgrids + parent.parents('.w2ui-grid').find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { + var grid = $(el).attr('name'); + if (w2ui[grid]) w2ui[grid].selectNone(); + }); + } + // unselect all subgrids + $(this.box).find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { + var grid = $(el).attr('name'); + if (w2ui[grid]) w2ui[grid].selectNone(); + }); + // default action + var obj = this; + var sel = this.getSelection(); + $('#grid_'+ this.name +'_check_all').prop("checked", false); + var ind = this.get(recid, true); + var record = this.records[ind]; + var selectColumns = []; + obj.last.sel_ind = ind; + obj.last.sel_col = column; + obj.last.sel_recid = recid; + obj.last.sel_type = 'click'; + // multi select with shif key + if (event.shiftKey && sel.length > 0 && obj.multiSelect) { + if (sel[0].recid) { + var start = this.get(sel[0].recid, true); + var end = this.get(recid, true); + if (column > sel[0].column) { + var t1 = sel[0].column; + var t2 = column; + } else { + var t1 = column; + var t2 = sel[0].column; + } + for (var c = t1; c <= t2; c++) selectColumns.push(c); + } else { + var start = this.get(sel[0], true); + var end = this.get(recid, true); + } + var sel_add = [] + if (start > end) { var tmp = start; start = end; end = tmp; } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + for (var i = start; i <= end; i++) { + if (this.searchData.length > 0 && !url && $.inArray(i, this.last.searchIds) == -1) continue; + if (this.selectType == 'row') { + sel_add.push(this.records[i].recid); + } else { + for (var sc in selectColumns) sel_add.push({ recid: this.records[i].recid, column: selectColumns[sc] }); + } + //sel.push(this.records[i].recid); + } + this.select.apply(this, sel_add); + } else { + var last = this.last.selection; + var flag = (last.indexes.indexOf(ind) != -1 ? true : false); + // clear other if necessary + if (((!event.ctrlKey && !event.shiftKey && !event.metaKey) || !this.multiSelect) && !this.showSelectColumn) { + if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; + if (sel.length > 300) this.selectNone(); else this.unselect.apply(this, sel); + if (flag === true) { + this.unselect({ recid: recid, column: column }); + } else { + this.select({ recid: recid, column: column }); + } + } else { + if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; + if (flag === true) { + this.unselect({ recid: recid, column: column }); + } else { + this.select({ recid: recid, column: column }); + } + } + } + this.status(); + obj.initResize(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + columnClick: function (field, event) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'columnClick', target: this.name, field: field, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behaviour + var column = this.getColumn(field); + if (column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false) ); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + keydown: function (event) { + // this method is called from w2utils + var obj = this; + if (obj.keyboard !== true) return; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behavior + var empty = false; + var records = $('#grid_'+ obj.name +'_records'); + var sel = obj.getSelection(); + if (sel.length == 0) empty = true; + var recid = sel[0] || null; + var columns = []; + var recid2 = sel[sel.length-1]; + if (typeof recid == 'object' && recid != null) { + recid = sel[0].recid; + columns = []; + var ii = 0; + while (true) { + if (!sel[ii] || sel[ii].recid != recid) break; + columns.push(sel[ii].column); + ii++; + } + recid2 = sel[sel.length-1].recid; + } + var ind = obj.get(recid, true); + var ind2 = obj.get(recid2, true); + var rec = obj.get(recid); + var recEL = $('#grid_'+ obj.name +'_rec_'+ (ind !== null ? w2utils.escapeId(obj.records[ind].recid) : 'none')); + var cancel = false; + var key = event.keyCode; + var shiftKey= event.shiftKey; + if (key == 9) { // tab key + if (event.shiftKey) key = 37; else key = 39; // replace with arrows + shiftKey = false; + cancel = true; + } + switch (key) { + case 8: // backspace + case 46: // delete + obj.delete(); + cancel = true; + event.stopPropagation(); + break; + + case 27: // escape + obj.selectNone(); + if (sel.length > 0 && typeof sel[0] == 'object') { + obj.select({ recid: sel[0].recid, column: sel[0].column }); + } + cancel = true; + break; + + case 65: // cmd + A + if (!event.metaKey && !event.ctrlKey) break; + obj.selectAll(); + cancel = true; + break; + + case 70: // cmd + F + if (!event.metaKey && !event.ctrlKey) break; + $('#grid_'+ obj.name + '_search_all').focus(); + cancel = true; + break; + + case 13: // enter + // if expandable columns - expand it + if (this.selectType == 'row' && obj.show.expandColumn === true) { + if (recEL.length <= 0) break; + obj.toggle(recid, event); + cancel = true; + } else { // or enter edit + for (var c in this.columns) { + if (this.columns[c].editable) { + columns.push(parseInt(c)); + break; + } + } + // edit last column that was edited + if (this.selectType == 'row' && this.last.edit_col) columns = [this.last.edit_col]; + if (columns.length > 0) { + obj.editField(recid, columns[0], null, event); + cancel = true; + } + } + break; + + case 37: // left + if (empty) break; + // check if this is subgrid + var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind].recid)).parents('tr'); + if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var recid = parent.prev().attr('recid'); + var grid = parent.parents('.w2ui-grid').attr('name'); + obj.selectNone(); + w2utils.keyboard.active(grid); + w2ui[grid].set(recid, { expanded: false }); + w2ui[grid].collapse(recid); + w2ui[grid].click(recid); + cancel = true; + break; + } + if (this.selectType == 'row') { + if (recEL.length <= 0 || rec.expanded !== true ) break; + obj.set(recid, { expanded: false }, true); + obj.collapse(recid, event); + } else { + var prev = obj.prevCell(columns[0]); + if (prev !== false) { + if (shiftKey && obj.multiSelect) { + if (tmpUnselect()) return; + var tmp = []; + var newSel = []; + var unSel = []; + if (columns.indexOf(this.last.sel_col) == 0 && columns.length > 1) { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + unSel.push({ recid: sel[i].recid, column: columns[columns.length-1] }); + } + } else { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + newSel.push({ recid: sel[i].recid, column: prev }); + } + } + obj.unselect.apply(obj, unSel); + obj.select.apply(obj, newSel); + } else { + event.shiftKey = false; + obj.click({ recid: recid, column: prev }, event); + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=1; s 1) { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + unSel.push({ recid: sel[i].recid, column: columns[0] }); + } + } else { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + newSel.push({ recid: sel[i].recid, column: next }); + } + } + obj.unselect.apply(obj, unSel); + obj.select.apply(obj, newSel); + } else { + obj.click({ recid: recid, column: next }, event); + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=0; s 0 && w2ui[subgrid.attr('name')]) { + obj.selectNone(); + var grid = subgrid.attr('name'); + var recs = w2ui[grid].records; + w2utils.keyboard.active(grid); + w2ui[grid].click(recs[recs.length-1].recid); + cancel = true; + break; + } + } + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return; + if (obj.selectType == 'row') { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + obj.unselect(obj.records[ind2].recid); + } else { + obj.select(obj.records[prev].recid); + } + } else { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + prev = ind2; + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); + obj.unselect.apply(obj, tmp); + } else { + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); + obj.select.apply(obj, tmp); + } + } + } else { // move selected record + obj.selectNone(); + obj.click({ recid: obj.records[prev].recid, column: columns[0] }, event); + } + obj.scrollIntoView(prev); + if (event.preventDefault) event.preventDefault(); + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=1; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var recid = parent.prev().attr('recid'); + var grid = parent.parents('.w2ui-grid').attr('name'); + obj.selectNone(); + w2utils.keyboard.active(grid); + w2ui[grid].click(recid); + cancel = true; + break; + } + } + break; + + case 40: // down + if (empty) selectTopRecord(); + if (recEL.length <= 0) break; + // jump into subgrid + if (obj.records[ind2].expanded) { + var subgrid = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind2].recid) +'_expanded_row').find('.w2ui-grid'); + if (subgrid.length > 0 && w2ui[subgrid.attr('name')]) { + obj.selectNone(); + var grid = subgrid.attr('name'); + var recs = w2ui[grid].records; + w2utils.keyboard.active(grid); + w2ui[grid].click(recs[0].recid); + cancel = true; + break; + } + } + // move to the next record + var next = obj.nextRow(ind2); + if (next != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return; + if (obj.selectType == 'row') { + if (this.last.sel_ind < next && this.last.sel_ind != ind) { + obj.unselect(obj.records[ind].recid); + } else { + obj.select(obj.records[next].recid); + } + } else { + if (this.last.sel_ind < next && this.last.sel_ind != ind) { + next = ind; + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); + obj.unselect.apply(obj, tmp); + } else { + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); + obj.select.apply(obj, tmp); + } + } + } else { // move selected record + obj.selectNone(); + obj.click({ recid: obj.records[next].recid, column: columns[0] }, event); + } + obj.scrollIntoView(next); + cancel = true; + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=0; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var recid = parent.next().attr('recid'); + var grid = parent.parents('.w2ui-grid').attr('name'); + obj.selectNone(); + w2utils.keyboard.active(grid); + w2ui[grid].click(recid); + cancel = true; + break; + } + } + break; + + case 86: // v - paste + if (empty) break; + if (event.ctrlKey || event.metaKey) { + $('body').append(''); + $('#_tmp_copy_data').focus(); + setTimeout(function () { + obj.paste($('#_tmp_copy_data').val()); + $('#_tmp_copy_data').remove(); + }, 50); // need timer to allow paste + } + break; + + case 88: // x - cut + if (empty) break; + if (event.ctrlKey || event.metaKey) { + setTimeout(function () { obj.delete(true); }, 100); + } + case 67: // c - copy + if (empty) break; + if (event.ctrlKey || event.metaKey) { + var text = obj.copy(); + $('body').append(''); + $('#_tmp_copy_data').focus().select(); + setTimeout(function () { $('#_tmp_copy_data').remove(); }, 50); + } + break; + } + var tmp = [187, 189, 32]; // =-spacebar + for (var i=48; i<=90; i++) tmp.push(i); // 0-9,a-z,A-Z + if (tmp.indexOf(key) != -1 && !event.ctrlKey && !event.metaKey && !cancel) { + if (columns.length == 0) columns.push(0); + var tmp = String.fromCharCode(key); + if (key == 187) tmp = '='; + if (key == 189) tmp = '-'; + if (!shiftKey) tmp = tmp.toLowerCase(); + obj.editField(recid, columns[0], tmp, event); + cancel = true; + } + if (cancel) { // cancel default behaviour + if (event.preventDefault) event.preventDefault(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + + function selectTopRecord() { + var ind = Math.floor((records[0].scrollTop + (records.height() / 2.1)) / obj.recordHeight); + if (!obj.records[ind]) ind = 0; + obj.select({ recid: obj.records[ind].recid, column: 0}); + } + + function tmpUnselect () { + if (obj.last.sel_type != 'click') return false; + if (obj.selectType != 'row') { + obj.last.sel_type = 'key'; + if (sel.length > 1) { + for (var s in sel) { + if (sel[s].recid == obj.last.sel_recid && sel[s].column == obj.last.sel_col) { + sel.splice(s, 1); + break; + } + } + obj.unselect.apply(obj, sel); + return true; + } + return false; + } else { + obj.last.sel_type = 'key'; + if (sel.length > 1) { + sel.splice(sel.indexOf(obj.records[obj.last.sel_ind].recid), 1); + obj.unselect.apply(obj, sel); + return true; + } + return false; + } + } + }, + + scrollIntoView: function (ind) { + if (typeof ind == 'undefined') { + var sel = this.getSelection(); + if (sel.length == 0) return; + ind = this.get(sel[0], true); + } + var records = $('#grid_'+ this.name +'_records'); + if (records.length == 0) return; + // if all records in view + var len = this.last.searchIds.length; + if (records.height() > this.recordHeight * (len > 0 ? len : this.records.length)) return; + if (len > 0) ind = this.last.searchIds.indexOf(ind); // if seach is applied + // scroll to correct one + var t1 = Math.floor(records[0].scrollTop / this.recordHeight); + var t2 = t1 + Math.floor(records.height() / this.recordHeight); + if (ind == t1) records.animate({ 'scrollTop': records.scrollTop() - records.height() / 1.3 }, 250, 'linear'); + if (ind == t2) records.animate({ 'scrollTop': records.scrollTop() + records.height() / 1.3 }, 250, 'linear'); + if (ind < t1 || ind > t2) records.animate({ 'scrollTop': (ind - 1) * this.recordHeight }); + }, + + dblClick: function (recid, event) { + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // find columns + var column = null; + if (typeof recid == 'object') { + column = recid.column; + recid = recid.recid; + } + if (typeof event == 'undefined') event = {}; + // column user clicked on + if (column == null && event.target) { + var tmp = event.target; + if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; + column = parseInt($(tmp).attr('col')); + } + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'dblClick', recid: recid, column: column, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + this.selectNone(); + var col = this.columns[column]; + if (col && $.isPlainObject(col.editable)) { + this.editField(recid, column, null, event); + } else { + this.select({ recid: recid, column: column }); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + contextMenu: function (recid, event) { + var obj = this; + if (typeof event.offsetX === 'undefined') { + event.offsetX = event.layerX - event.target.offsetLeft; + event.offsetY = event.layerY - event.target.offsetTop; + } + if (w2utils.isFloat(recid)) recid = parseFloat(recid); + if (this.getSelection().indexOf(recid) == -1) obj.click(recid); + // need timeout to allow click to finish first + setTimeout(function () { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: obj.name, originalEvent: event, recid: recid }); + if (eventData.isCancelled === true) return; + // default action + if (obj.menu.length > 0) { + $(obj.box).find(event.target) + .w2menu(obj.menu, { + left : event.offsetX, + onSelect: function (event) { + obj.menuClick(recid, parseInt(event.index), event.originalEvent); + } + } + ); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 150); // need timer 150 for FF + }, + + menuClick: function (recid, index, event) { + var obj = this; + // event before + var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: obj.name, originalEvent: event, + recid: recid, menuIndex: index, menuItem: obj.menu[index] }); + if (eventData.isCancelled === true) return; + // default action + // -- empty + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + toggle: function (recid) { + var rec = this.get(recid); + if (rec.expanded === true) return this.collapse(recid); else return this.expand(recid); + }, + + expand: function (recid) { + var rec = this.get(recid); + var obj = this; + var id = w2utils.escapeId(recid); + if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length > 0) return false; + if (rec.expanded == 'none') return false; + // insert expand row + var tmp = 1 + (this.show.selectColumn ? 1 : 0); + var addClass = ''; // ($('#grid_'+this.name +'_rec_'+ w2utils.escapeId(recid)).hasClass('w2ui-odd') ? 'w2ui-odd' : 'w2ui-even'); + $('#grid_'+ this.name +'_rec_'+ id).after( + ''+ + (this.show.lineNumbers ? '' : '') + + '
      '+ + ' '+ + '
      '+ + ' '+ + ''); + // event before + var eventData = this.trigger({ phase: 'before', type: 'expand', target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded', ready: ready }); + if (eventData.isCancelled === true) { + $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove(); + return; + } + // default action + $('#grid_'+ this.name +'_rec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded'); + $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').show(); + $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('
      '); + rec.expanded = true; + // check if height of expanded row > 5 then remove spinner + setTimeout(ready, 300); + function ready() { + var div1 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded'); + var div2 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row .w2ui-expanded1 > div'); + if (div1.height() < 5) return; + div1.css('opacity', 1); + div2.show().css('opacity', 1); + $('#grid_'+ obj.name +'_cell_'+ obj.get(recid, true) +'_expand div').html('-'); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.resizeRecords(); + return true; + }, + + collapse: function (recid) { + var rec = this.get(recid); + var obj = this; + var id = w2utils.escapeId(recid); + if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length == 0) return false; + // event before + var eventData = this.trigger({ phase: 'before', type: 'collapse', target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded' }); + if (eventData.isCancelled === true) return; + // default action + $('#grid_'+ this.name +'_rec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded'); + $('#grid_'+ this.name +'_rec_'+ id +'_expanded').css('opacity', 0); + $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('+'); + setTimeout(function () { + $('#grid_'+ obj.name +'_rec_'+ id +'_expanded').height('0px'); + setTimeout(function () { + $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row').remove(); + delete rec.expanded; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resizeRecords(); + }, 300); + }, 200); + return true; + }, + + sort: function (field, direction, multiField) { // if no params - clears sort + // event before + var eventData = this.trigger({ phase: 'before', type: 'sort', target: this.name, field: field, direction: direction, multiField: multiField }); + if (eventData.isCancelled === true) return; + // check if needed to quit + if (typeof field != 'undefined') { + // default action + var sortIndex = this.sortData.length; + for (var s in this.sortData) { + if (this.sortData[s].field == field) { sortIndex = s; break; } + } + if (typeof direction == 'undefined' || direction == null) { + if (typeof this.sortData[sortIndex] == 'undefined') { + direction = 'asc'; + } else { + switch (String(this.sortData[sortIndex].direction)) { + case 'asc' : direction = 'desc'; break; + case 'desc' : direction = 'asc'; break; + default : direction = 'asc'; break; + } + } + } + if (this.multiSort === false) { this.sortData = []; sortIndex = 0; } + if (multiField != true) { this.sortData = []; sortIndex = 0; } + // set new sort + if (typeof this.sortData[sortIndex] == 'undefined') this.sortData[sortIndex] = {}; + this.sortData[sortIndex].field = field; + this.sortData[sortIndex].direction = direction; + } else { + this.sortData = []; + } + this.selectNone(); + // if local + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(); + if (this.searchData.length > 0) this.localSearch(true); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(); + } else { + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.last.xhr_offset = 0; + this.reload(); + } + }, + + copy: function () { + var sel = this.getSelection(); + if (sel.length == 0) return ''; + var text = ''; + if (typeof sel[0] == 'object') { // cell copy + // find min/max column + var minCol = sel[0].column; + var maxCol = sel[0].column; + var recs = []; + for (var s in sel) { + if (sel[s].column < minCol) minCol = sel[s].column; + if (sel[s].column > maxCol) maxCol = sel[s].column; + if (recs.indexOf(sel[s].index) == -1) recs.push(sel[s].index); + } + recs.sort(); + for (var r in recs) { + var ind = recs[r]; + for (var c = minCol; c <= maxCol; c++) { + var col = this.columns[c]; + if (col.hidden === true) continue; + text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + } + } else { // row copy + for (var s in sel) { + var ind = this.get(sel[s], true); + for (var c in this.columns) { + var col = this.columns[c]; + if (col.hidden === true) continue; + text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + } + } + text = text.substr(0, text.length - 1); + // before event + var eventData = this.trigger({ phase: 'before', type: 'copy', target: this.name, text: text }); + if (eventData.isCancelled === true) return ''; + text = eventData.text; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return text; + }, + + paste: function (text) { + var sel = this.getSelection(); + var ind = this.get(sel[0].recid, true); + var col = sel[0].column; + // before event + var eventData = this.trigger({ phase: 'before', type: 'paste', target: this.name, text: text, index: ind, column: col }); + if (eventData.isCancelled === true) return; + text = eventData.text; + // default action + if (this.selectType == 'row' || sel.length == 0) { + console.log('ERROR: You can paste only if grid.selectType = \'cell\' and when at least one cell selected.'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return; + } + var newSel = []; + var text = text.split('\n'); + for (var t in text) { + var tmp = text[t].split('\t'); + var cnt = 0; + var rec = this.records[ind]; + var cols = []; + for (var dt in tmp) { + if (!this.columns[col + cnt]) continue; + var field = this.columns[col + cnt].field; + rec.changes = rec.changes || {}; + rec.changes[field] = tmp[dt]; + cols.push(col + cnt); + cnt++; + } + for (var c in cols) newSel.push({ recid: rec.recid, column: cols[c] }); + ind++; + } + this.selectNone(); + this.select.apply(this, newSel); + this.refresh(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + // ================================================== + // --- Common functions + + resize: function () { + var obj = this; + var time = (new Date()).getTime(); + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // make sure the box is right + if (!this.box || $(this.box).attr('name') != this.name) return; + // determine new width and height + $(this.box).find('> div') + .css('width', $(this.box).width()) + .css('height', $(this.box).height()); + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; + // resize + obj.resizeBoxes(); + obj.resizeRecords(); + // init editable + // $('#grid_'+ obj.name + '_records .w2ui-editable input').each(function (index, el) { + // var column = obj.columns[$(el).attr('column')]; + // if (column && column.editable) $(el).w2field(column.editable); + // }); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + refreshCell: function (recid, field) { + var index = this.get(recid, true); + var col_ind = this.getColumn(field, true); + var rec = this.records[index]; + var col = this.columns[col_ind]; + var cell = $('#grid_'+ this.name + '_rec_'+ recid +' [col='+ col_ind +']'); + // set cell html and changed flag + cell.html(this.getCellHTML(index, col_ind)); + if (rec.changes && typeof rec.changes[col.field] != 'undefined') { + cell.addClass('w2ui-changed'); + } else { + cell.removeClass('w2ui-changed'); + } + }, + + refreshRow: function (recid) { + var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (tr.length != 0) { + var ind = this.get(recid, true); + var line = tr.attr('line'); + // if it is searched, find index in search array + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.searchData.length > 0 && !url) for (var s in this.last.searchIds) if (this.last.searchIds[s] == ind) ind = s; + $(tr).replaceWith(this.getRecordHTML(ind, line)); + } + + }, + + refresh: function () { + var obj = this; + var time = (new Date()).getTime(); + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.total <= 0 && !url && this.searchData.length == 0) { + this.total = this.records.length; + this.buffered = this.total; + } + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + this.toolbar.disable('w2ui-edit', 'w2ui-delete'); + if (!this.box) return; + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'refresh' }); + if (eventData.isCancelled === true) return; + // -- header + if (this.show.header) { + $('#grid_'+ this.name +'_header').html(this.header +' ').show(); + } else { + $('#grid_'+ this.name +'_header').hide(); + } + // -- toolbar + if (this.show.toolbar) { + // if select-collumn is checked - no toolbar refresh + if (this.toolbar && this.toolbar.get('w2ui-column-on-off') && this.toolbar.get('w2ui-column-on-off').checked) { + // no action + } else { + $('#grid_'+ this.name +'_toolbar').show(); + // refresh toolbar all but search field + if (typeof this.toolbar == 'object') { + var tmp = this.toolbar.items; + for (var t in tmp) { + if (tmp[t].id == 'w2ui-search' || tmp[t].type == 'break') continue; + this.toolbar.refresh(tmp[t].id); + } + } + } + } else { + $('#grid_'+ this.name +'_toolbar').hide(); + } + // -- make sure search is closed + this.searchClose(); + // search placeholder + var el = $('#grid_'+ obj.name +'_search_all'); + if (!this.multiSearch && this.last.field == 'all' && this.searches.length > 0) { + this.last.field = this.searches[0].field; + this.last.caption = this.searches[0].caption; + } + for (var s in this.searches) { + if (this.searches[s].field == this.last.field) this.last.caption = this.searches[s].caption; + } + if (this.last.multi) { + el.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']'); + } else { + el.attr('placeholder', this.last.caption); + } + if (el.val() != this.last.search) { + var val = this.last.search; + var tmp = el.data('w2field'); + if (tmp) val = tmp.format(val); + el.val(val); + } + + // -- separate summary + var tmp = this.find({ summary: true }, true); + if (tmp.length > 0) { + for (var t in tmp) this.summary.push(this.records[tmp[t]]); + for (var t=tmp.length-1; t>=0; t--) this.records.splice(tmp[t], 1); + this.total = this.total - tmp.length; + this.buffered = this.buffered - tmp.length; + } + + // -- body + var bodyHTML = ''; + bodyHTML += '
      '+ + this.getRecordsHTML() + + '
      '+ + '
      '+ + ' '+ this.getColumnsHTML() +'
      '+ + '
      '; // Columns need to be after to be able to overlap + $('#grid_'+ this.name +'_body').html(bodyHTML); + // show summary records + if (this.summary.length > 0) { + $('#grid_'+ this.name +'_summary').html(this.getSummaryHTML()).show(); + } else { + $('#grid_'+ this.name +'_summary').hide(); + } + // -- footer + if (this.show.footer) { + $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()).show(); + } else { + $('#grid_'+ this.name +'_footer').hide(); + } + // show/hide clear search link + if (this.searchData.length > 0) { + $('#grid_'+ this.name +'_searchClear').show(); + } else { + $('#grid_'+ this.name +'_searchClear').hide(); + } + // all selected? + var sel = this.last.selection; + if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { + $('#grid_'+ this.name +'_check_all').prop('checked', true); + } else { + $('#grid_'+ this.name +'_check_all').prop('checked', false); + } + // show number of selected + this.status(); + // collapse all records + var rows = obj.find({ expanded: true }, true); + for (var r in rows) obj.records[rows[r]].expanded = false; + // mark selection + setTimeout(function () { + var str = $.trim($('#grid_'+ obj.name +'_search_all').val()); + if (str != '') $(obj.box).find('.w2ui-grid-data > div').w2marker(str); + }, 50); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + obj.addRange('selection'); + setTimeout(function () { obj.resize(); obj.scroll(); }, 1); // allow to render first + + if ( obj.reorderColumns && !obj.last.columnDrag ) { + obj.last.columnDrag = obj.initColumnDrag(); + } else if ( !obj.reorderColumns && obj.last.columnDrag ) { + obj.last.columnDrag.remove(); + } + + return (new Date()).getTime() - time; + }, + + render: function (box) { + var obj = this; + var time = (new Date()).getTime(); + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (typeof box != 'undefined' && box != null) { + if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid') + .html(''); + } + this.box = box; + } + if (!this.box) return; + if (this.last.sortData == null) this.last.sortData = this.sortData; + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'render', box: box }); + if (eventData.isCancelled === true) return; + // insert Elements + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-grid') + .html('
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + ' '+ + '
      '); + if (this.selectType != 'row') $(this.box).addClass('w2ui-ss'); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // init toolbar + this.initToolbar(); + if (this.toolbar != null) this.toolbar.render($('#grid_'+ this.name +'_toolbar')[0]); + // reinit search_all + if (this.last.field && this.last.field != 'all') { + var sd = this.searchData; + this.initAllField(this.last.field, (sd.length == 1 ? sd[0].value : null)); + } + // init footer + $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()); + // refresh + if (this.url) this.refresh(); // show empty grid (need it) - should it be only for remote data source + this.reload(); + + // init mouse events for mouse selection + $(this.box).on('mousedown', mouseStart); + $(this.box).on('selectstart', function () { return false; }); // fixes chrome cursor bug + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + // attach to resize event + if ($('.w2ui-layout').length == 0) { // if there is layout, it will send a resize event + this.tmp_resize = function (event) { w2ui[obj.name].resize(); } + $(window).off('resize', this.tmp_resize).on('resize', this.tmp_resize); + } + return (new Date()).getTime() - time; + + function mouseStart (event) { + if ($(event.target).parents().hasClass('w2ui-head') || $(event.target).hasClass('w2ui-head')) return; + if (obj.last.move && obj.last.move.type == 'expand') return; + if (!obj.multiSelect) return; + obj.last.move = { + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + recid : $(event.target).parents('tr').attr('recid'), + column : (event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')), + type : 'select', + ghost : false, + start : true + }; + $(document).on('mousemove', mouseMove); + $(document).on('mouseup', mouseStop); + } + + function mouseMove (event) { + var mv = obj.last.move; + if (!mv || mv.type != 'select') return; + mv.divX = (event.screenX - mv.x); + mv.divY = (event.screenY - mv.y); + if (Math.abs(mv.divX) <= 1 && Math.abs(mv.divY) <= 1) return; // only if moved more then 1px + obj.last.cancelClick = true; + if (obj.reorderRows == true) { + if (!mv.ghost) { + var row = $('#grid_'+ obj.name + '_rec_'+ mv.recid); + var tmp = row.parents('table').find('tr:first-child').clone(); + mv.offsetY = event.offsetY; + mv.from = mv.recid; + mv.pos = row.position(); + mv.ghost = $(row).clone(true); + mv.ghost.removeAttr('id'); + row.find('td:first-child').replaceWith(''); + var recs = $(obj.box).find('.w2ui-grid-records'); + recs.append('
      '); + $('#grid_'+ obj.name + '_ghost').append(tmp).append(mv.ghost); + } + var recid = $(event.target).parents('tr').attr('recid'); + if (recid != mv.from) { + var row1 = $('#grid_'+ obj.name + '_rec_'+ mv.recid); + var row2 = $('#grid_'+ obj.name + '_rec_'+ recid); + if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); + mv.lastY = event.screenY; + mv.to = recid; + } + var ghost = $('#grid_'+ obj.name + '_ghost'); + var recs = $(obj.box).find('.w2ui-grid-records'); + ghost.css({ + top : mv.pos.top + mv.divY + recs.scrollTop(), // + mv.offsetY - obj.recordHeight / 2, + left : mv.pos.left + }); + return; + } + if (mv.start && mv.recid) { + obj.selectNone(); + mv.start = false; + } + var newSel= []; + var recid = (event.target.tagName == 'TR' ? $(event.target).attr('recid') : $(event.target).parents('tr').attr('recid')); + if (typeof recid == 'undefined') return; + var ind1 = obj.get(mv.recid, true); + // |:wolfmanx:| this happens when selection is started on summary row + if (ind1 === null) return; + var ind2 = obj.get(recid, true); + // this happens when selection is extended into summary row (a good place to implement scrolling) + if (ind2 === null) return; + var col1 = parseInt(mv.column); + var col2 = parseInt(event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')); + if (ind1 > ind2) { var tmp = ind1; ind1 = ind2; ind2 = tmp; } + // check if need to refresh + var tmp = 'ind1:'+ ind1 +',ind2;'+ ind2 +',col1:'+ col1 +',col2:'+ col2; + if (mv.range == tmp) return; + mv.range = tmp; + for (var i = ind1; i <= ind2; i++) { + if (obj.last.searchIds.length > 0 && obj.last.searchIds.indexOf(i) == -1) continue; + if (obj.selectType != 'row') { + if (col1 > col2) { var tmp = col1; col1 = col2; col2 = tmp; } + var tmp = []; + for (var c = col1; c <= col2; c++) { + if (obj.columns[c].hidden) continue; + newSel.push({ recid: obj.records[i].recid, column: parseInt(c) }); + } + } else { + newSel.push(obj.records[i].recid); + } + } + if (obj.selectType != 'row') { + var sel = obj.getSelection(); + // add more items + var tmp = []; + for (var ns in newSel) { + var flag = false; + for (var s in sel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; + if (!flag) tmp.push({ recid: newSel[ns].recid, column: newSel[ns].column }); + } + obj.select.apply(obj, tmp); + // remove items + var tmp = []; + for (var s in sel) { + var flag = false; + for (var ns in newSel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; + if (!flag) tmp.push({ recid: sel[s].recid, column: sel[s].column }); + } + obj.unselect.apply(obj, tmp); + } else { + if (obj.multiSelect) { + var sel = obj.getSelection(); + for (var ns in newSel) if (sel.indexOf(newSel[ns]) == -1) obj.select(newSel[ns]); // add more items + for (var s in sel) if (newSel.indexOf(sel[s]) == -1) obj.unselect(sel[s]); // remove items + } + } + } + + function mouseStop (event) { + var mv = obj.last.move; + setTimeout(function () { delete obj.last.cancelClick; }, 1); + if ($(event.target).parents().hasClass('.w2ui-head') || $(event.target).hasClass('.w2ui-head')) return; + if (!mv || mv.type != 'select') return; + if (obj.reorderRows == true) { + var ind1 = obj.get(mv.from, true); + var tmp = obj.records[ind1]; + obj.records.splice(ind1, 1); + var ind2 = obj.get(mv.to, true); + if (ind1 > ind2) obj.records.splice(ind2, 0, tmp); else obj.records.splice(ind2+1, 0, tmp); + $('#grid_'+ obj.name + '_ghost').remove(); + obj.refresh(); + } + delete obj.last.move; + $(document).off('mousemove', mouseMove); + $(document).off('mouseup', mouseStop); + } + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'destroy' }); + if (eventData.isCancelled === true) return; + // remove events + $(window).off('resize', this.tmp_resize); + // clean up + if (typeof this.toolbar == 'object' && this.toolbar.destroy) this.toolbar.destroy(); + if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + // =========================================== + // --- Internal Functions + + initColumnOnOff: function () { + if (!this.show.toolbarColumns) return; + var obj = this; + var col_html = '
      '+ + ''; + for (var c in this.columns) { + var col = this.columns[c]; + var tmp = this.columns[c].caption; + if (!tmp && this.columns[c].hint) tmp = this.columns[c].hint; + if (!tmp) tmp = '- column '+ (parseInt(c) + 1) +' -'; + col_html += ''+ + ''+ + ''+ + ''; + } + col_html += ''; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + col_html += + ''; + } + col_html += ''+ + ''; + col_html += "
      '+ + ' '+ + ''+ + ' '+ + '
      '+ + '
      '+ w2utils.lang('Skip') + + ' '+ w2utils.lang('Records')+ + '
      '+ + '
      '+ + '
      '+ w2utils.lang('Toggle Line Numbers') +'
      '+ + '
      '+ + '
      '+ w2utils.lang('Reset Column Size') + '
      '+ + '
      "; + this.toolbar.get('w2ui-column-on-off').html = col_html; + }, + + /** + * + * @param box, grid object + * @returns {{remove: Function}} contains a closure around all events to ensure they are removed from the dom + */ + initColumnDrag: function( box ){ + //throw error if using column groups + if ( this.columnGroups && this.columnGroups.length ) throw 'Draggable columns are not currently supported with column groups.'; + + var obj = this, + _dragData = {}; + _dragData.lastInt = null; + _dragData.pressed = false; + _dragData.timeout = null;_dragData.columnHead = null; + + //attach orginal event listener + $( obj.box).on( 'mousedown', dragColStart ); + $( obj.box ).on( 'mouseup', catchMouseup ); + + function catchMouseup(){ + _dragData.pressed = false; + clearTimeout( _dragData.timeout ); + } + /** + * + * @param event, mousedown + * @returns {boolean} false, preventsDefault + */ + function dragColStart ( event ) { + if ( _dragData.timeout ) clearTimeout( _dragData.timeout ); + var self = this; + _dragData.pressed = true; + + _dragData.timeout = setTimeout(function(){ + if ( !_dragData.pressed ) return; + + var eventData, + columns, + selectedCol, + origColumn, + origColumnNumber, + invalidPreColumns = [ 'w2ui-col-number', 'w2ui-col-expand', 'w2ui-col-select' ], + invalidPostColumns = [ 'w2ui-head-last' ], + invalidColumns = invalidPreColumns.concat( invalidPostColumns ), + preColumnsSelector = '.w2ui-col-number, .w2ui-col-expand, .w2ui-col-select', + preColHeadersSelector = '.w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select'; + + // do nothing if it is not a header + if ( !$( event.originalEvent.target ).parents().hasClass( 'w2ui-head' ) ) return; + + // do nothing if it is an invalid column + for ( var i = 0, l = invalidColumns.length; i < l; i++ ){ + if ( $( event.originalEvent.target ).parents().hasClass( invalidColumns[ i ] ) ) return; + } + + _dragData.numberPreColumnsPresent = $( obj.box ).find( preColHeadersSelector ).length; + + //start event for drag start + _dragData.columnHead = origColumn = $( event.originalEvent.target ).parents( '.w2ui-head' ); + origColumnNumber = parseInt( origColumn.attr( 'col' ), 10); + eventData = obj.trigger({ type: 'columnDragStart', phase: 'before', originalEvent: event, origColumnNumber: origColumnNumber, target: origColumn[0] }); + if ( eventData.isCancelled === true ) return false; + + columns = _dragData.columns = $( obj.box ).find( '.w2ui-head:not(.w2ui-head-last)' ); + + //add events + $( document ).on( 'mouseup', dragColEnd ); + $( document ).on( 'mousemove', dragColOver ); + + _dragData.originalPos = parseInt( $( event.originalEvent.target ).parent( '.w2ui-head' ).attr( 'col' ), 10 ); + //_dragData.columns.css({ overflow: 'visible' }).children( 'div' ).css({ overflow: 'visible' }); + + //configure and style ghost image + _dragData.ghost = $( self ).clone( true ); + + //hide other elements on ghost except the grid body + $( _dragData.ghost ).find( '[col]:not([col="' + _dragData.originalPos + '"]), .w2ui-toolbar, .w2ui-grid-header' ).remove(); + $( _dragData.ghost ).find( preColumnsSelector ).remove(); + $( _dragData.ghost ).find( '.w2ui-grid-body' ).css({ top: 0 }); + + selectedCol = $( _dragData.ghost ).find( '[col="' + _dragData.originalPos + '"]' ); + $( document.body ).append( _dragData.ghost ); + + $( _dragData.ghost ).css({ + width: 0, + height: 0, + margin: 0, + position: 'fixed', + zIndex: 999999, + opacity: 0 + }).addClass( '.w2ui-grid-ghost' ).animate({ + width: selectedCol.width(), + height: $(obj.box).find('.w2ui-grid-body:first').height(), + left : event.pageX, + top : event.pageY, + opacity: .8 + }, 0 ); + + //establish current offsets + _dragData.offsets = []; + for ( var i = 0, l = columns.length; i < l; i++ ) { + _dragData.offsets.push( $( columns[ i ] ).offset().left ); + } + + //conclude event + obj.trigger( $.extend( eventData, { phase: 'after' } ) ); + }, 150 );//end timeout wrapper + } + + function dragColOver ( event ) { + if ( !_dragData.pressed ) return; + + var cursorX = event.originalEvent.pageX, + cursorY = event.originalEvent.pageY, + offsets = _dragData.offsets, + lastWidth = $( '.w2ui-head:not(.w2ui-head-last)' ).width(); + + _dragData.targetInt = targetIntersection( cursorX, offsets, lastWidth ); + markIntersection( _dragData.targetInt ); + trackGhost( cursorX, cursorY ); + } + + function dragColEnd ( event ) { + _dragData.pressed = false; + + var eventData, + target, + selected, + columnConfig, + columnNum, + targetColumn, + ghosts = $( '.w2ui-grid-ghost' ); + + //start event for drag start + eventData = obj.trigger({ type: 'columnDragEnd', phase: 'before', originalEvent: event, target: _dragData.columnHead[0] }); + if ( eventData.isCancelled === true ) return false; + + selected = obj.columns[ _dragData.originalPos ]; + columnConfig = obj.columns; + columnNum = ( _dragData.targetInt >= obj.columns.length ) ? obj.columns.length - 1 : + ( _dragData.targetInt < _dragData.originalPos ) ? _dragData.targetInt : _dragData.targetInt - 1; + target = ( _dragData.numberPreColumnsPresent ) ? + ( _dragData.targetInt - _dragData.numberPreColumnsPresent < 0 ) ? 0 : _dragData.targetInt - _dragData.numberPreColumnsPresent : + _dragData.targetInt; + targetColumn = $( '.w2ui-head[col="' + columnNum + '"]' ); + + if ( target !== _dragData.originalPos + 1 && target !== _dragData.originalPos && targetColumn && targetColumn.length ) { + $( _dragData.ghost ).animate({ + top: $( obj.box ).offset().top, + left: targetColumn.offset().left, + width: 0, + height: 0, + opacity:.2 + }, 300, function(){ + $( this ).remove(); + ghosts.remove(); + }); + + columnConfig.splice( target, 0, $.extend( {}, selected ) ); + columnConfig.splice( columnConfig.indexOf( selected ), 1); + } else { + $( _dragData.ghost ).remove(); + ghosts.remove(); + } + + //_dragData.columns.css({ overflow: '' }).children( 'div' ).css({ overflow: '' }); + + $( document ).off( 'mouseup', dragColEnd ); + $( document ).off( 'mousemove', dragColOver ); + if ( _dragData.marker ) _dragData.marker.remove(); + _dragData = {}; + + obj.refresh(); + + //conclude event + obj.trigger( $.extend( eventData, { phase: 'after', targetColumnNumber: target - 1 } ) ); + } + + function markIntersection( intersection ){ + if ( !_dragData.marker && !_dragData.markerLeft ) { + _dragData.marker = $('
      ' + + '
      ' + + '
      ' + + '
      '); + _dragData.markerLeft = $('
      ' + + '
      ' + + '
      ' + + '
      '); + } + + if ( !_dragData.lastInt || _dragData.lastInt !== intersection ){ + _dragData.lastInt = intersection; + _dragData.marker.remove(); + _dragData.markerLeft.remove(); + $('.w2ui-head').removeClass('w2ui-col-intersection'); + + //if the current intersection is greater than the number of columns add the marker to the end of the last column only + if ( intersection >= _dragData.columns.length ) { + $( _dragData.columns[ _dragData.columns.length - 1 ] ).children( 'div:last' ).append( _dragData.marker.addClass( 'right' ).removeClass( 'left' ) ); + $( _dragData.columns[ _dragData.columns.length - 1 ] ).addClass('w2ui-col-intersection'); + } else if ( intersection <= _dragData.numberPreColumnsPresent ) { + //if the current intersection is on the column numbers place marker on first available column only + $( '.w2ui-head[col="0"]' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ).css({ position: 'relative' }); + $( '.w2ui-head[col="0"]').prev().addClass('w2ui-col-intersection'); + } else { + //otherwise prepend the marker to the targeted column and append it to the previous column + $( _dragData.columns[intersection] ).children( 'div:last' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ); + $( _dragData.columns[intersection] ).prev().children( 'div:last' ).append( _dragData.markerLeft.addClass( 'right' ).removeClass( 'left' ) ).css({ position: 'relative' }); + $( _dragData.columns[intersection - 1] ).addClass('w2ui-col-intersection'); + } + } + } + + function targetIntersection( cursorX, offsets, lastWidth ){ + if ( cursorX <= offsets[0] ) { + return 0; + } else if ( cursorX >= offsets[offsets.length - 1] + lastWidth ) { + return offsets.length; + } else { + for ( var i = 0, l = offsets.length; i < l; i++ ) { + var thisOffset = offsets[ i ]; + var nextOffset = offsets[ i + 1 ] || offsets[ i ] + lastWidth; + var midpoint = ( nextOffset - offsets[ i ]) / 2 + offsets[ i ]; + + if ( cursorX > thisOffset && cursorX <= midpoint ) { + return i; + } else if ( cursorX > midpoint && cursorX <= nextOffset ) { + return i + 1; + } + } + return intersection; + } + } + + function trackGhost( cursorX, cursorY ){ + $( _dragData.ghost ).css({ + left: cursorX - 10, + top: cursorY - 10 + }); + } + + //return an object to remove drag if it has ever been enabled + return { + remove: function(){ + $( obj.box ).off( 'mousedown', dragColStart ); + $( obj.box ).off( 'mouseup', catchMouseup ); + $( obj.box ).find( '.w2ui-head' ).removeAttr( 'draggable' ); + obj.last.columnDrag = false; + } + } + }, + + columnOnOff: function (el, event, field, value) { + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'columnOnOff', checkbox: el, field: field, originalEvent: event }); + if (eventData.isCancelled === true) return; + // regular processing + var obj = this; + // collapse expanded rows + for (var r in this.records) { + if (this.records[r].expanded === true) this.records[r].expanded = false + } + // show/hide + var hide = true; + if (field == 'line-numbers') { + this.show.lineNumbers = !this.show.lineNumbers; + this.refresh(); + } else if (field == 'skip') { + if (!w2utils.isInt(value)) value = 0; + obj.skip(value); + } else if (field == 'resize') { + // restore sizes + for (var c in this.columns) { + if (typeof this.columns[c].sizeOriginal != 'undefined') { + this.columns[c].size = this.columns[c].sizeOriginal; + } + } + this.initResize(); + this.resize(); + } else { + var col = this.getColumn(field); + if (col.hidden) { + $(el).prop('checked', true); + this.showColumn(col.field); + } else { + $(el).prop('checked', false); + this.hideColumn(col.field); + } + hide = false; + } + this.initColumnOnOff(); + if (hide) { + setTimeout(function () { + $().w2overlay('', { name: 'searches-'+ this.name }); + obj.toolbar.uncheck('column-on-off'); + }, 100); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + initToolbar: function () { + // -- if toolbar is true + if (typeof this.toolbar['render'] == 'undefined') { + var tmp_items = this.toolbar.items; + this.toolbar.items = []; + this.toolbar = $().w2toolbar($.extend(true, {}, this.toolbar, { name: this.name +'_toolbar', owner: this })); + + // ============================================= + // ------ Toolbar Generic buttons + + if (this.show.toolbarReload) { + this.toolbar.items.push($.extend(true, {}, this.buttons['reload'])); + } + if (this.show.toolbarColumns) { + this.toolbar.items.push($.extend(true, {}, this.buttons['columns'])); + this.initColumnOnOff(); + } + if (this.show.toolbarReload || this.show.toolbarColumn) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break0' }); + } + if (this.show.toolbarSearch) { + var html = + ''; + this.toolbar.items.push({ type: 'html', id: 'w2ui-search', html: html }); + if (this.multiSearch && this.searches.length > 0) { + this.toolbar.items.push($.extend(true, {}, this.buttons['search-go'])); + } + } + if (this.show.toolbarSearch && (this.show.toolbarAdd || this.show.toolbarEdit || this.show.toolbarDelete || this.show.toolbarSave)) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break1' }); + } + if (this.show.toolbarAdd) { + this.toolbar.items.push($.extend(true, {}, this.buttons['add'])); + } + if (this.show.toolbarEdit) { + this.toolbar.items.push($.extend(true, {}, this.buttons['edit'])); + } + if (this.show.toolbarDelete) { + this.toolbar.items.push($.extend(true, {}, this.buttons['delete'])); + } + if (this.show.toolbarSave) { + if (this.show.toolbarAdd || this.show.toolbarDelete || this.show.toolbarEdit) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break2' }); + } + this.toolbar.items.push($.extend(true, {}, this.buttons['save'])); + } + // add original buttons + for (var i in tmp_items) this.toolbar.items.push(tmp_items[i]); + + // ============================================= + // ------ Toolbar onClick processing + + var obj = this; + this.toolbar.on('click', function (event) { + var eventData = obj.trigger({ phase: 'before', type: 'toolbar', target: event.target, originalEvent: event }); + if (eventData.isCancelled === true) return; + var id = event.target; + switch (id) { + case 'w2ui-reload': + var eventData2 = obj.trigger({ phase: 'before', type: 'reload', target: obj.name }); + if (eventData2.isCancelled === true) return false; + obj.reload(); + obj.trigger($.extend(eventData2, { phase: 'after' })); + break; + case 'w2ui-column-on-off': + for (var c in obj.columns) { + if (obj.columns[c].hidden) { + $("#grid_"+ obj.name +"_column_"+ c + "_check").prop("checked", false); + } else { + $("#grid_"+ obj.name +"_column_"+ c + "_check").prop('checked', true); + } + } + obj.initResize(); + obj.resize(); + break; + case 'w2ui-search-advanced': + var tb = this; + var it = this.get(id); + if (it.checked) { + obj.searchClose(); + setTimeout(function () { tb.uncheck(id); }, 1); + } else { + obj.searchOpen(); + event.originalEvent.stopPropagation(); + function tmp_close() { + if ($('#w2ui-overlay-searches-'+ obj.name).data('keepOpen') === true) return; + tb.uncheck(id); + $(document).off('click', 'body', tmp_close); + } + $(document).on('click', 'body', tmp_close); + } + break; + case 'w2ui-add': + // events + var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'add', recid: null }); + obj.trigger($.extend(eventData, { phase: 'after' })); + break; + case 'w2ui-edit': + var sel = obj.getSelection(); + var recid = null; + if (sel.length == 1) recid = sel[0]; + // events + var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'edit', recid: recid }); + obj.trigger($.extend(eventData, { phase: 'after' })); + break; + case 'w2ui-delete': + obj.delete(); + break; + case 'w2ui-save': + obj.save(); + break; + } + // no default action + obj.trigger($.extend(eventData, { phase: 'after' })); + }); + } + return; + }, + + initResize: function () { + var obj = this; + //if (obj.resizing === true) return; + $(this.box).find('.w2ui-resizer') + .off('click') + .on('click', function (event) { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + }) + .off('mousedown') + .on('mousedown', function (event) { + if (!event) event = window.event; + if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } + obj.resizing = true; + obj.last.tmp = { + x : event.screenX, + y : event.screenY, + gx : event.screenX, + gy : event.screenY, + col : parseInt($(this).attr('name')) + }; + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + // fix sizes + for (var c in obj.columns) { + if (typeof obj.columns[c].sizeOriginal == 'undefined') obj.columns[c].sizeOriginal = obj.columns[c].size; + obj.columns[c].size = obj.columns[c].sizeCalculated; + } + var eventData = { phase: 'before', type: 'columnResize', target: obj.name, column: obj.last.tmp.col, field: obj.columns[obj.last.tmp.col].field }; + eventData = obj.trigger($.extend(eventData, { resizeBy: 0, originalEvent: event })); + // set move event + var mouseMove = function (event) { + if (obj.resizing != true) return; + if (!event) event = window.event; + // event before + eventData = obj.trigger($.extend(eventData, { resizeBy: (event.screenX - obj.last.tmp.gx), originalEvent: event })); + if (eventData.isCancelled === true) { eventData.isCancelled = false; return; } + // default action + obj.last.tmp.x = (event.screenX - obj.last.tmp.x); + obj.last.tmp.y = (event.screenY - obj.last.tmp.y); + obj.columns[obj.last.tmp.col].size = (parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px'; + obj.resizeRecords(); + // reset + obj.last.tmp.x = event.screenX; + obj.last.tmp.y = event.screenY; + } + var mouseUp = function (event) { + delete obj.resizing; + $(document).off('mousemove', 'body'); + $(document).off('mouseup', 'body'); + obj.resizeRecords(); + // event before + obj.trigger($.extend(eventData, { phase: 'after', originalEvent: event })); + } + $(document).on('mousemove', 'body', mouseMove); + $(document).on('mouseup', 'body', mouseUp); + }) + .each(function (index, el) { + var td = $(el).parent(); + $(el).css({ + "height" : '25px', + "margin-left" : (td.width() - 3) + 'px' + }) + }); + }, + + resizeBoxes: function () { + // elements + var main = $(this.box).find('> div'); + var header = $('#grid_'+ this.name +'_header'); + var toolbar = $('#grid_'+ this.name +'_toolbar'); + var summary = $('#grid_'+ this.name +'_summary'); + var footer = $('#grid_'+ this.name +'_footer'); + var body = $('#grid_'+ this.name +'_body'); + var columns = $('#grid_'+ this.name +'_columns'); + var records = $('#grid_'+ this.name +'_records'); + + if (this.show.header) { + header.css({ + top: '0px', + left: '0px', + right: '0px' + }); + } + + if (this.show.toolbar) { + toolbar.css({ + top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + } + if (this.show.footer) { + footer.css({ + bottom: '0px', + left: '0px', + right: '0px' + }); + } + if (this.summary.length > 0) { + summary.css({ + bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + } + body.css({ + top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) ) + 'px', + bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + (this.summary.length > 0 ? w2utils.getSize(summary, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + }, + + resizeRecords: function () { + var obj = this; + // remove empty records + $(this.box).find('.w2ui-empty-record').remove(); + // -- Calculate Column size in PX + var box = $(this.box); + var grid = $(this.box).find('> div'); + var header = $('#grid_'+ this.name +'_header'); + var toolbar = $('#grid_'+ this.name +'_toolbar'); + var summary = $('#grid_'+ this.name +'_summary'); + var footer = $('#grid_'+ this.name +'_footer'); + var body = $('#grid_'+ this.name +'_body'); + var columns = $('#grid_'+ this.name +'_columns'); + var records = $('#grid_'+ this.name +'_records'); + + // body might be expanded by data + if (!this.fixedBody) { + // allow it to render records, then resize + var calculatedHeight = w2utils.getSize(columns, 'height') + + w2utils.getSize($('#grid_'+ obj.name +'_records table'), 'height'); + obj.height = calculatedHeight + + w2utils.getSize(grid, '+height') + + (obj.show.header ? w2utils.getSize(header, 'height') : 0) + + (obj.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + + (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + + (obj.show.footer ? w2utils.getSize(footer, 'height') : 0); + grid.css('height', obj.height); + body.css('height', calculatedHeight); + box.css('height', w2utils.getSize(grid, 'height') + w2utils.getSize(box, '+height')); + } else { + // fixed body height + var calculatedHeight = grid.height() + - (this.show.header ? w2utils.getSize(header, 'height') : 0) + - (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + - (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + - (this.show.footer ? w2utils.getSize(footer, 'height') : 0); + body.css('height', calculatedHeight); + } + + // check overflow + var bodyOverflowX = false; + var bodyOverflowY = false; + if (body.width() < $(records).find('>table').width()) bodyOverflowX = true; + if (body.height() - columns.height() < $(records).find('>table').height() + (bodyOverflowX ? w2utils.scrollBarSize() : 0)) bodyOverflowY = true; + if (!this.fixedBody) { bodyOverflowY = false; bodyOverflowX = false; } + if (bodyOverflowX || bodyOverflowY) { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + "-webkit-overflow-scrolling": "touch", + "overflow-x": (bodyOverflowX ? 'auto' : 'hidden'), + "overflow-y": (bodyOverflowY ? 'auto' : 'hidden') }); + } else { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').hide(); + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + overflow: 'hidden' + }); + if (records.length > 0) { this.last.scrollTop = 0; this.last.scrollLeft = 0; } // if no scrollbars, always show top + } + if (this.show.emptyRecords && !bodyOverflowY) { + var max = Math.floor(records.height() / this.recordHeight) + 1; + if (this.fixedBody) { + for (var di = this.buffered; di <= max; di++) { + var html = ''; + html += ''; + if (this.show.lineNumbers) html += ''; + if (this.show.selectColumn) html += ''; + if (this.show.expandColumn) html += ''; + var j = 0; + while (true && this.columns.length > 0) { + var col = this.columns[j]; + if (col.hidden) { j++; if (typeof this.columns[j] == 'undefined') break; else continue; } + html += ''; + j++; + if (typeof this.columns[j] == 'undefined') break; + } + html += ''; + html += ''; + $('#grid_'+ this.name +'_records > table').append(html); + } + } + } + if (body.length > 0) { + var width_max = parseInt(body.width()) + - (bodyOverflowY ? w2utils.scrollBarSize() : 0) + - (this.show.lineNumbers ? 34 : 0) + - (this.show.selectColumn ? 26 : 0) + - (this.show.expandColumn ? 26 : 0); + var width_box = width_max; + var percent = 0; + // gridMinWidth processiong + var restart = false; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (typeof col.gridMinWidth != 'undefined') { + if (col.gridMinWidth > width_box && col.hidden !== true) { + col.hidden = true; + restart = true; + } + if (col.gridMinWidth < width_box && col.hidden === true) { + col.hidden = false; + restart = true; + } + } + } + if (restart === true) { + this.refresh(); + return; + } + // assign PX column s + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (String(col.size).substr(String(col.size).length-2).toLowerCase() == 'px') { + width_max -= parseFloat(col.size); + this.columns[i].sizeCalculated = col.size; + this.columns[i].sizeType = 'px'; + } else { + percent += parseFloat(col.size); + this.columns[i].sizeType = '%'; + delete col.sizeCorrected; + } + } + // if sum != 100% -- reassign proportionally + if (percent != 100 && percent > 0) { + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (col.sizeType == '%') { + col.sizeCorrected = Math.round(parseFloat(col.size) * 100 * 100 / percent) / 100 + '%'; + } + } + } + // calculate % columns + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (col.sizeType == '%') { + if (typeof this.columns[i].sizeCorrected != 'undefined') { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.sizeCorrected) / 100) - 1 + 'px'; + } else { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.size) / 100) - 1 + 'px'; + } + } + } + } + // fix margin of error that is due percentage calculations + var width_cols = 0; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (typeof col.min == 'undefined') col.min = 20; + if (parseInt(col.sizeCalculated) < parseInt(col.min)) col.sizeCalculated = col.min + 'px'; + if (parseInt(col.sizeCalculated) > parseInt(col.max)) col.sizeCalculated = col.max + 'px'; + width_cols += parseInt(col.sizeCalculated); + } + var width_diff = parseInt(width_box) - parseInt(width_cols); + if (width_diff > 0 && percent > 0) { + var i = 0; + while (true) { + var col = this.columns[i]; + if (typeof col == 'undefined') { i = 0; continue; } + if (col.hidden || col.sizeType == 'px') { i++; continue; } + col.sizeCalculated = (parseInt(col.sizeCalculated) + 1) + 'px'; + width_diff--; + if (width_diff == 0) break; + i++; + } + } else if (width_diff > 0) { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); + } + // resize columns + columns.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { + var ind = $(el).attr('col'); + if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + // last column + if ($(el).hasClass('w2ui-head-last')) { + $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); + } + }); + // if there are column groups - hide first row (needed for sizing) + if (columns.find('> table > tbody > tr').length == 3) { + columns.find('> table > tbody > tr:nth-child(1) td').html('').css({ + 'height' : '0px', + 'border' : '0px', + 'padding': '0px', + 'margin' : '0px' + }); + } + // resize records + records.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { + var ind = $(el).attr('col'); + if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + // last column + if ($(el).hasClass('w2ui-grid-data-last')) { + $(el).css('width', (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); + } + }); + // resize summary + summary.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { + var ind = $(el).attr('col'); + if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + // last column + if ($(el).hasClass('w2ui-grid-data-last')) { + $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); + } + }); + this.initResize(); + this.refreshRanges(); + // apply last scroll if any + if (this.last.scrollTop != '' && records.length > 0) { + columns.prop('scrollLeft', this.last.scrollLeft); + records.prop('scrollTop', this.last.scrollTop); + records.prop('scrollLeft', this.last.scrollLeft); + } + }, + + getSearchesHTML: function () { + var html = ''; + var showBtn = false; + for (var i = 0; i < this.searches.length; i++) { + var s = this.searches[i]; + s.type = String(s.type).toLowerCase(); + if (s.hidden) continue; + var btn = ''; + if (showBtn == false) { + btn = ''+ + ' ' + + ' ' + + ' '+ + ' ' + + ''; + } + html += ''+ + ' '+ + '
      '+ btn +''+ s.caption +''+ operator + + '
      '+ + '
      '; + + switch (s.type) { + case 'text': + case 'alphanumeric': + case 'hex': + case 'list': + case 'combo': + case 'enum': + html += ''; + break; + + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + html += ''+ + ''; + break; + + case 'select': + html += ''; + break; + + } + html += s.outTag + + '
      '+ + '
      '+ + ' '+ + ' '+ + '
      '+ + '
      '; + return html; + }, + + initOperator: function (el, search_ind) { + var obj = this; + var search = obj.searches[search_ind]; + var range = $('#grid_'+ obj.name + '_range_'+ search_ind); + var fld1 = $('#grid_'+ obj.name +'_field_'+ search_ind); + var fld2 = fld1.parent().find('span input'); + if ($(el).val() == 'in') { fld1.w2field('clear'); } else { fld1.w2field(search.type); } + if ($(el).val() == 'between') { range.show(); fld2.w2field(search.type); } else { range.hide(); } + }, + + initSearches: function () { + var obj = this; + // init searches + for (var s in this.searches) { + var search = this.searches[s]; + var sdata = this.getSearchData(search.field); + search.type = String(search.type).toLowerCase(); + if (typeof search.options != 'object') search.options = {}; + // init types + switch (search.type) { + case 'text': + case 'alphanumeric': + $('#grid_'+ this.name +'_operator_'+s).val('begins'); + if (['alphanumeric', 'hex'].indexOf(search.type) != -1) { + $('#grid_'+ this.name +'_field_' + s).w2field(search.type, search.options); + } + break; + + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + if (sdata && sdata.type == 'int' && sdata.operator == 'in') break; + $('#grid_'+ this.name +'_field_'+s).w2field(search.type, search.options); + $('#grid_'+ this.name +'_field2_'+s).w2field(search.type, search.options); + setTimeout(function () { // convert to date if it is number + $('#grid_'+ obj.name +'_field_'+s).keydown(); + $('#grid_'+ obj.name +'_field2_'+s).keydown(); + }, 1); + break; + + case 'hex': + break; + + case 'list': + case 'combo': + case 'enum': + var options = search.options; + if (search.type == 'list') options.selected = {}; + if (search.type == 'enum') options.selected = []; + if (sdata) options.selected = sdata.value; + $('#grid_'+ this.name +'_field_'+s).w2field(search.type, options); + if (search.type == 'combo') { + $('#grid_'+ this.name +'_operator_'+s).val('begins'); + } + break; + + case 'select': + // build options + var options = ''; + for (var i in search.options.items) { + var si = search.options.items[i]; + if ($.isPlainObject(search.options.items[i])) { + var val = si.id; + var txt = si.text; + if (typeof val == 'undefined' && typeof si.value != 'undefined') val = si.value; + if (typeof txt == 'undefined' && typeof si.caption != 'undefined') txt = si.caption; + if (val == null) val = ''; + options += ''; + } else { + options += ''; + } + } + $('#grid_'+ this.name +'_field_'+s).html(options); + break; + } + if (sdata != null) { + if (sdata.type == 'int' && sdata.operator == 'in') { + $('#grid_'+ this.name +'_field_'+ s).w2field('clear').val(sdata.value); + } + $('#grid_'+ this.name +'_operator_'+ s).val(sdata.operator).trigger('change'); + if (!$.isArray(sdata.value)) { + if (typeof sdata.value != 'udefined') $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); + } else { + if (sdata.operator == 'in') { + $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); + } else { + $('#grid_'+ this.name +'_field_'+ s).val(sdata.value[0]).trigger('change'); + $('#grid_'+ this.name +'_field2_'+ s).val(sdata.value[1]).trigger('change'); + } + } + } + } + // add on change event + $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches *[rel=search]').on('keypress', function (evnt) { + if (evnt.keyCode == 13 && (evnt.ctrlKey || evnt.metaKey)) { + obj.search(); + $().w2overlay(); + } + }); + }, + + getColumnsHTML: function () { + var obj = this; + var html = ''; + if (this.show.columnHeaders) { + if (this.columnGroups.length > 0) { + html = getColumns(true) + getGroups() + getColumns(false); + } else { + html = getColumns(true); + } + } + return html; + + function getGroups () { + var html = ''; + // add empty group at the end + if (obj.columnGroups[obj.columnGroups.length-1].caption != '') obj.columnGroups.push({ caption: '' }); + + if (obj.show.lineNumbers) { + html += ''+ + '
       
      '+ + ''; + } + if (obj.show.selectColumn) { + html += ''+ + '
       
      '+ + ''; + } + if (obj.show.expandColumn) { + html += ''+ + '
       
      '+ + ''; + } + var ii = 0; + for (var i=0; i
      '; + } + html += ''+ + resizer + + '
      '+ + '
      '+ + (!col.caption ? ' ' : col.caption) + + '
      '+ + ''; + } else { + html += ''+ + '
      '+ + (!colg.caption ? ' ' : colg.caption) + + '
      '+ + ''; + } + ii += colg.span; + } + html += ''; + return html; + } + + function getColumns (master) { + var html = '', + reorderCols = (obj.reorderColumns && (!obj.columnGroups || !obj.columnGroups.length)) ? ' w2ui-reorder-cols-head ' : ''; + if (obj.show.lineNumbers) { + html += ''+ + '
      #
      '+ + ''; + } + if (obj.show.selectColumn) { + html += ''+ + '
      '+ + ' '+ + '
      '+ + ''; + } + if (obj.show.expandColumn) { + html += ''+ + '
       
      '+ + ''; + } + var ii = 0; + var id = 0; + for (var i=0; i
      '; + } + html += ''+ + resizer + + '
      '+ + '
      '+ + (!col.caption ? ' ' : col.caption) + + '
      '+ + ''; + } + } + html += '
       
      '; + html += ''; + return html; + } + }, + + getRecordsHTML: function () { + // larget number works better with chrome, smaller with FF. + if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; + var records = $('#grid_'+ this.name +'_records'); + var limit = Math.floor(records.height() / this.recordHeight) + this.show_extra + 1; + if (!this.fixedBody) limit = this.buffered; + // always need first record for resizing purposes + var html = '' + this.getRecordHTML(-1, 0); + // first empty row with height + html += ''+ + ' '+ + ''; + for (var i = 0; i < limit; i++) { + html += this.getRecordHTML(i, i+1); + } + html += ''+ + ' '+ + ''+ + ''+ + ' '+ + ''+ + '
      '; + this.last.range_start = 0; + this.last.range_end = limit; + return html; + }, + + getSummaryHTML: function () { + if (this.summary.length == 0) return; + var html = ''; + for (var i = 0; i < this.summary.length; i++) { + html += this.getRecordHTML(i, i+1, true); + } + html += '
      '; + return html; + }, + + scroll: function (event) { + var time = (new Date()).getTime(); + var obj = this; + var records = $('#grid_'+ this.name +'_records'); + if (this.records.length == 0 || records.length == 0 || records.height() == 0) return; + if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; + // need this to enable scrolling when this.limit < then a screen can fit + if (records.height() < this.buffered * this.recordHeight && records.css('overflow-y') == 'hidden') { + if (this.total > 0) this.refresh(); + return; + } + // update footer + var t1 = Math.round(records[0].scrollTop / this.recordHeight + 1); + var t2 = t1 + (Math.round(records.height() / this.recordHeight) - 1); + if (t1 > this.buffered) t1 = this.buffered; + if (t2 > this.buffered) t2 = this.buffered; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + $('#grid_'+ this.name + '_footer .w2ui-footer-right').html(w2utils.formatNumber(this.offset + t1) + '-' + w2utils.formatNumber(this.offset + t2) + ' ' + w2utils.lang('of') + ' ' + w2utils.formatNumber(this.total) + + (url ? ' ('+ w2utils.lang('buffered') + ' '+ w2utils.formatNumber(this.buffered) + (this.offset > 0 ? ', skip ' + w2utils.formatNumber(this.offset) : '') + ')' : '') + ); + // only for local data source, else no extra records loaded + if (!url && (!this.fixedBody || this.total <= 300)) return; + // regular processing + var start = Math.floor(records[0].scrollTop / this.recordHeight) - this.show_extra; + var end = start + Math.floor(records.height() / this.recordHeight) + this.show_extra * 2 + 1; + // var div = start - this.last.range_start; + if (start < 1) start = 1; + if (end > this.total) end = this.total; + var tr1 = records.find('#grid_'+ this.name +'_rec_top'); + var tr2 = records.find('#grid_'+ this.name +'_rec_bottom'); + // if row is expanded + if (String(tr1.next().prop('id')).indexOf('_expanded_row') != -1) tr1.next().remove(); + if (this.total > end && String(tr2.prev().prop('id')).indexOf('_expanded_row') != -1) tr2.prev().remove(); + var first = parseInt(tr1.next().attr('line')); + var last = parseInt(tr2.prev().attr('line')); + //$('#log').html('buffer: '+ this.buffered +' start-end: ' + start + '-'+ end + ' ===> first-last: ' + first + '-' + last); + if (first < start || first == 1 || this.last.pull_refresh) { // scroll down + // console.log('end', end, 'last', last, 'show_extre', this.show_extra, this.last.pull_refresh); + if (end <= last + this.show_extra - 2 && end != this.total) return; + this.last.pull_refresh = false; + // remove from top + while (true) { + var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); + if (tmp.attr('line') == 'bottom') break; + if (parseInt(tmp.attr('line')) < start) tmp.remove(); else break; + } + // add at bottom + var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); + var rec_start = tmp.attr('line'); + if (rec_start == 'top') rec_start = start; + for (var i = parseInt(rec_start) + 1; i <= end; i++) { + if (!this.records[i-1]) continue; + if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; + tr2.before(this.getRecordHTML(i-1, i)); + } + markSearch(); + setTimeout(function() { obj.refreshRanges(); }, 0); + } else { // scroll up + if (start >= first - this.show_extra + 2 && start > 1) return; + // remove from bottom + while (true) { + var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); + if (tmp.attr('line') == 'top') break; + if (parseInt(tmp.attr('line')) > end) tmp.remove(); else break; + } + // add at top + var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); + var rec_start = tmp.attr('line'); + if (rec_start == 'bottom') rec_start = end; + for (var i = parseInt(rec_start) - 1; i >= start; i--) { + if (!this.records[i-1]) continue; + if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; + tr1.after(this.getRecordHTML(i-1, i)); + } + markSearch(); + setTimeout(function() { obj.refreshRanges(); }, 0); + } + // first/last row size + var h1 = (start - 1) * obj.recordHeight; + var h2 = (this.buffered - end) * obj.recordHeight; + if (h2 < 0) h2 = 0; + tr1.css('height', h1 + 'px'); + tr2.css('height', h2 + 'px'); + obj.last.range_start = start; + obj.last.range_end = end; + // load more if needed + var s = Math.floor(records[0].scrollTop / this.recordHeight); + var e = s + Math.floor(records.height() / this.recordHeight); + if (e + 10 > this.buffered && this.last.pull_more !== true && this.buffered < this.total - this.offset) { + if (this.autoLoad === true) { + this.last.pull_more = true; + this.last.xhr_offset += this.limit; + this.request('get-records'); + } else { + var more = $('#grid_'+ this.name +'_rec_more'); + if (more.css('display') == 'none') { + more.show() + .on('click', function () { + obj.last.pull_more = true; + obj.last.xhr_offset += obj.limit; + obj.request('get-records'); + // show spinner the last + $(this).find('td').html('
      '); + }); + } + if (more.find('td').text().indexOf('Load') == -1) { + more.find('td').html('
      '+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
      '); + } + } + } + // check for grid end + if (this.buffered >= this.total - this.offset) $('#grid_'+ this.name +'_rec_more').hide(); + return; + + function markSearch() { + // mark search + if(obj.markSearch === false) return; + clearTimeout(obj.last.marker_timer); + obj.last.marker_timer = setTimeout(function () { + // mark all search strings + var str = []; + for (var s in obj.searchData) { + var tmp = obj.searchData[s]; + if ($.inArray(tmp.value, str) == -1) str.push(tmp.value); + } + if (str.length > 0) $(obj.box).find('.w2ui-grid-data > div').w2marker(str); + }, 50); + } + }, + + getRecordHTML: function (ind, lineNum, summary) { + var rec_html = ''; + var sel = this.last.selection; + var record; + // first record needs for resize purposes + if (ind == -1) { + rec_html += ''; + if (this.show.lineNumbers) rec_html += ''; + if (this.show.selectColumn) rec_html += ''; + if (this.show.expandColumn) rec_html += ''; + for (var i in this.columns) { + if (this.columns[i].hidden) continue; + rec_html += ''; + } + rec_html += ''; + rec_html += ''; + return rec_html; + } + // regular record + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (summary !== true) { + if (this.searchData.length > 0 && !url) { + if (ind >= this.last.searchIds.length) return ''; + ind = this.last.searchIds[ind]; + record = this.records[ind]; + } else { + if (ind >= this.records.length) return ''; + record = this.records[ind]; + } + } else { + if (ind >= this.summary.length) return ''; + record = this.summary[ind]; + } + if (!record) return ''; + var id = w2utils.escapeId(record.recid); + var isRowSelected = false; + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true; + // render TR + rec_html += ''; + if (this.show.lineNumbers) { + rec_html += ''+ + (summary !== true ? '
      '+ lineNum +'
      ' : '') + + ''; + } + if (this.show.selectColumn) { + rec_html += + ''+ + (summary !== true ? + '
      '+ + ' '+ + '
      ' + : + '' ) + + ''; + } + if (this.show.expandColumn) { + var tmp_img = ''; + if (record.expanded === true) tmp_img = '-'; else tmp_img = '+'; + if (record.expanded == 'none') tmp_img = ''; + if (record.expanded == 'spinner') tmp_img = '
      '; + rec_html += + ''+ + (summary !== true ? + '
      '+ + ' '+ tmp_img +'
      ' + : + '' ) + + ''; + } + var col_ind = 0; + while (true) { + var col = this.columns[col_ind]; + if (col.hidden) { col_ind++; if (typeof this.columns[col_ind] == 'undefined') break; else continue; } + var isChanged = !summary && record.changes && typeof record.changes[col.field] != 'undefined'; + var rec_cell = this.getCellHTML(ind, col_ind, summary); + var addStyle = ''; + if (typeof col.render == 'string') { + var tmp = col.render.toLowerCase().split(':'); + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) addStyle += 'text-align: right;'; + } + if (typeof record.style == 'object' && typeof record.style[col_ind] == 'string') { + addStyle += record.style[col_ind] + ';'; + } + var isCellSelected = false; + if (isRowSelected && $.inArray(col_ind, sel.columns[ind]) != -1) isCellSelected = true; + rec_html += ''+ + rec_cell + + ''; + col_ind++; + if (typeof this.columns[col_ind] == 'undefined') break; + } + rec_html += ''; + rec_html += ''; + return rec_html; + }, + + getCellHTML: function (ind, col_ind, summary) { + var col = this.columns[col_ind]; + var record = (summary !== true ? this.records[ind] : this.summary[ind]); + var data = this.getCellValue(ind, col_ind, summary); + var edit = col.editable; + // various renderers + if (typeof col.render != 'undefined') { + if (typeof col.render == 'function') { + data = $.trim(col.render.call(this, record, ind, col_ind)); + if (data.length < 4 || data.substr(0, 4).toLowerCase() != ''; + } + if (typeof col.render == 'object') data = '
      ' + col.render[data] + '
      '; + if (typeof col.render == 'string') { + var tmp = col.render.toLowerCase().split(':'); + var prefix = ''; + var suffix = ''; + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) { + if (typeof tmp[1] == 'undefined' || !w2utils.isInt(tmp[1])) tmp[1] = 0; + if (tmp[1] > 20) tmp[1] = 20; + if (tmp[1] < 0) tmp[1] = 0; + if (['money', 'currency'].indexOf(tmp[0]) != -1) { tmp[1] = w2utils.settings.currencyPrecision; prefix = w2utils.settings.currencyPrefix; suffix = w2utils.settings.currencySuffix } + if (tmp[0] == 'percent') { suffix = '%'; if (tmp[1] !== '0') tmp[1] = 1; } + if (tmp[0] == 'int') { tmp[1] = 0; } + // format + data = '
      ' + (data !== '' ? prefix + w2utils.formatNumber(Number(data).toFixed(tmp[1])) + suffix : '') + '
      '; + } + if (tmp[0] == 'time') { + if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.time_format; + data = '
      ' + prefix + w2utils.formatTime(data, tmp[1] == 'h12' ? 'hh:mi pm': 'h24:min') + suffix + '
      '; + } + if (tmp[0] == 'date') { + if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.date_display; + data = '
      ' + prefix + w2utils.formatDate(data, tmp[1]) + suffix + '
      '; + } + if (tmp[0] == 'age') { + data = '
      ' + prefix + w2utils.age(data) + suffix + '
      '; + } + } + } else { + // if editable checkbox + var addStyle = ''; + if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { + var changeInd = summary ? -(ind + 1) : ind; + addStyle = 'text-align: center'; + data = ''; + } + if (!this.show.recordTitles) { + var data = '
      '+ data +'
      '; + } else { + // title overwrite + var title = String(data).replace(/"/g, "''"); + if (typeof col.title != 'undefined') { + if (typeof col.title == 'function') title = col.title.call(this, record, ind, col_ind); + if (typeof col.title == 'string') title = col.title; + } + var data = '
      '+ data +'
      '; + } + } + if (data == null || typeof data == 'undefined') data = ''; + return data; + }, + + getCellValue: function (ind, col_ind, summary) { + var col = this.columns[col_ind]; + var record = (summary !== true ? this.records[ind] : this.summary[ind]); + var data = this.parseField(record, col.field); + if (record.changes && typeof record.changes[col.field] != 'undefined') data = record.changes[col.field]; + if (data == null || typeof data == 'undefined') data = ''; + return data; + }, + + getFooterHTML: function () { + return '
      '+ + ' '+ + ' '+ + ' '+ + '
      '; + }, + + status: function (msg) { + if (typeof msg != 'undefined') { + $('#grid_'+ this.name +'_footer').find('.w2ui-footer-left').html(msg); + } else { + // show number of selected + var msgLeft = ''; + var sel = this.getSelection(); + if (sel.length > 0) { + msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") + ' ' + w2utils.lang('selected'); + var tmp = sel[0]; + if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column; + if (sel.length == 1) msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' '; + } + $('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft); + // toolbar + if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); + if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); + } + }, + + lock: function (msg, showSpinner) { + var box = $(this.box).find('> div:first-child'); + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(box); + setTimeout(function () { w2utils.lock.apply(window, args); }, 10); + }, + + unlock: function () { + var box = this.box; + setTimeout(function () { w2utils.unlock(box); }, 25); // needed timer so if server fast, it will not flash + }, + + parseField: function (obj, field) { + var val = ''; + try { // need this to make sure no error in fields + val = obj; + var tmp = String(field).split('.'); + for (var i in tmp) { + val = val[tmp[i]]; + } + } catch (event) { + val = ''; + } + return val; + }, + + prepareData: function () { + // loops thru records and prepares date and time objects + for (var r in this.records) { + var rec = this.records[r]; + for (var c in this.columns) { + var column = this.columns[c]; + if (rec[column.field] == null || typeof column.render != 'string') continue; + // number + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { + if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]); + } + // date + if (['date', 'age'].indexOf(column.render) != -1) { + if (!rec[column.field + '_']) { + var dt = rec[column.field]; + if (w2utils.isInt(dt)) dt = parseInt(dt); + rec[column.field + '_'] = new Date(dt); + } + } + // time + if (['time'].indexOf(column.render) != -1) { + if (w2utils.isTime(rec[column.field])) { // if string + var tmp = w2utils.isTime(rec[column.field], true); + var dt = new Date(); + dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0); // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt; + } else { // if date object + var tmp = rec[column.field]; + if (w2utils.isInt(tmp)) tmp = parseInt(tmp); + var tmp = (tmp != null ? new Date(tmp) : new Date()); + var dt = new Date(); + dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0); // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt; + } + } + } + } + }, + + nextCell: function (col_ind, editable) { + var check = col_ind + 1; + if (this.columns.length == check) return false; + if (editable === true) { + var edit = this.columns[check].editable; + if (this.columns[check].hidden || typeof edit == 'undefined' + || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.nextCell(check, editable); + } + return check; + }, + + prevCell: function (col_ind, editable) { + var check = col_ind - 1; + if (check < 0) return false; + if (editable === true) { + var edit = this.columns[check].editable; + if (this.columns[check].hidden || typeof edit == 'undefined' + || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.prevCell(check, editable); + } + return check; + }, + + nextRow: function (ind) { + if ((ind + 1 < this.records.length && this.last.searchIds.length == 0) // if there are more records + || (this.last.searchIds.length > 0 && ind < this.last.searchIds[this.last.searchIds.length-1])) { + ind++; + if (this.last.searchIds.length > 0) { + while (true) { + if ($.inArray(ind, this.last.searchIds) != -1 || ind > this.records.length) break; + ind++; + } + } + return ind; + } else { + return null; + } + }, + + prevRow: function (ind) { + if ((ind > 0 && this.last.searchIds.length == 0) // if there are more records + || (this.last.searchIds.length > 0 && ind > this.last.searchIds[0])) { + ind--; + if (this.last.searchIds.length > 0) { + while (true) { + if ($.inArray(ind, this.last.searchIds) != -1 || ind < 0) break; + ind--; + } + } + return ind; + } else { + return null; + } + } + }; + + $.extend(w2grid.prototype, w2utils.event); + w2obj.grid = w2grid; })(); /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2layout - layout widget -* - $().w2layout - jQuery wrapper -* - Dependencies: jQuery, w2utils, w2toolbar, w2tabs +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2layout - layout widget +* - $().w2layout - jQuery wrapper +* - Dependencies: jQuery, w2utils, w2toolbar, w2tabs * * == NICE TO HAVE == -* - onResize for the panel -* - add more panel title positions (left=rotated, right=rotated, bottom) -* - bug: resizer is visible (and onHover) when panel is hidden. +* - onResize for the panel +* - add more panel title positions (left=rotated, right=rotated, bottom) +* - bug: resizer is visible (and onHover) when panel is hidden. * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - added panel title -* - added panel.maxSize property -* - fixed resize bugs -* - BUG resize problems (resizer flashes, not very snappy, % should stay in percent) -* - added onResizerClick event +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - added panel title +* - added panel.maxSize property +* - fixed resize bugs +* - BUG resize problems (resizer flashes, not very snappy, % should stay in percent) +* - added onResizerClick event * ************************************************************************/ (function () { - var w2layout = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.panels = []; - this.tmp = {}; - - this.padding = 1; // panel padding - this.resizer = 4; // resizer width or height - this.style = ''; - - this.onShow = null; - this.onHide = null; - this.onResizing = null; - this.onResizerClick = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; - - $.extend(true, this, w2obj.layout, options); - }; - - /* @const */ var w2layout_panels = ['top', 'left', 'main', 'preview', 'right', 'bottom']; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2layout = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2layout')) return; - var panels = method.panels || []; - var object = new w2layout(method); - $.extend(object, { handlers: [], panels: [] }); - // add defined panels - for (var p = 0, len = panels.length; p < len; p++) { - object.panels[p] = $.extend(true, {}, w2layout.prototype.panel, panels[p]); - if ($.isPlainObject(object.panels[p].tabs) || $.isArray(object.panels[p].tabs)) initTabs(object, panels[p].type); - if ($.isPlainObject(object.panels[p].toolbar) || $.isArray(object.panels[p].toolbar)) initToolbar(object, panels[p].type); - } - // add all other panels - for (var p1 in w2layout_panels) { - p1 = w2layout_panels[p1]; - if (object.get(p1) !== null) continue; - object.panels.push($.extend(true, {}, w2layout.prototype.panel, { type: p1, hidden: (p1 !== 'main'), size: 50 })); - } - if ($(this).length > 0) { - object.render($(this)[0]); - } - w2ui[object.name] = object; - return object; - - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2layout' ); - } - - function initTabs(object, panel, tabs) { - var pan = object.get(panel); - if (pan !== null && typeof tabs == 'undefined') tabs = pan.tabs; - if (pan === null || tabs === null) return false; - // instanciate tabs - if ($.isArray(tabs)) tabs = { tabs: tabs }; - $().w2destroy(object.name + '_' + panel + '_tabs'); // destroy if existed - pan.tabs = $().w2tabs($.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })); - pan.show.tabs = true; - return true; - } - - function initToolbar(object, panel, toolbar) { - var pan = object.get(panel); - if (pan !== null && typeof toolbar == 'undefined') toolbar = pan.toolbar; - if (pan === null || toolbar === null) return false; - // instanciate toolbar - if ($.isArray(toolbar)) toolbar = { items: toolbar }; - $().w2destroy(object.name + '_' + panel + '_toolbar'); // destroy if existed - pan.toolbar = $().w2toolbar($.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })); - pan.show.toolbar = true; - return true; - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2layout.prototype = { - // default setting for a panel - panel: { - title : '', - type : null, // left, right, top, bottom - size : 100, // width or height depending on panel name - minSize : 20, - maxSize : false, - hidden : false, - resizable : false, - overflow : 'auto', - style : '', - content : '', // can be String or Object with .render(box) method - tabs : null, - toolbar : null, - width : null, // read only - height : null, // read only - show : { - toolbar : false, - tabs : false - }, - onRefresh : null, - onShow : null, - onHide : null - }, - - // alias for content - html: function (panel, data, transition) { - return this.content(panel, data, transition); - }, - - content: function (panel, data, transition) { - var obj = this; - var p = this.get(panel); - // if it is CSS panel - if (panel == 'css') { - $('#layout_'+ obj.name +'_panel_css').html(''); - return true; - } - if (p === null) return false; - if (typeof data == 'undefined' || data === null) { - return p.content; - } else { - if (data instanceof jQuery) { - console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); - return false; - } - var pname = '#layout_'+ this.name + '_panel_'+ p.type; - var current = $(pname + '> .w2ui-panel-content'); - var panelTop = 0; - if (current.length > 0) { - $(pname).scrollTop(0); - panelTop = $(current).position().top; - } - if (p.content === '') { - p.content = data; - this.refresh(panel); - } else { - p.content = data; - if (!p.hidden) { - if (transition !== null && transition !== '' && typeof transition != 'undefined') { - // apply transition - var div1 = $(pname + '> .w2ui-panel-content'); - div1.after('
      '); - var div2 = $(pname + '> .w2ui-panel-content.new-panel'); - div1.css('top', panelTop); - div2.css('top', panelTop); - if (typeof data == 'object') { - data.box = div2[0]; // do not do .render(box); - data.render(); - } else { - div2.html(data); - } - w2utils.transition(div1[0], div2[0], transition, function () { - div1.remove(); - div2.removeClass('new-panel'); - div2.css('overflow', p.overflow); - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - }); - } - } - this.refresh(panel); - } - } - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - return true; - }, - - load: function (panel, url, transition, onLoad) { - var obj = this; - if (panel == 'css') { - $.get(url, function (data, status, xhr) { - obj.content(panel, xhr.responseText); - if (onLoad) onLoad(); - }); - return true; - } - if (this.get(panel) !== null) { - $.get(url, function (data, status, xhr) { - obj.content(panel, xhr.responseText, transition); - if (onLoad) onLoad(); - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - }); - return true; - } - return false; - }, - - sizeTo: function (panel, size) { - var obj = this; - var pan = obj.get(panel); - if (pan === null) return false; - // resize - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s' - }); - setTimeout(function () { - obj.set(panel, { size: size }); - }, 1); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '0s', - '-moz-transition' : '0s', - '-ms-transition' : '0s', - '-o-transition' : '0s' - }); - obj.resize(); - }, 500); - return true; - }, - - show: function (panel, immediate) { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', type: 'show', target: panel, object: this.get(panel), immediate: immediate }); - if (eventData.isCancelled === true) return; - - var p = obj.get(panel); - if (p === null) return false; - p.hidden = false; - if (immediate === true) { - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '1' }); - if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - } else { - if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); - // resize - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s' - }); - setTimeout(function () { obj.resize(); }, 1); - // show - setTimeout(function() { - $('#layout_'+ obj.name +'_panel_'+ panel).css({ 'opacity': '1' }); - }, 250); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '0s', - '-moz-transition' : '0s', - '-ms-transition' : '0s', - '-o-transition' : '0s' - }); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - }, 500); - } - return true; - }, - - hide: function (panel, immediate) { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', type: 'hide', target: panel, object: this.get(panel), immediate: immediate }); - if (eventData.isCancelled === true) return; - - var p = obj.get(panel); - if (p === null) return false; - p.hidden = true; - if (immediate === true) { - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - $('#layout_'+ obj.name +'_resizer_'+panel).hide(); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - } else { - $('#layout_'+ obj.name +'_resizer_'+panel).hide(); - // hide - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s' - }); - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - setTimeout(function () { obj.resize(); }, 1); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '0s', - '-moz-transition' : '0s', - '-ms-transition' : '0s', - '-o-transition' : '0s' - }); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - }, 500); - } - return true; - }, - - toggle: function (panel, immediate) { - var p = this.get(panel); - if (p === null) return false; - if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate); - }, - - set: function (panel, options) { - var obj = this.get(panel, true); - if (obj === null) return false; - $.extend(this.panels[obj], options); - if (typeof options['content'] != 'undefined') this.refresh(panel); // refresh only when content changed - this.resize(); // resize is needed when panel size is changed - return true; - }, - - get: function (panel, returnIndex) { - for (var p in this.panels) { - if (this.panels[p].type == panel) { - if (returnIndex === true) return p; else return this.panels[p]; - } - } - return null; - }, - - el: function (panel) { - var el = $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content'); - if (el.length != 1) return null; - return el[0]; - }, - - hideToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.toolbar = false; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide(); - this.resize(); - }, - - showToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.toolbar = true; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show(); - this.resize(); - }, - - toggleToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel); - }, - - hideTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.tabs = false; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide(); - this.resize(); - }, - - showTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.tabs = true; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show(); - this.resize(); - }, - - toggleTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel); - }, - - render: function (box) { - var obj = this; - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - var time = (new Date()).getTime(); - // event before - var eventData = obj.trigger({ phase: 'before', type: 'render', target: obj.name, box: box }); - if (eventData.isCancelled === true) return; - - if (typeof box != 'undefined' && box !== null) { - if ($(obj.box).find('#layout_'+ obj.name +'_panel_main').length > 0) { - $(obj.box) - .removeAttr('name') - .removeClass('w2ui-layout') - .html(''); - } - obj.box = box; - } - if (!obj.box) return false; - $(obj.box) - .attr('name', obj.name) - .addClass('w2ui-layout') - .html('
      '); - if ($(obj.box).length > 0) $(obj.box)[0].style.cssText += obj.style; - // create all panels - for (var p1 in w2layout_panels) { - p1 = w2layout_panels[p1]; - var pan = obj.get(p1); - var html = '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '; - $(obj.box).find(' > div').append(html); - // tabs are rendered in refresh() - } - $(obj.box).find(' > div') - .append('
      panel.width) { - resize_x = panel.minSize - panel.width; - } - if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { - resize_x = panel.maxSize - panel.width; - } - if (mainPanel.minSize + resize_x > mainPanel.width) { - resize_x = mainPanel.width - mainPanel.minSize; - } - break; - - case 'right': - if (panel.minSize + resize_x > panel.width) { - resize_x = panel.width - panel.minSize; - } - if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { - resize_x = panel.width - panel.maxSize; - } - if (mainPanel.minSize - resize_x > mainPanel.width) { - resize_x = mainPanel.minSize - mainPanel.width; - } - break; - - case 'top': - if (panel.minSize - resize_y > panel.height) { - resize_y = panel.minSize - panel.height; - } - if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { - resize_y = panel.maxSize - panel.height; - } - if (mainPanel.minSize + resize_y > mainPanel.height) { - resize_y = mainPanel.height - mainPanel.minSize; - } - break; - - case 'preview': - case 'bottom': - if (panel.minSize + resize_y > panel.height) { - resize_y = panel.height - panel.minSize; - } - if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { - resize_y = panel.height - panel.maxSize; - } - if (mainPanel.minSize - resize_y > mainPanel.height) { - resize_y = mainPanel.minSize - mainPanel.height; - } - break; - } - tmp.diff_x = resize_x; - tmp.diff_y = resize_y; - - switch (tmp.type) { - case 'top': - case 'preview': - case 'bottom': - tmp.diff_x = 0; - if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px'; - break; - - case 'left': - case 'right': - tmp.diff_y = 0; - if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px'; - break; - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - }, - - refresh: function (panel) { - var obj = this; - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (typeof panel == 'undefined') panel = null; - var time = (new Date()).getTime(); - // event before - var eventData = obj.trigger({ phase: 'before', type: 'refresh', target: (typeof panel != 'undefined' ? panel : obj.name), object: obj.get(panel) }); - if (eventData.isCancelled === true) return; - // obj.unlock(panel); - if (typeof panel == 'string') { - var p = obj.get(panel); - if (p === null) return; - var pname = '#layout_'+ obj.name + '_panel_'+ p.type; - var rname = '#layout_'+ obj.name +'_resizer_'+ p.type; - // apply properties to the panel - $(pname).css({ display: p.hidden ? 'none' : 'block' }); - if (p.resizable) $(rname).show(); else $(rname).hide(); - // insert content - if (typeof p.content == 'object' && typeof p.content.render === 'function') { - p.content.box = $(pname +'> .w2ui-panel-content')[0]; - setTimeout(function () { - // need to remove unnecessary classes - if ($(pname +'> .w2ui-panel-content').length > 0) { - $(pname +'> .w2ui-panel-content') - .removeClass() - .addClass('w2ui-panel-content') - .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; - } - p.content.render(); // do not do .render(box); - }, 1); - } else { - // need to remove unnecessary classes - if ($(pname +'> .w2ui-panel-content').length > 0) { - $(pname +'> .w2ui-panel-content') - .removeClass() - .addClass('w2ui-panel-content') - .html(p.content) - .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; - } - } - // if there are tabs and/or toolbar - render it - var tmp = $(obj.box).find(pname +'> .w2ui-panel-tabs'); - if (p.show.tabs) { - if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs !== null) tmp.w2render(p.tabs); else p.tabs.refresh(); - } else { - tmp.html('').removeClass('w2ui-tabs').hide(); - } - tmp = $(obj.box).find(pname +'> .w2ui-panel-toolbar'); - if (p.show.toolbar) { - if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar !== null) tmp.w2render(p.toolbar); else p.toolbar.refresh(); - } else { - tmp.html('').removeClass('w2ui-toolbar').hide(); - } - // show title - tmp = $(obj.box).find(pname +'> .w2ui-panel-title'); - if (p.title) { - tmp.html(p.title).show(); - } else { - tmp.html('').hide(); - } - } else { - if ($('#layout_'+ obj.name +'_panel_main').length == 0) { - obj.render(); - return; - } - obj.resize(); - // refresh all of them - for (var p1 in this.panels) { obj.refresh(this.panels[p1].type); } - } - obj.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - resize: function () { - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (!this.box) return false; - var time = (new Date()).getTime(); - // event before - var tmp = this.tmp.resize; - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name, - panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); - if (eventData.isCancelled === true) return; - if (this.padding < 0) this.padding = 0; - - // layout itself - var width = parseInt($(this.box).width()); - var height = parseInt($(this.box).height()); - $(this.box).find(' > div').css({ - width : width + 'px', - height : height + 'px' - }); - var obj = this; - // panels - var pmain = this.get('main'); - var pprev = this.get('preview'); - var pleft = this.get('left'); - var pright = this.get('right'); - var ptop = this.get('top'); - var pbottom = this.get('bottom'); - var smain = true; // main always on - var sprev = (pprev !== null && pprev.hidden !== true ? true : false); - var sleft = (pleft !== null && pleft.hidden !== true ? true : false); - var sright = (pright !== null && pright.hidden !== true ? true : false); - var stop = (ptop !== null && ptop.hidden !== true ? true : false); - var sbottom = (pbottom !== null && pbottom.hidden !== true ? true : false); - var l, t, w, h, e; - // calculate % - for (var p in w2layout_panels) { - p = w2layout_panels[p]; - if (p === 'main') continue; - var tmp = this.get(p); - if (!tmp) continue; - var str = String(tmp.size || 0); - if (str.substr(str.length-1) == '%') { - var tmph = height; - if (tmp.type == 'preview') { - tmph = tmph - - (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - - (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); - } - tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100); - } else { - tmp.sizeCalculated = parseInt(tmp.size); - } - tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)); - } - // top if any - if (ptop !== null && ptop.hidden !== true) { - l = 0; - t = 0; - w = width; - h = ptop.sizeCalculated; - $('#layout_'+ this.name +'_panel_top').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - ptop.width = w; - ptop.height = h; - // resizer - if (ptop.resizable) { - t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_top').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'top', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('top', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_top').hide(); - } - // left if any - if (pleft !== null && pleft.hidden !== true) { - l = 0; - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = pleft.sizeCalculated; - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0); - e = $('#layout_'+ this.name +'_panel_left'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pleft.width = w; - pleft.height = h; - // resizer - if (pleft.resizable) { - l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0); - w = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_left').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ew-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'left', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('left', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_left').hide(); - $('#layout_'+ this.name +'_resizer_left').hide(); - } - // right if any - if (pright !== null && pright.hidden !== true) { - l = width - pright.sizeCalculated; - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = pright.sizeCalculated; - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0); - $('#layout_'+ this.name +'_panel_right').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pright.width = w; - pright.height = h; - // resizer - if (pright.resizable) { - l = l - this.padding; - w = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_right').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ew-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'right', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('right', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_right').hide(); - } - // bottom if any - if (pbottom !== null && pbottom.hidden !== true) { - l = 0; - t = height - pbottom.sizeCalculated; - w = width; - h = pbottom.sizeCalculated; - $('#layout_'+ this.name +'_panel_bottom').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pbottom.width = w; - pbottom.height = h; - // resizer - if (pbottom.resizable) { - t = t - (this.padding === 0 ? 0 : this.padding); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_bottom').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'bottom', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('bottom', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_bottom').hide(); - } - // main - always there - l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding: 0); - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - - (sprev ? pprev.sizeCalculated + this.padding : 0); - e = $('#layout_'+ this.name +'_panel_main'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }); - pmain.width = w; - pmain.height = h; - - // preview if any - if (pprev !== null && pprev.hidden !== true) { - l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated; - w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding : 0); - h = pprev.sizeCalculated; - e = $('#layout_'+ this.name +'_panel_preview'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pprev.width = w; - pprev.height = h; - // resizer - if (pprev.resizable) { - t = t - (this.padding === 0 ? 0 : this.padding); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_preview').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'preview', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('preview', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_preview').hide(); - } - - // display tabs and toolbar if needed - for (var p1 in w2layout_panels) { - p1 = w2layout_panels[p1]; - var pan = this.get(p1); - var tmp2 = '#layout_'+ this.name +'_panel_'+ p1 +' > .w2ui-panel-'; - var tabHeight = 0; - if (pan) { - if (pan.title) { - tabHeight += w2utils.getSize($(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - if (pan.show.tabs) { - if (pan.tabs !== null && w2ui[this.name +'_'+ p1 +'_tabs']) w2ui[this.name +'_'+ p1 +'_tabs'].resize(); - tabHeight += w2utils.getSize($(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - if (pan.show.toolbar) { - if (pan.toolbar !== null && w2ui[this.name +'_'+ p1 +'_toolbar']) w2ui[this.name +'_'+ p1 +'_toolbar'].resize(); - tabHeight += w2utils.getSize($(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - } - $(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }); - } - // send resize to all objects - clearTimeout(this._resize_timer); - this._resize_timer = setTimeout(function () { - for (var e in w2ui) { - if (typeof w2ui[e].resize == 'function') { - // sent to all none-layouts - if (w2ui[e].panels == 'undefined') w2ui[e].resize(); - // only send to nested layouts - var parent = $(w2ui[e].box).parents('.w2ui-layout'); - if (parent.length > 0 && parent.attr('name') == obj.name) w2ui[e].resize(); - } - } - }, 100); - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - if (typeof w2ui[this.name] == 'undefined') return false; - // clean up - if ($(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-layout') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - if (this.tmp.events && this.tmp.events.resize) $(window).off('resize', this.tmp.events.resize); - return true; - }, - - lock: function (panel, msg, showSpinner) { - if (w2layout_panels.indexOf(panel) == -1) { - console.log('ERROR: First parameter needs to be the a valid panel name.'); - return; - } - var args = Array.prototype.slice.call(arguments, 0); - args[0] = '#layout_'+ this.name + '_panel_' + panel; - w2utils.lock.apply(window, args); - }, - - unlock: function (panel) { - if (w2layout_panels.indexOf(panel) == -1) { - console.log('ERROR: First parameter needs to be the a valid panel name.'); - return; - } - var nm = '#layout_'+ this.name + '_panel_' + panel; - w2utils.unlock(nm); - } - }; - - $.extend(w2layout.prototype, w2utils.event); - w2obj.layout = w2layout; + var w2layout = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.panels = []; + this.tmp = {}; + + this.padding = 1; // panel padding + this.resizer = 4; // resizer width or height + this.style = ''; + + this.onShow = null; + this.onHide = null; + this.onResizing = null; + this.onResizerClick = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; + + $.extend(true, this, w2obj.layout, options); + }; + + /* @const */ var w2layout_panels = ['top', 'left', 'main', 'preview', 'right', 'bottom']; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2layout = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2layout')) return; + var panels = method.panels || []; + var object = new w2layout(method); + $.extend(object, { handlers: [], panels: [] }); + // add defined panels + for (var p = 0, len = panels.length; p < len; p++) { + object.panels[p] = $.extend(true, {}, w2layout.prototype.panel, panels[p]); + if ($.isPlainObject(object.panels[p].tabs) || $.isArray(object.panels[p].tabs)) initTabs(object, panels[p].type); + if ($.isPlainObject(object.panels[p].toolbar) || $.isArray(object.panels[p].toolbar)) initToolbar(object, panels[p].type); + } + // add all other panels + for (var p1 in w2layout_panels) { + p1 = w2layout_panels[p1]; + if (object.get(p1) !== null) continue; + object.panels.push($.extend(true, {}, w2layout.prototype.panel, { type: p1, hidden: (p1 !== 'main'), size: 50 })); + } + if ($(this).length > 0) { + object.render($(this)[0]); + } + w2ui[object.name] = object; + return object; + + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2layout' ); + } + + function initTabs(object, panel, tabs) { + var pan = object.get(panel); + if (pan !== null && typeof tabs == 'undefined') tabs = pan.tabs; + if (pan === null || tabs === null) return false; + // instanciate tabs + if ($.isArray(tabs)) tabs = { tabs: tabs }; + $().w2destroy(object.name + '_' + panel + '_tabs'); // destroy if existed + pan.tabs = $().w2tabs($.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })); + pan.show.tabs = true; + return true; + } + + function initToolbar(object, panel, toolbar) { + var pan = object.get(panel); + if (pan !== null && typeof toolbar == 'undefined') toolbar = pan.toolbar; + if (pan === null || toolbar === null) return false; + // instanciate toolbar + if ($.isArray(toolbar)) toolbar = { items: toolbar }; + $().w2destroy(object.name + '_' + panel + '_toolbar'); // destroy if existed + pan.toolbar = $().w2toolbar($.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })); + pan.show.toolbar = true; + return true; + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2layout.prototype = { + // default setting for a panel + panel: { + title : '', + type : null, // left, right, top, bottom + size : 100, // width or height depending on panel name + minSize : 20, + maxSize : false, + hidden : false, + resizable : false, + overflow : 'auto', + style : '', + content : '', // can be String or Object with .render(box) method + tabs : null, + toolbar : null, + width : null, // read only + height : null, // read only + show : { + toolbar : false, + tabs : false + }, + onRefresh : null, + onShow : null, + onHide : null + }, + + // alias for content + html: function (panel, data, transition) { + return this.content(panel, data, transition); + }, + + content: function (panel, data, transition) { + var obj = this; + var p = this.get(panel); + // if it is CSS panel + if (panel == 'css') { + $('#layout_'+ obj.name +'_panel_css').html(''); + return true; + } + if (p === null) return false; + if (typeof data == 'undefined' || data === null) { + return p.content; + } else { + if (data instanceof jQuery) { + console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); + return false; + } + var pname = '#layout_'+ this.name + '_panel_'+ p.type; + var current = $(pname + '> .w2ui-panel-content'); + var panelTop = 0; + if (current.length > 0) { + $(pname).scrollTop(0); + panelTop = $(current).position().top; + } + if (p.content === '') { + p.content = data; + this.refresh(panel); + } else { + p.content = data; + if (!p.hidden) { + if (transition !== null && transition !== '' && typeof transition != 'undefined') { + // apply transition + var div1 = $(pname + '> .w2ui-panel-content'); + div1.after('
      '); + var div2 = $(pname + '> .w2ui-panel-content.new-panel'); + div1.css('top', panelTop); + div2.css('top', panelTop); + if (typeof data == 'object') { + data.box = div2[0]; // do not do .render(box); + data.render(); + } else { + div2.html(data); + } + w2utils.transition(div1[0], div2[0], transition, function () { + div1.remove(); + div2.removeClass('new-panel'); + div2.css('overflow', p.overflow); + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + }); + } + } + this.refresh(panel); + } + } + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + return true; + }, + + load: function (panel, url, transition, onLoad) { + var obj = this; + if (panel == 'css') { + $.get(url, function (data, status, xhr) { + obj.content(panel, xhr.responseText); + if (onLoad) onLoad(); + }); + return true; + } + if (this.get(panel) !== null) { + $.get(url, function (data, status, xhr) { + obj.content(panel, xhr.responseText, transition); + if (onLoad) onLoad(); + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + }); + return true; + } + return false; + }, + + sizeTo: function (panel, size) { + var obj = this; + var pan = obj.get(panel); + if (pan === null) return false; + // resize + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s' + }); + setTimeout(function () { + obj.set(panel, { size: size }); + }, 1); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '0s', + '-moz-transition' : '0s', + '-ms-transition' : '0s', + '-o-transition' : '0s' + }); + obj.resize(); + }, 500); + return true; + }, + + show: function (panel, immediate) { + var obj = this; + // event before + var eventData = this.trigger({ phase: 'before', type: 'show', target: panel, object: this.get(panel), immediate: immediate }); + if (eventData.isCancelled === true) return; + + var p = obj.get(panel); + if (p === null) return false; + p.hidden = false; + if (immediate === true) { + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '1' }); + if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + } else { + if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); + // resize + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s' + }); + setTimeout(function () { obj.resize(); }, 1); + // show + setTimeout(function() { + $('#layout_'+ obj.name +'_panel_'+ panel).css({ 'opacity': '1' }); + }, 250); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '0s', + '-moz-transition' : '0s', + '-ms-transition' : '0s', + '-o-transition' : '0s' + }); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + }, 500); + } + return true; + }, + + hide: function (panel, immediate) { + var obj = this; + // event before + var eventData = this.trigger({ phase: 'before', type: 'hide', target: panel, object: this.get(panel), immediate: immediate }); + if (eventData.isCancelled === true) return; + + var p = obj.get(panel); + if (p === null) return false; + p.hidden = true; + if (immediate === true) { + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + $('#layout_'+ obj.name +'_resizer_'+panel).hide(); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + } else { + $('#layout_'+ obj.name +'_resizer_'+panel).hide(); + // hide + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s' + }); + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + setTimeout(function () { obj.resize(); }, 1); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '0s', + '-moz-transition' : '0s', + '-ms-transition' : '0s', + '-o-transition' : '0s' + }); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + }, 500); + } + return true; + }, + + toggle: function (panel, immediate) { + var p = this.get(panel); + if (p === null) return false; + if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate); + }, + + set: function (panel, options) { + var obj = this.get(panel, true); + if (obj === null) return false; + $.extend(this.panels[obj], options); + if (typeof options['content'] != 'undefined') this.refresh(panel); // refresh only when content changed + this.resize(); // resize is needed when panel size is changed + return true; + }, + + get: function (panel, returnIndex) { + for (var p in this.panels) { + if (this.panels[p].type == panel) { + if (returnIndex === true) return p; else return this.panels[p]; + } + } + return null; + }, + + el: function (panel) { + var el = $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content'); + if (el.length != 1) return null; + return el[0]; + }, + + hideToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.toolbar = false; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide(); + this.resize(); + }, + + showToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.toolbar = true; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show(); + this.resize(); + }, + + toggleToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel); + }, + + hideTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.tabs = false; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide(); + this.resize(); + }, + + showTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.tabs = true; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show(); + this.resize(); + }, + + toggleTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel); + }, + + render: function (box) { + var obj = this; + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + var time = (new Date()).getTime(); + // event before + var eventData = obj.trigger({ phase: 'before', type: 'render', target: obj.name, box: box }); + if (eventData.isCancelled === true) return; + + if (typeof box != 'undefined' && box !== null) { + if ($(obj.box).find('#layout_'+ obj.name +'_panel_main').length > 0) { + $(obj.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html(''); + } + obj.box = box; + } + if (!obj.box) return false; + $(obj.box) + .attr('name', obj.name) + .addClass('w2ui-layout') + .html('
      '); + if ($(obj.box).length > 0) $(obj.box)[0].style.cssText += obj.style; + // create all panels + for (var p1 in w2layout_panels) { + p1 = w2layout_panels[p1]; + var pan = obj.get(p1); + var html = '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '; + $(obj.box).find(' > div').append(html); + // tabs are rendered in refresh() + } + $(obj.box).find(' > div') + .append('
      panel.width) { + resize_x = panel.minSize - panel.width; + } + if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { + resize_x = panel.maxSize - panel.width; + } + if (mainPanel.minSize + resize_x > mainPanel.width) { + resize_x = mainPanel.width - mainPanel.minSize; + } + break; + + case 'right': + if (panel.minSize + resize_x > panel.width) { + resize_x = panel.width - panel.minSize; + } + if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { + resize_x = panel.width - panel.maxSize; + } + if (mainPanel.minSize - resize_x > mainPanel.width) { + resize_x = mainPanel.minSize - mainPanel.width; + } + break; + + case 'top': + if (panel.minSize - resize_y > panel.height) { + resize_y = panel.minSize - panel.height; + } + if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { + resize_y = panel.maxSize - panel.height; + } + if (mainPanel.minSize + resize_y > mainPanel.height) { + resize_y = mainPanel.height - mainPanel.minSize; + } + break; + + case 'preview': + case 'bottom': + if (panel.minSize + resize_y > panel.height) { + resize_y = panel.height - panel.minSize; + } + if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { + resize_y = panel.height - panel.maxSize; + } + if (mainPanel.minSize - resize_y > mainPanel.height) { + resize_y = mainPanel.minSize - mainPanel.height; + } + break; + } + tmp.diff_x = resize_x; + tmp.diff_y = resize_y; + + switch (tmp.type) { + case 'top': + case 'preview': + case 'bottom': + tmp.diff_x = 0; + if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px'; + break; + + case 'left': + case 'right': + tmp.diff_y = 0; + if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px'; + break; + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + }, + + refresh: function (panel) { + var obj = this; + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (typeof panel == 'undefined') panel = null; + var time = (new Date()).getTime(); + // event before + var eventData = obj.trigger({ phase: 'before', type: 'refresh', target: (typeof panel != 'undefined' ? panel : obj.name), object: obj.get(panel) }); + if (eventData.isCancelled === true) return; + // obj.unlock(panel); + if (typeof panel == 'string') { + var p = obj.get(panel); + if (p === null) return; + var pname = '#layout_'+ obj.name + '_panel_'+ p.type; + var rname = '#layout_'+ obj.name +'_resizer_'+ p.type; + // apply properties to the panel + $(pname).css({ display: p.hidden ? 'none' : 'block' }); + if (p.resizable) $(rname).show(); else $(rname).hide(); + // insert content + if (typeof p.content == 'object' && typeof p.content.render === 'function') { + p.content.box = $(pname +'> .w2ui-panel-content')[0]; + setTimeout(function () { + // need to remove unnecessary classes + if ($(pname +'> .w2ui-panel-content').length > 0) { + $(pname +'> .w2ui-panel-content') + .removeClass() + .addClass('w2ui-panel-content') + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; + } + p.content.render(); // do not do .render(box); + }, 1); + } else { + // need to remove unnecessary classes + if ($(pname +'> .w2ui-panel-content').length > 0) { + $(pname +'> .w2ui-panel-content') + .removeClass() + .addClass('w2ui-panel-content') + .html(p.content) + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; + } + } + // if there are tabs and/or toolbar - render it + var tmp = $(obj.box).find(pname +'> .w2ui-panel-tabs'); + if (p.show.tabs) { + if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs !== null) tmp.w2render(p.tabs); else p.tabs.refresh(); + } else { + tmp.html('').removeClass('w2ui-tabs').hide(); + } + tmp = $(obj.box).find(pname +'> .w2ui-panel-toolbar'); + if (p.show.toolbar) { + if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar !== null) tmp.w2render(p.toolbar); else p.toolbar.refresh(); + } else { + tmp.html('').removeClass('w2ui-toolbar').hide(); + } + // show title + tmp = $(obj.box).find(pname +'> .w2ui-panel-title'); + if (p.title) { + tmp.html(p.title).show(); + } else { + tmp.html('').hide(); + } + } else { + if ($('#layout_'+ obj.name +'_panel_main').length == 0) { + obj.render(); + return; + } + obj.resize(); + // refresh all of them + for (var p1 in this.panels) { obj.refresh(this.panels[p1].type); } + } + obj.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + resize: function () { + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (!this.box) return false; + var time = (new Date()).getTime(); + // event before + var tmp = this.tmp.resize; + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); + if (eventData.isCancelled === true) return; + if (this.padding < 0) this.padding = 0; + + // layout itself + var width = parseInt($(this.box).width()); + var height = parseInt($(this.box).height()); + $(this.box).find(' > div').css({ + width : width + 'px', + height : height + 'px' + }); + var obj = this; + // panels + var pmain = this.get('main'); + var pprev = this.get('preview'); + var pleft = this.get('left'); + var pright = this.get('right'); + var ptop = this.get('top'); + var pbottom = this.get('bottom'); + var smain = true; // main always on + var sprev = (pprev !== null && pprev.hidden !== true ? true : false); + var sleft = (pleft !== null && pleft.hidden !== true ? true : false); + var sright = (pright !== null && pright.hidden !== true ? true : false); + var stop = (ptop !== null && ptop.hidden !== true ? true : false); + var sbottom = (pbottom !== null && pbottom.hidden !== true ? true : false); + var l, t, w, h, e; + // calculate % + for (var p in w2layout_panels) { + p = w2layout_panels[p]; + if (p === 'main') continue; + var tmp = this.get(p); + if (!tmp) continue; + var str = String(tmp.size || 0); + if (str.substr(str.length-1) == '%') { + var tmph = height; + if (tmp.type == 'preview') { + tmph = tmph - + (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); + } + tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100); + } else { + tmp.sizeCalculated = parseInt(tmp.size); + } + tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)); + } + // top if any + if (ptop !== null && ptop.hidden !== true) { + l = 0; + t = 0; + w = width; + h = ptop.sizeCalculated; + $('#layout_'+ this.name +'_panel_top').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + ptop.width = w; + ptop.height = h; + // resizer + if (ptop.resizable) { + t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_top').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'top', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('top', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_top').hide(); + } + // left if any + if (pleft !== null && pleft.hidden !== true) { + l = 0; + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = pleft.sizeCalculated; + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0); + e = $('#layout_'+ this.name +'_panel_left'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pleft.width = w; + pleft.height = h; + // resizer + if (pleft.resizable) { + l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0); + w = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_left').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'left', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('left', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_left').hide(); + $('#layout_'+ this.name +'_resizer_left').hide(); + } + // right if any + if (pright !== null && pright.hidden !== true) { + l = width - pright.sizeCalculated; + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = pright.sizeCalculated; + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0); + $('#layout_'+ this.name +'_panel_right').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pright.width = w; + pright.height = h; + // resizer + if (pright.resizable) { + l = l - this.padding; + w = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_right').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'right', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('right', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_right').hide(); + } + // bottom if any + if (pbottom !== null && pbottom.hidden !== true) { + l = 0; + t = height - pbottom.sizeCalculated; + w = width; + h = pbottom.sizeCalculated; + $('#layout_'+ this.name +'_panel_bottom').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pbottom.width = w; + pbottom.height = h; + // resizer + if (pbottom.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_bottom').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'bottom', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('bottom', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_bottom').hide(); + } + // main - always there + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding: 0); + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) - + (sprev ? pprev.sizeCalculated + this.padding : 0); + e = $('#layout_'+ this.name +'_panel_main'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }); + pmain.width = w; + pmain.height = h; + + // preview if any + if (pprev !== null && pprev.hidden !== true) { + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); + t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated; + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding : 0); + h = pprev.sizeCalculated; + e = $('#layout_'+ this.name +'_panel_preview'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pprev.width = w; + pprev.height = h; + // resizer + if (pprev.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_preview').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'preview', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('preview', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_preview').hide(); + } + + // display tabs and toolbar if needed + for (var p1 in w2layout_panels) { + p1 = w2layout_panels[p1]; + var pan = this.get(p1); + var tmp2 = '#layout_'+ this.name +'_panel_'+ p1 +' > .w2ui-panel-'; + var tabHeight = 0; + if (pan) { + if (pan.title) { + tabHeight += w2utils.getSize($(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + if (pan.show.tabs) { + if (pan.tabs !== null && w2ui[this.name +'_'+ p1 +'_tabs']) w2ui[this.name +'_'+ p1 +'_tabs'].resize(); + tabHeight += w2utils.getSize($(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + if (pan.show.toolbar) { + if (pan.toolbar !== null && w2ui[this.name +'_'+ p1 +'_toolbar']) w2ui[this.name +'_'+ p1 +'_toolbar'].resize(); + tabHeight += w2utils.getSize($(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + } + $(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }); + } + // send resize to all objects + clearTimeout(this._resize_timer); + this._resize_timer = setTimeout(function () { + for (var e in w2ui) { + if (typeof w2ui[e].resize == 'function') { + // sent to all none-layouts + if (w2ui[e].panels == 'undefined') w2ui[e].resize(); + // only send to nested layouts + var parent = $(w2ui[e].box).parents('.w2ui-layout'); + if (parent.length > 0 && parent.attr('name') == obj.name) w2ui[e].resize(); + } + } + }, 100); + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + if (typeof w2ui[this.name] == 'undefined') return false; + // clean up + if ($(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + if (this.tmp.events && this.tmp.events.resize) $(window).off('resize', this.tmp.events.resize); + return true; + }, + + lock: function (panel, msg, showSpinner) { + if (w2layout_panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.'); + return; + } + var args = Array.prototype.slice.call(arguments, 0); + args[0] = '#layout_'+ this.name + '_panel_' + panel; + w2utils.lock.apply(window, args); + }, + + unlock: function (panel) { + if (w2layout_panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.'); + return; + } + var nm = '#layout_'+ this.name + '_panel_' + panel; + w2utils.unlock(nm); + } + }; + + $.extend(w2layout.prototype, w2utils.event); + w2obj.layout = w2layout; })(); /************************************************************************ * Library: Web 2.0 UI for jQuery (using prototypical inheritance) * - Following objects defined -* - w2popup - popup widget -* - $().w2popup - jQuery wrapper +* - w2popup - popup widget +* - $().w2popup - jQuery wrapper * - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - transition should include title, body and buttons, not just body +* - transition should include title, body and buttons, not just body * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - new: w2popup.status can be ['closed', 'opening', 'open', 'closing', resizing', 'moving'] -* - add lock method() to lock popup content -* - fixed bug with max width/height of message +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - new: w2popup.status can be ['closed', 'opening', 'open', 'closing', resizing', 'moving'] +* - add lock method() to lock popup content +* - fixed bug with max width/height of message * ************************************************************************/ @@ -7617,624 +7617,624 @@ var w2popup = {}; (function () { - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2popup = function(method, options) { - if (typeof method === 'undefined') { - options = {}; - method = 'open'; - } - if ($.isPlainObject(method)) { - options = method; - method = 'open'; - } - method = method.toLowerCase(); - if (method === 'load' && typeof options === 'string') { - options = $.extend({ url: options }, arguments.length > 2 ? arguments[2] : {}); - } - if (method === 'open' && options.url != null) method = 'load'; - options = options || {}; - // load options from markup - var dlgOptions = {}; - if ($(this).length > 0) { - if ($(this).find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { - if ($(this).find('div[rel=title]').length > 0) { - dlgOptions['title'] = $(this).find('div[rel=title]').html(); - } - if ($(this).find('div[rel=body]').length > 0) { - dlgOptions['body'] = $(this).find('div[rel=body]').html(); - dlgOptions['style'] = $(this).find('div[rel=body]')[0].style.cssText; - } - if ($(this).find('div[rel=buttons]').length > 0) { - dlgOptions['buttons'] = $(this).find('div[rel=buttons]').html(); - } - } else { - dlgOptions['title'] = ' '; - dlgOptions['body'] = $(this).html(); - } - if (parseInt($(this).css('width')) != 0) dlgOptions['width'] = parseInt($(this).css('width')); - if (parseInt($(this).css('height')) != 0) dlgOptions['height'] = parseInt($(this).css('height')); - } - // show popup - return w2popup[method]($.extend({}, dlgOptions, options)); - }; - - // ==================================================== - // -- Implementation of core functionality (SINGELTON) - - w2popup = { - defaults: { - title : '', - body : '', - buttons : '', - style : '', - color : '#000', - opacity : 0.4, - speed : 0.3, - modal : false, - maximized : false, - keyboard : true, // will close popup on esc if not modal - width : 500, - height : 300, - showClose : true, - showMax : false, - transition : null - }, - status : 'closed', // string that describes current status - handlers : [], - onOpen : null, - onClose : null, - onMax : null, - onMin : null, - onToggle : null, - onKeydown : null, - - open: function (options) { - var obj = this; - if (w2popup.status == 'closing') { - setTimeout(function () { obj.open.call(obj, options); }, 100); - return; - } - // get old options and merge them - var old_options = $('#w2ui-popup').data('options'); - var options = $.extend({}, this.defaults, { body : '' }, old_options, options, { maximized: false }); - // need timer because popup might not be open - setTimeout(function () { $('#w2ui-popup').data('options', options); }, 100); - // if new - reset event handlers - if ($('#w2ui-popup').length == 0) { - w2popup.handlers = []; - w2popup.onMax = null; - w2popup.onMin = null; - w2popup.onToggle = null; - w2popup.onOpen = null; - w2popup.onClose = null; - w2popup.onKeydown = null; - } - if (options.onOpen) w2popup.onOpen = options.onOpen; - if (options.onClose) w2popup.onClose = options.onClose; - if (options.onMax) w2popup.onMax = options.onMax; - if (options.onMin) w2popup.onMin = options.onMin; - if (options.onToggle) w2popup.onToggle = options.onToggle; - if (options.onKeydown) w2popup.onKeydown = options.onKeydown; - - if (window.innerHeight == undefined) { - var width = document.documentElement.offsetWidth; - var height = document.documentElement.offsetHeight; - if (w2utils.engine === 'IE7') { width += 21; height += 4; } - } else { - var width = window.innerWidth; - var height = window.innerHeight; - } - if (parseInt(width) - 10 < parseInt(options.width)) options.width = parseInt(width) - 10; - if (parseInt(height) - 10 < parseInt(options.height)) options.height = parseInt(height) - 10; - var top = ((parseInt(height) - parseInt(options.height)) / 2) * 0.6; - var left = (parseInt(width) - parseInt(options.width)) / 2; - // check if message is already displayed - if ($('#w2ui-popup').length == 0) { - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: false }); - if (eventData.isCancelled === true) return; - w2popup.status = 'opening'; - // output message - w2popup.lockScreen(options); - var msg = '
      '; - if (options.title != '') { - msg +='
      '+ - (options.showClose ? '
      Close
      ' : '')+ - (options.showMax ? '
      Max
      ' : '') + - options.title + - '
      '; - } - msg += '
      '; - msg += '
      ' + options.body + '
      '; - msg += '
      '; - msg += '
      '; - msg += '
      '; - msg += '
      '; - if (options.buttons != '') { - msg += '
      ' + options.buttons + '
      '; - } - msg += '
      '; - $('body').append(msg); - // allow element to render - setTimeout(function () { - $('#w2ui-popup .w2ui-box2').hide(); - $('#w2ui-popup').css({ - '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', - '-webkit-transform': 'scale(1)', - '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', - '-moz-transform': 'scale(1)', - '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', - '-ms-transform': 'scale(1)', - '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', - '-o-transform': 'scale(1)', - 'opacity': '1' - }); - }, 1); - // clean transform - setTimeout(function () { - $('#w2ui-popup').css({ - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '' - }); - // event after - w2popup.status = 'open'; - setTimeout(function () { - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 100); - }, options.speed * 1000); - } else { - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: true }); - if (eventData.isCancelled === true) return; - // check if size changed - w2popup.status = 'opening'; - if (typeof old_options == 'undefined' || old_options['width'] != options['width'] || old_options['height'] != options['height']) { - w2popup.resize(options.width, options.height); - } - if (typeof old_options != 'undefined') { - options.prevSize = options.width + ':' + options.height; - options.maximized = old_options.maximized; - } - // show new items - var body = $('#w2ui-popup .w2ui-box2 > .w2ui-msg-body').html(options.body); - if (body.length > 0) body[0].style.cssText = options.style; - $('#w2ui-popup .w2ui-msg-buttons').html(options.buttons); - $('#w2ui-popup .w2ui-msg-title').html( - (options.showClose ? '
      Close
      ' : '')+ - (options.showMax ? '
      Max
      ' : '') + - options.title); - // transition - var div_old = $('#w2ui-popup .w2ui-box1')[0]; - var div_new = $('#w2ui-popup .w2ui-box2')[0]; - w2utils.transition(div_old, div_new, options.transition); - div_new.className = 'w2ui-box1'; - div_old.className = 'w2ui-box2'; - $(div_new).addClass('w2ui-current-box'); - // remove max state - $('#w2ui-popup').data('prev-size', null); - // call event onChange - setTimeout(function () { - w2popup.status = 'open'; - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 100); - } - // save new options - options._last_w2ui_name = w2utils.keyboard.active(); - w2utils.keyboard.active(null); - // keyboard events - if (options.keyboard) $(document).on('keydown', this.keydown); - - // initialize move - var tmp = { - resizing: false, - mvMove : mvMove, - mvStop : mvStop - }; - $('#w2ui-popup .w2ui-msg-title').on('mousedown', function (event) { mvStart(event); }) - - // handlers - function mvStart(evnt) { - if (!evnt) evnt = window.event; - if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } - w2popup.status = 'moving'; - tmp.resizing = true; - tmp.x = evnt.screenX; - tmp.y = evnt.screenY; - tmp.pos_x = $('#w2ui-popup').position().left; - tmp.pos_y = $('#w2ui-popup').position().top; - w2popup.lock({ opacity: 0 }); - $(document).on('mousemove', tmp.mvMove); - $(document).on('mouseup', tmp.mvStop); - if (evnt.stopPropagation) evnt.stopPropagation(); else evnt.cancelBubble = true; - if (evnt.preventDefault) evnt.preventDefault(); else return false; - } - - function mvMove(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - tmp.div_x = evnt.screenX - tmp.x; - tmp.div_y = evnt.screenY - tmp.y; - $('#w2ui-popup').css({ - '-webkit-transition': 'none', - '-webkit-transform': 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)', - '-moz-transition': 'none', - '-moz-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', - '-ms-transition': 'none', - '-ms-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', - '-o-transition': 'none', - '-o-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)' - }); - } - - function mvStop(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - w2popup.status = 'open'; - tmp.div_x = (evnt.screenX - tmp.x); - tmp.div_y = (evnt.screenY - tmp.y); - $('#w2ui-popup').css({ - 'left': (tmp.pos_x + tmp.div_x) + 'px', - 'top': (tmp.pos_y + tmp.div_y) + 'px', - '-webkit-transition': 'none', - '-webkit-transform': 'translate3d(0px, 0px, 0px)', - '-moz-transition': 'none', - '-moz-transform': 'translate(0px, 0px)', - '-ms-transition': 'none', - '-ms-transform': 'translate(0px, 0px)', - '-o-transition': 'none', - '-o-transform': 'translate(0px, 0px)', - }); - tmp.resizing = false; - $(document).off('mousemove', tmp.mvMove); - $(document).off('mouseup', tmp.mvStop); - w2popup.unlock(); - } - return this; - }, - - keydown: function (event) { - var options = $('#w2ui-popup').data('options'); - if (!options.keyboard) return; - // trigger event - var eventData = w2popup.trigger({ phase: 'before', type: 'keydown', target: 'popup', options: options, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behavior - switch (event.keyCode) { - case 27: - event.preventDefault(); - if ($('#w2ui-popup .w2ui-popup-message').length > 0) w2popup.message(); else w2popup.close(); - break; - } - // event after - w2popup.trigger($.extend(eventData, { phase: 'after'})); - }, - - close: function (options) { - var obj = this; - var options = $.extend({}, $('#w2ui-popup').data('options'), options); - if ($('#w2ui-popup').length == 0) return; - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'close', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // default behavior - w2popup.status = 'closing'; - $('#w2ui-popup').css({ - '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', - '-webkit-transform': 'scale(0.9)', - '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', - '-moz-transform': 'scale(0.9)', - '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', - '-ms-transform': 'scale(0.9)', - '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', - '-o-transform': 'scale(0.9)', - 'opacity': '0' - }); - w2popup.unlockScreen(options); - setTimeout(function () { - $('#w2ui-popup').remove(); - w2popup.status = 'closed'; - // event after - obj.trigger($.extend(eventData, { phase: 'after'})); - }, options.speed * 1000); - // restore active - w2utils.keyboard.active(options._last_w2ui_name); - // remove keyboard events - if (options.keyboard) $(document).off('keydown', this.keydown); - }, - - toggle: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'toggle', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // defatul action - if (options.maximized === true) w2popup.min(); else w2popup.max(); - // event after - setTimeout(function () { - obj.trigger($.extend(eventData, { phase: 'after'})); - }, 250); - }, - - max: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - if (options.maximized === true) return; - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'max', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // default behavior - w2popup.status = 'resizing'; - options.prevSize = $('#w2ui-popup').css('width')+':'+$('#w2ui-popup').css('height'); - // do resize - w2popup.resize(10000, 10000, function () { - w2popup.status = 'open'; - options.maximized = true; - obj.trigger($.extend(eventData, { phase: 'after'})); - }); - }, - - min: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - if (options.maximized !== true) return; - var size = options.prevSize.split(':'); - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'min', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // default behavior - w2popup.status = 'resizing'; - // do resize - w2popup.resize(size[0], size[1], function () { - w2popup.status = 'open'; - options.maximized = false; - options.prevSize = null; - obj.trigger($.extend(eventData, { phase: 'after'})); - }); - }, - - get: function () { - return $('#w2ui-popup').data('options'); - }, - - set: function (options) { - w2popup.open(options); - }, - - clear: function() { - $('#w2ui-popup .w2ui-msg-title').html(''); - $('#w2ui-popup .w2ui-msg-body').html(''); - $('#w2ui-popup .w2ui-msg-buttons').html(''); - }, - - reset: function () { - w2popup.open(w2popup.defaults); - }, - - load: function (options) { - w2popup.status = 'loading'; - if (String(options.url) == 'undefined') { - console.log('ERROR: The url parameter is empty.'); - return; - } - var tmp = String(options.url).split('#'); - var url = tmp[0]; - var selector = tmp[1]; - if (String(options) == 'undefined') options = {}; - // load url - var html = $('#w2ui-popup').data(url); - if (typeof html != 'undefined' && html != null) { - popup(html, selector); - } else { - $.get(url, function (data, status, obj) { - popup(obj.responseText, selector); - $('#w2ui-popup').data(url, obj.responseText); // remember for possible future purposes - }); - } - function popup(html, selector) { - delete options.url; - $('body').append(''); - if (typeof selector != 'undefined' && $('#w2ui-tmp #'+selector).length > 0) { - $('#w2ui-tmp #' + selector).w2popup(options); - } else { - $('#w2ui-tmp > div').w2popup(options); - } - // link styles - if ($('#w2ui-tmp > style').length > 0) { - var style = $('
      ').append($('#w2ui-tmp > style').clone()).html(); - if ($('#w2ui-popup #div-style').length == 0) { - $('#w2ui-popup').append('
      '); - } - $('#w2ui-popup #div-style').html(style); - } - $('#w2ui-tmp').remove(); - } - }, - - message: function (options) { - $().w2tag(); // hide all tags - if (!options) options = { width: 200, height: 100 }; - if (parseInt(options.width) < 10) options.width = 10; - if (parseInt(options.height) < 10) options.height = 10; - if (typeof options.hideOnClick == 'undefined') options.hideOnClick = false; - var poptions = $('#w2ui-popup').data('options') - if (typeof options.width == 'undefined' || options.width > poptions.width - 10) options.width = poptions.width - 10; - if (typeof options.height == 'undefined' || options.height > poptions.height - 40) options.height = poptions.height - 40; // title is 30px or so - - var head = $('#w2ui-popup .w2ui-msg-title'); - var pwidth = parseInt($('#w2ui-popup').width()); - var msgCount = $('#w2ui-popup .w2ui-popup-message').length; - // remove message - if ($.trim(options.html) == '') { - $('#w2ui-popup #w2ui-message'+ (msgCount-1)).css('z-Index', 250); - var options = $('#w2ui-popup #w2ui-message'+ (msgCount-1)).data('options') || {}; - $('#w2ui-popup #w2ui-message'+ (msgCount-1)).remove(); - if (typeof options.onClose == 'function') options.onClose(); - if (msgCount == 1) { - w2popup.unlock(); - } else { - $('#w2ui-popup #w2ui-message'+ (msgCount-2)).show(); - } - } else { - // hide previous messages - $('#w2ui-popup .w2ui-popup-message').hide(); - // add message - $('#w2ui-popup .w2ui-box1') - .before(''); - $('#w2ui-popup #w2ui-message'+ msgCount).data('options', options); - var display = $('#w2ui-popup #w2ui-message'+ msgCount).css('display'); - $('#w2ui-popup #w2ui-message'+ msgCount).css({ - '-webkit-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), - '-moz-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), - '-ms-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), - '-o-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)') - }); - if (display == 'none') { - $('#w2ui-popup #w2ui-message'+ msgCount).show().html(options.html); - // timer needs to animation - setTimeout(function () { - $('#w2ui-popup #w2ui-message'+ msgCount).css({ - '-webkit-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), - '-moz-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), - '-ms-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), - '-o-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') - }); - }, 1); - // timer for lock - setTimeout(function() { - $('#w2ui-popup #w2ui-message'+ msgCount).css({ - '-webkit-transition': '0s', '-moz-transition': '0s', '-ms-transition': '0s', '-o-transition': '0s', - 'z-Index': 1500 - }); // has to be on top of lock - if (msgCount == 0) w2popup.lock(); - if (typeof options.onOpen == 'function') options.onOpen(); - }, 300); - } - } - }, - - lock: function (msg, showSpinner) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift($('#w2ui-popup')); - w2utils.lock.apply(window, args); - }, - - unlock: function () { - w2utils.unlock($('#w2ui-popup')); - }, - - // --- INTERNAL FUNCTIONS - - lockScreen: function (options) { - if ($('#w2ui-lock').length > 0) return false; - if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); - if (typeof options == 'undefined') options = {}; - options = $.extend({}, w2popup.defaults, options); - // show element - $('body').append('
      '); - // lock screen - setTimeout(function () { - $('#w2ui-lock').css({ - '-webkit-transition': options.speed + 's opacity', - '-moz-transition': options.speed + 's opacity', - '-ms-transition': options.speed + 's opacity', - '-o-transition': options.speed + 's opacity', - 'opacity': options.opacity - }); - }, 1); - // add events - if (options.modal == true) { - $('#w2ui-lock').on('mousedown', function () { - $('#w2ui-lock').css({ - '-webkit-transition': '.1s', - '-moz-transition': '.1s', - '-ms-transition': '.1s', - '-o-transition': '.1s', - 'opacity': '0.6' - }); - // if (window.getSelection) window.getSelection().removeAllRanges(); - }); - $('#w2ui-lock').on('mouseup', function () { - setTimeout(function () { - $('#w2ui-lock').css({ - '-webkit-transition': '.1s', - '-moz-transition': '.1s', - '-ms-transition': '.1s', - '-o-transition': '.1s', - 'opacity': options.opacity - }); - }, 100); - // if (window.getSelection) window.getSelection().removeAllRanges(); - }); - } else { - $('#w2ui-lock').on('mouseup', function () { w2popup.close(); }); - } - return true; - }, - - unlockScreen: function (options) { - if ($('#w2ui-lock').length == 0) return false; - if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); - if (typeof options == 'undefined') options = {}; - options = $.extend({}, w2popup.defaults, options); - $('#w2ui-lock').css({ - '-webkit-transition': options.speed + 's opacity', - '-moz-transition': options.speed + 's opacity', - '-ms-transition': options.speed + 's opacity', - '-o-transition': options.speed + 's opacity', - 'opacity': 0 - }); - setTimeout(function () { - $('#w2ui-lock').remove(); - }, options.speed * 1000); - return true; - }, - - resize: function (width, height, callBack) { - var options = $('#w2ui-popup').data('options'); - // calculate new position - if (parseInt($(window).width()) - 10 < parseInt(width)) width = parseInt($(window).width()) - 10; - if (parseInt($(window).height()) - 10 < parseInt(height)) height = parseInt($(window).height()) - 10; - var top = ((parseInt($(window).height()) - parseInt(height)) / 2) * 0.8; - var left = (parseInt($(window).width()) - parseInt(width)) / 2; - // resize there - $('#w2ui-popup').css({ - '-webkit-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - '-moz-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - '-ms-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - '-o-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - 'top': top, - 'left': left, - 'width': width, - 'height': height - }); - if (typeof callBack == 'function') { - setTimeout(function () { - callBack(); - }, options.speed * 1000); - } - } - } - - // merge in event handling - $.extend(w2popup, w2utils.event); + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2popup = function(method, options) { + if (typeof method === 'undefined') { + options = {}; + method = 'open'; + } + if ($.isPlainObject(method)) { + options = method; + method = 'open'; + } + method = method.toLowerCase(); + if (method === 'load' && typeof options === 'string') { + options = $.extend({ url: options }, arguments.length > 2 ? arguments[2] : {}); + } + if (method === 'open' && options.url != null) method = 'load'; + options = options || {}; + // load options from markup + var dlgOptions = {}; + if ($(this).length > 0) { + if ($(this).find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { + if ($(this).find('div[rel=title]').length > 0) { + dlgOptions['title'] = $(this).find('div[rel=title]').html(); + } + if ($(this).find('div[rel=body]').length > 0) { + dlgOptions['body'] = $(this).find('div[rel=body]').html(); + dlgOptions['style'] = $(this).find('div[rel=body]')[0].style.cssText; + } + if ($(this).find('div[rel=buttons]').length > 0) { + dlgOptions['buttons'] = $(this).find('div[rel=buttons]').html(); + } + } else { + dlgOptions['title'] = ' '; + dlgOptions['body'] = $(this).html(); + } + if (parseInt($(this).css('width')) != 0) dlgOptions['width'] = parseInt($(this).css('width')); + if (parseInt($(this).css('height')) != 0) dlgOptions['height'] = parseInt($(this).css('height')); + } + // show popup + return w2popup[method]($.extend({}, dlgOptions, options)); + }; + + // ==================================================== + // -- Implementation of core functionality (SINGELTON) + + w2popup = { + defaults: { + title : '', + body : '', + buttons : '', + style : '', + color : '#000', + opacity : 0.4, + speed : 0.3, + modal : false, + maximized : false, + keyboard : true, // will close popup on esc if not modal + width : 500, + height : 300, + showClose : true, + showMax : false, + transition: null + }, + status : 'closed', // string that describes current status + handlers : [], + onOpen : null, + onClose : null, + onMax : null, + onMin : null, + onToggle : null, + onKeydown : null, + + open: function (options) { + var obj = this; + if (w2popup.status == 'closing') { + setTimeout(function () { obj.open.call(obj, options); }, 100); + return; + } + // get old options and merge them + var old_options = $('#w2ui-popup').data('options'); + var options = $.extend({}, this.defaults, { body : '' }, old_options, options, { maximized: false }); + // need timer because popup might not be open + setTimeout(function () { $('#w2ui-popup').data('options', options); }, 100); + // if new - reset event handlers + if ($('#w2ui-popup').length == 0) { + w2popup.handlers = []; + w2popup.onMax = null; + w2popup.onMin = null; + w2popup.onToggle = null; + w2popup.onOpen = null; + w2popup.onClose = null; + w2popup.onKeydown = null; + } + if (options.onOpen) w2popup.onOpen = options.onOpen; + if (options.onClose) w2popup.onClose = options.onClose; + if (options.onMax) w2popup.onMax = options.onMax; + if (options.onMin) w2popup.onMin = options.onMin; + if (options.onToggle) w2popup.onToggle = options.onToggle; + if (options.onKeydown) w2popup.onKeydown = options.onKeydown; + + if (window.innerHeight == undefined) { + var width = document.documentElement.offsetWidth; + var height = document.documentElement.offsetHeight; + if (w2utils.engine === 'IE7') { width += 21; height += 4; } + } else { + var width = window.innerWidth; + var height = window.innerHeight; + } + if (parseInt(width) - 10 < parseInt(options.width)) options.width = parseInt(width) - 10; + if (parseInt(height) - 10 < parseInt(options.height)) options.height = parseInt(height) - 10; + var top = ((parseInt(height) - parseInt(options.height)) / 2) * 0.6; + var left = (parseInt(width) - parseInt(options.width)) / 2; + // check if message is already displayed + if ($('#w2ui-popup').length == 0) { + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: false }); + if (eventData.isCancelled === true) return; + w2popup.status = 'opening'; + // output message + w2popup.lockScreen(options); + var msg = '
      '; + if (options.title != '') { + msg +='
      '+ + (options.showClose ? '
      Close
      ' : '')+ + (options.showMax ? '
      Max
      ' : '') + + options.title + + '
      '; + } + msg += '
      '; + msg += '
      ' + options.body + '
      '; + msg += '
      '; + msg += '
      '; + msg += '
      '; + msg += '
      '; + if (options.buttons != '') { + msg += '
      ' + options.buttons + '
      '; + } + msg += '
      '; + $('body').append(msg); + // allow element to render + setTimeout(function () { + $('#w2ui-popup .w2ui-box2').hide(); + $('#w2ui-popup').css({ + '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', + '-webkit-transform': 'scale(1)', + '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', + '-moz-transform': 'scale(1)', + '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', + '-ms-transform': 'scale(1)', + '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', + '-o-transform': 'scale(1)', + 'opacity': '1' + }); + }, 1); + // clean transform + setTimeout(function () { + $('#w2ui-popup').css({ + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '' + }); + // event after + w2popup.status = 'open'; + setTimeout(function () { + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 100); + }, options.speed * 1000); + } else { + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: true }); + if (eventData.isCancelled === true) return; + // check if size changed + w2popup.status = 'opening'; + if (typeof old_options == 'undefined' || old_options['width'] != options['width'] || old_options['height'] != options['height']) { + w2popup.resize(options.width, options.height); + } + if (typeof old_options != 'undefined') { + options.prevSize = options.width + ':' + options.height; + options.maximized = old_options.maximized; + } + // show new items + var body = $('#w2ui-popup .w2ui-box2 > .w2ui-msg-body').html(options.body); + if (body.length > 0) body[0].style.cssText = options.style; + $('#w2ui-popup .w2ui-msg-buttons').html(options.buttons); + $('#w2ui-popup .w2ui-msg-title').html( + (options.showClose ? '
      Close
      ' : '')+ + (options.showMax ? '
      Max
      ' : '') + + options.title); + // transition + var div_old = $('#w2ui-popup .w2ui-box1')[0]; + var div_new = $('#w2ui-popup .w2ui-box2')[0]; + w2utils.transition(div_old, div_new, options.transition); + div_new.className = 'w2ui-box1'; + div_old.className = 'w2ui-box2'; + $(div_new).addClass('w2ui-current-box'); + // remove max state + $('#w2ui-popup').data('prev-size', null); + // call event onChange + setTimeout(function () { + w2popup.status = 'open'; + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 100); + } + // save new options + options._last_w2ui_name = w2utils.keyboard.active(); + w2utils.keyboard.active(null); + // keyboard events + if (options.keyboard) $(document).on('keydown', this.keydown); + + // initialize move + var tmp = { + resizing : false, + mvMove : mvMove, + mvStop : mvStop + }; + $('#w2ui-popup .w2ui-msg-title').on('mousedown', function (event) { mvStart(event); }) + + // handlers + function mvStart(evnt) { + if (!evnt) evnt = window.event; + if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } + w2popup.status = 'moving'; + tmp.resizing = true; + tmp.x = evnt.screenX; + tmp.y = evnt.screenY; + tmp.pos_x = $('#w2ui-popup').position().left; + tmp.pos_y = $('#w2ui-popup').position().top; + w2popup.lock({ opacity: 0 }); + $(document).on('mousemove', tmp.mvMove); + $(document).on('mouseup', tmp.mvStop); + if (evnt.stopPropagation) evnt.stopPropagation(); else evnt.cancelBubble = true; + if (evnt.preventDefault) evnt.preventDefault(); else return false; + } + + function mvMove(evnt) { + if (tmp.resizing != true) return; + if (!evnt) evnt = window.event; + tmp.div_x = evnt.screenX - tmp.x; + tmp.div_y = evnt.screenY - tmp.y; + $('#w2ui-popup').css({ + '-webkit-transition': 'none', + '-webkit-transform': 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)', + '-moz-transition': 'none', + '-moz-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', + '-ms-transition': 'none', + '-ms-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', + '-o-transition': 'none', + '-o-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)' + }); + } + + function mvStop(evnt) { + if (tmp.resizing != true) return; + if (!evnt) evnt = window.event; + w2popup.status = 'open'; + tmp.div_x = (evnt.screenX - tmp.x); + tmp.div_y = (evnt.screenY - tmp.y); + $('#w2ui-popup').css({ + 'left': (tmp.pos_x + tmp.div_x) + 'px', + 'top': (tmp.pos_y + tmp.div_y) + 'px', + '-webkit-transition': 'none', + '-webkit-transform': 'translate3d(0px, 0px, 0px)', + '-moz-transition': 'none', + '-moz-transform': 'translate(0px, 0px)', + '-ms-transition': 'none', + '-ms-transform': 'translate(0px, 0px)', + '-o-transition': 'none', + '-o-transform': 'translate(0px, 0px)', + }); + tmp.resizing = false; + $(document).off('mousemove', tmp.mvMove); + $(document).off('mouseup', tmp.mvStop); + w2popup.unlock(); + } + return this; + }, + + keydown: function (event) { + var options = $('#w2ui-popup').data('options'); + if (!options.keyboard) return; + // trigger event + var eventData = w2popup.trigger({ phase: 'before', type: 'keydown', target: 'popup', options: options, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behavior + switch (event.keyCode) { + case 27: + event.preventDefault(); + if ($('#w2ui-popup .w2ui-popup-message').length > 0) w2popup.message(); else w2popup.close(); + break; + } + // event after + w2popup.trigger($.extend(eventData, { phase: 'after'})); + }, + + close: function (options) { + var obj = this; + var options = $.extend({}, $('#w2ui-popup').data('options'), options); + if ($('#w2ui-popup').length == 0) return; + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'close', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // default behavior + w2popup.status = 'closing'; + $('#w2ui-popup').css({ + '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', + '-webkit-transform': 'scale(0.9)', + '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', + '-moz-transform': 'scale(0.9)', + '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', + '-ms-transform': 'scale(0.9)', + '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', + '-o-transform': 'scale(0.9)', + 'opacity': '0' + }); + w2popup.unlockScreen(options); + setTimeout(function () { + $('#w2ui-popup').remove(); + w2popup.status = 'closed'; + // event after + obj.trigger($.extend(eventData, { phase: 'after'})); + }, options.speed * 1000); + // restore active + w2utils.keyboard.active(options._last_w2ui_name); + // remove keyboard events + if (options.keyboard) $(document).off('keydown', this.keydown); + }, + + toggle: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'toggle', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // defatul action + if (options.maximized === true) w2popup.min(); else w2popup.max(); + // event after + setTimeout(function () { + obj.trigger($.extend(eventData, { phase: 'after'})); + }, 250); + }, + + max: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + if (options.maximized === true) return; + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'max', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // default behavior + w2popup.status = 'resizing'; + options.prevSize = $('#w2ui-popup').css('width')+':'+$('#w2ui-popup').css('height'); + // do resize + w2popup.resize(10000, 10000, function () { + w2popup.status = 'open'; + options.maximized = true; + obj.trigger($.extend(eventData, { phase: 'after'})); + }); + }, + + min: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + if (options.maximized !== true) return; + var size = options.prevSize.split(':'); + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'min', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // default behavior + w2popup.status = 'resizing'; + // do resize + w2popup.resize(size[0], size[1], function () { + w2popup.status = 'open'; + options.maximized = false; + options.prevSize = null; + obj.trigger($.extend(eventData, { phase: 'after'})); + }); + }, + + get: function () { + return $('#w2ui-popup').data('options'); + }, + + set: function (options) { + w2popup.open(options); + }, + + clear: function() { + $('#w2ui-popup .w2ui-msg-title').html(''); + $('#w2ui-popup .w2ui-msg-body').html(''); + $('#w2ui-popup .w2ui-msg-buttons').html(''); + }, + + reset: function () { + w2popup.open(w2popup.defaults); + }, + + load: function (options) { + w2popup.status = 'loading'; + if (String(options.url) == 'undefined') { + console.log('ERROR: The url parameter is empty.'); + return; + } + var tmp = String(options.url).split('#'); + var url = tmp[0]; + var selector = tmp[1]; + if (String(options) == 'undefined') options = {}; + // load url + var html = $('#w2ui-popup').data(url); + if (typeof html != 'undefined' && html != null) { + popup(html, selector); + } else { + $.get(url, function (data, status, obj) { + popup(obj.responseText, selector); + $('#w2ui-popup').data(url, obj.responseText); // remember for possible future purposes + }); + } + function popup(html, selector) { + delete options.url; + $('body').append(''); + if (typeof selector != 'undefined' && $('#w2ui-tmp #'+selector).length > 0) { + $('#w2ui-tmp #' + selector).w2popup(options); + } else { + $('#w2ui-tmp > div').w2popup(options); + } + // link styles + if ($('#w2ui-tmp > style').length > 0) { + var style = $('
      ').append($('#w2ui-tmp > style').clone()).html(); + if ($('#w2ui-popup #div-style').length == 0) { + $('#w2ui-popup').append('
      '); + } + $('#w2ui-popup #div-style').html(style); + } + $('#w2ui-tmp').remove(); + } + }, + + message: function (options) { + $().w2tag(); // hide all tags + if (!options) options = { width: 200, height: 100 }; + if (parseInt(options.width) < 10) options.width = 10; + if (parseInt(options.height) < 10) options.height = 10; + if (typeof options.hideOnClick == 'undefined') options.hideOnClick = false; + var poptions = $('#w2ui-popup').data('options') + if (typeof options.width == 'undefined' || options.width > poptions.width - 10) options.width = poptions.width - 10; + if (typeof options.height == 'undefined' || options.height > poptions.height - 40) options.height = poptions.height - 40; // title is 30px or so + + var head = $('#w2ui-popup .w2ui-msg-title'); + var pwidth = parseInt($('#w2ui-popup').width()); + var msgCount = $('#w2ui-popup .w2ui-popup-message').length; + // remove message + if ($.trim(options.html) == '') { + $('#w2ui-popup #w2ui-message'+ (msgCount-1)).css('z-Index', 250); + var options = $('#w2ui-popup #w2ui-message'+ (msgCount-1)).data('options') || {}; + $('#w2ui-popup #w2ui-message'+ (msgCount-1)).remove(); + if (typeof options.onClose == 'function') options.onClose(); + if (msgCount == 1) { + w2popup.unlock(); + } else { + $('#w2ui-popup #w2ui-message'+ (msgCount-2)).show(); + } + } else { + // hide previous messages + $('#w2ui-popup .w2ui-popup-message').hide(); + // add message + $('#w2ui-popup .w2ui-box1') + .before(''); + $('#w2ui-popup #w2ui-message'+ msgCount).data('options', options); + var display = $('#w2ui-popup #w2ui-message'+ msgCount).css('display'); + $('#w2ui-popup #w2ui-message'+ msgCount).css({ + '-webkit-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), + '-moz-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), + '-ms-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), + '-o-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)') + }); + if (display == 'none') { + $('#w2ui-popup #w2ui-message'+ msgCount).show().html(options.html); + // timer needs to animation + setTimeout(function () { + $('#w2ui-popup #w2ui-message'+ msgCount).css({ + '-webkit-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), + '-moz-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), + '-ms-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), + '-o-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') + }); + }, 1); + // timer for lock + setTimeout(function() { + $('#w2ui-popup #w2ui-message'+ msgCount).css({ + '-webkit-transition': '0s', '-moz-transition': '0s', '-ms-transition': '0s', '-o-transition': '0s', + 'z-Index': 1500 + }); // has to be on top of lock + if (msgCount == 0) w2popup.lock(); + if (typeof options.onOpen == 'function') options.onOpen(); + }, 300); + } + } + }, + + lock: function (msg, showSpinner) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift($('#w2ui-popup')); + w2utils.lock.apply(window, args); + }, + + unlock: function () { + w2utils.unlock($('#w2ui-popup')); + }, + + // --- INTERNAL FUNCTIONS + + lockScreen: function (options) { + if ($('#w2ui-lock').length > 0) return false; + if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); + if (typeof options == 'undefined') options = {}; + options = $.extend({}, w2popup.defaults, options); + // show element + $('body').append('
      '); + // lock screen + setTimeout(function () { + $('#w2ui-lock').css({ + '-webkit-transition': options.speed + 's opacity', + '-moz-transition': options.speed + 's opacity', + '-ms-transition': options.speed + 's opacity', + '-o-transition': options.speed + 's opacity', + 'opacity': options.opacity + }); + }, 1); + // add events + if (options.modal == true) { + $('#w2ui-lock').on('mousedown', function () { + $('#w2ui-lock').css({ + '-webkit-transition': '.1s', + '-moz-transition': '.1s', + '-ms-transition': '.1s', + '-o-transition': '.1s', + 'opacity': '0.6' + }); + // if (window.getSelection) window.getSelection().removeAllRanges(); + }); + $('#w2ui-lock').on('mouseup', function () { + setTimeout(function () { + $('#w2ui-lock').css({ + '-webkit-transition': '.1s', + '-moz-transition': '.1s', + '-ms-transition': '.1s', + '-o-transition': '.1s', + 'opacity': options.opacity + }); + }, 100); + // if (window.getSelection) window.getSelection().removeAllRanges(); + }); + } else { + $('#w2ui-lock').on('mouseup', function () { w2popup.close(); }); + } + return true; + }, + + unlockScreen: function (options) { + if ($('#w2ui-lock').length == 0) return false; + if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); + if (typeof options == 'undefined') options = {}; + options = $.extend({}, w2popup.defaults, options); + $('#w2ui-lock').css({ + '-webkit-transition': options.speed + 's opacity', + '-moz-transition': options.speed + 's opacity', + '-ms-transition': options.speed + 's opacity', + '-o-transition': options.speed + 's opacity', + 'opacity': 0 + }); + setTimeout(function () { + $('#w2ui-lock').remove(); + }, options.speed * 1000); + return true; + }, + + resize: function (width, height, callBack) { + var options = $('#w2ui-popup').data('options'); + // calculate new position + if (parseInt($(window).width()) - 10 < parseInt(width)) width = parseInt($(window).width()) - 10; + if (parseInt($(window).height()) - 10 < parseInt(height)) height = parseInt($(window).height()) - 10; + var top = ((parseInt($(window).height()) - parseInt(height)) / 2) * 0.8; + var left = (parseInt($(window).width()) - parseInt(width)) / 2; + // resize there + $('#w2ui-popup').css({ + '-webkit-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + '-moz-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + '-ms-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + '-o-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + 'top': top, + 'left': left, + 'width': width, + 'height': height + }); + if (typeof callBack == 'function') { + setTimeout(function () { + callBack(); + }, options.speed * 1000); + } + } + } + + // merge in event handling + $.extend(w2popup, w2utils.event); })(); @@ -8242,53 +8242,53 @@ var w2popup = {}; // --- Common dialogs var w2alert = function (msg, title, callBack) { - if (typeof title == 'undefined') title = w2utils.lang('Notification'); - if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { - w2popup.message({ - width : 400, - height : 150, - html : '
      ' + - '
      ' + msg + '
      ' + - '
      ' + - '
      ' + - ' ' + - '
      ', - onClose : function () { - if (typeof callBack == 'function') callBack(); - } - }); - } else { - w2popup.open({ - width : 450, - height : 200, - showMax : false, - title : title, - body : '
      ' + msg + '
      ', - buttons : '', - onClose : function () { - if (typeof callBack == 'function') callBack(); - } - }); - } + if (typeof title == 'undefined') title = w2utils.lang('Notification'); + if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + w2popup.message({ + width : 400, + height : 150, + html : '
      ' + + '
      ' + msg + '
      ' + + '
      ' + + '
      ' + + ' ' + + '
      ', + onClose : function () { + if (typeof callBack == 'function') callBack(); + } + }); + } else { + w2popup.open({ + width : 450, + height : 200, + showMax : false, + title : title, + body : '
      ' + msg + '
      ', + buttons : '', + onClose : function () { + if (typeof callBack == 'function') callBack(); + } + }); + } }; var w2confirm = function (obj, callBack) { var w2confirm_width = 400, w2confirm_height = 150, - w2confirm_yes_text = 'Yes', + w2confirm_yes_text = 'Yes', w2confirm_yes_class = '', w2confirm_yes_style = '', - w2confirm_no_text = 'No', + w2confirm_no_text = 'No', w2confirm_no_class = '', w2confirm_no_style = '', title = w2utils.lang('Confirmation'); if (arguments.length == 1 && typeof obj == 'object') { - var msg = w2utils.lang(obj['msg']), - callBack = obj['callBack'], - btn_yes = obj['btn_yes'], - btn_no = obj['btn_no']; + var msg = w2utils.lang(obj['msg']), + callBack = obj['callBack'], + btn_yes = obj['btn_yes'], + btn_no = obj['btn_no']; if (obj.title) title = w2utils.lang(obj['title']); if (w2utils.isInt(obj.width)) w2confirm_width = obj.width; @@ -8310,5643 +8310,5643 @@ var w2confirm = function (obj, callBack) { var msg = obj; } - if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { if (w2confirm_width > w2popup.get().width) w2confirm_width = w2popup.get().width; if (w2confirm_height > (w2popup.get().height - 50)) w2confirm_height = w2popup.get().height - 50; - w2popup.message({ - width : w2confirm_width, - height : w2confirm_height, - html : '
      ' + - '
      ' + msg + '
      ' + - '
      ' + - '
      ' + - ' ' + - ' ' + - '
      ', - onOpen: function () { - $('#w2ui-popup .w2ui-popup-message .btn').on('click', function (event) { - w2popup.message(); - if (typeof callBack == 'function') callBack(event.target.id); - }); - }, - onKeydown: function (event) { - switch (event.originalEvent.keyCode) { - case 13: // enter - if (typeof callBack == 'function') callBack('Yes'); - w2popup.message(); - break - case 27: // esc - if (typeof callBack == 'function') callBack('No'); - w2popup.message(); - break - } - } - }); - } else { + w2popup.message({ + width : w2confirm_width, + height : w2confirm_height, + html : '
      ' + + '
      ' + msg + '
      ' + + '
      ' + + '
      ' + + ' ' + + ' ' + + '
      ', + onOpen: function () { + $('#w2ui-popup .w2ui-popup-message .btn').on('click', function (event) { + w2popup.message(); + if (typeof callBack == 'function') callBack(event.target.id); + }); + }, + onKeydown: function (event) { + switch (event.originalEvent.keyCode) { + case 13: // enter + if (typeof callBack == 'function') callBack('Yes'); + w2popup.message(); + break + case 27: // esc + if (typeof callBack == 'function') callBack('No'); + w2popup.message(); + break + } + } + }); + } else { if (!w2utils.isInt(obj.height)) w2confirm_height = w2confirm_height + 50; w2popup.open({ - width : w2confirm_width, - height : w2confirm_height, - title : title, - modal : true, - showClose : false, - body : '
      ' + msg + '
      ', - buttons : ''+ - '', - onOpen: function (event) { - event.onComplete = function () { - $('#w2ui-popup .w2ui-popup-btn').on('click', function (event) { - w2popup.close(); - if (typeof callBack == 'function') callBack(event.target.id); - }); - } - }, - onKeydown: function (event) { - switch (event.originalEvent.keyCode) { - case 13: // enter - if (typeof callBack == 'function') callBack('Yes'); - w2popup.close(); - break - case 27: // esc - if (typeof callBack == 'function') callBack('No'); - w2popup.close(); - break - } - } - }); - } + width : w2confirm_width, + height : w2confirm_height, + title : title, + modal : true, + showClose : false, + body : '
      ' + msg + '
      ', + buttons : ''+ + '', + onOpen: function (event) { + event.onComplete = function () { + $('#w2ui-popup .w2ui-popup-btn').on('click', function (event) { + w2popup.close(); + if (typeof callBack == 'function') callBack(event.target.id); + }); + } + }, + onKeydown: function (event) { + switch (event.originalEvent.keyCode) { + case 13: // enter + if (typeof callBack == 'function') callBack('Yes'); + w2popup.close(); + break + case 27: // esc + if (typeof callBack == 'function') callBack('No'); + w2popup.close(); + break + } + } + }); + } }; /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2tabs - tabs widget -* - $().w2tabs - jQuery wrapper +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2tabs - tabs widget +* - $().w2tabs - jQuery wrapper * - Dependencies: jQuery, w2utils * * == NICE TO HAVE == * - on overflow display << >> * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - individual tab onClick (possibly other events) are not working +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - individual tab onClick (possibly other events) are not working * ************************************************************************/ (function () { - var w2tabs = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.active = null; - this.tabs = []; - this.right = ''; - this.style = ''; - this.onClick = null; - this.onClose = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; - - $.extend(this, { handlers: [] }); - $.extend(true, this, w2obj.tabs, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2tabs = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2tabs')) return; - // extend tabs - var tabs = method.tabs || []; - var object = new w2tabs(method); - for (var i = 0; i < tabs.length; i++) { - object.tabs[i] = $.extend({}, w2tabs.prototype.tab, tabs[i]); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - // register new object - w2ui[object.name] = object; - return object; - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2tabs' ); - return undefined; - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2tabs.prototype = { - tab : { - id : null, // command to be sent to all event handlers - text : '', - hidden : false, - disabled : false, - closable : false, - hint : '', - onClick : null, - onRefresh : null, - onClose : null - }, - - add: function (tab) { - return this.insert(null, tab); - }, - - insert: function (id, tab) { - if (!$.isArray(tab)) tab = [tab]; - // assume it is array - for (var i = 0; i < tab.length; i++) { - // checks - if (typeof tab[i].id === 'undefined') { - console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); - return; - } - if (!w2utils.checkUniqueId(tab[i].id, this.tabs, 'tabs', this.name)) return; - // add tab - var newTab = $.extend({}, w2tabs.prototype.tab, tab[i]); - if (id === null || typeof id === 'undefined') { - this.tabs.push(newTab); - } else { - var middle = this.get(id, true); - this.tabs = this.tabs.slice(0, middle).concat([newTab], this.tabs.slice(middle)); - } - this.refresh(tab[i].id); - } - }, - - remove: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab) return false; - removed++; - // remove from array - this.tabs.splice(this.get(tab.id, true), 1); - // remove from screen - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).remove(); - } - return removed; - }, - - select: function (id) { - if (this.active == id || this.get(id) === null) return false; - this.active = id; - this.refresh(); - return true; - }, - - set: function (id, tab) { - var index = this.get(id, true); - if (index === null) return false; - $.extend(this.tabs[index], tab); - this.refresh(id); - return true; - }, - - get: function (id, returnIndex) { - if (arguments.length === 0) { - var all = []; - for (var i1 = 0; i1 < this.tabs.length; i1++) { - if (this.tabs[i1].id != null) { - all.push(this.tabs[i1].id); - } - } - return all; - } else { - for (var i2 = 0; i2 < this.tabs.length; i2++) { - if (this.tabs[i2].id == id) { // need to be == since id can be numeric - return (returnIndex === true ? i2 : this.tabs[i2]); - } - } - } - return null; - }, - - show: function () { - var obj = this; - var shown = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.hidden === false) continue; - shown++; - tab.hidden = false; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return shown; - }, - - hide: function () { - var obj = this; - var hidden= 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.hidden === true) continue; - hidden++; - tab.hidden = true; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return hidden; - }, - - enable: function () { - var obj = this; - var enabled = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.disabled === false) continue; - enabled++; - tab.disabled = false; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return enabled; - }, - - disable: function () { - var obj = this; - var disabled = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.disabled === true) continue; - disabled++; - tab.disabled = true; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return disabled; - }, - - refresh: function (id) { - var time = (new Date()).getTime(); - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // event before - var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), object: this.get(id) }); - if (eventData.isCancelled === true) return; - if (typeof id === 'undefined') { - // refresh all - for (var i = 0; i < this.tabs.length; i++) this.refresh(this.tabs[i].id); - } else { - // create or refresh only one item - var tab = this.get(id); - if (tab === null) return false; - if (typeof tab.caption !== 'undefined') tab.text = tab.caption; - - var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); - var tabHTML = (tab.closable ? '
      ' : '') + - '
      ' + tab.text + '
      '; - if (jq_el.length === 0) { - // does not exist - create it - var addStyle = ''; - if (tab.hidden) { addStyle += 'display: none;'; } - if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } - var html = ''+ tabHTML + ''; - if (this.get(id, true) !== this.tabs.length-1 && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).length > 0) { - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).before(html); - } else { - $(this.box).find('#tabs_'+ this.name +'_right').before(html); - } - } else { - // refresh - jq_el.html(tabHTML); - if (tab.hidden) { jq_el.css('display', 'none'); } - else { jq_el.css('display', ''); } - if (tab.disabled) { jq_el.css({ 'opacity': '0.2', '-moz-opacity': '0.2', '-webkit-opacity': '0.2', '-o-opacity': '0.2', 'filter': 'alpha(opacity=20)' }); } - else { jq_el.css({ 'opacity': '1', '-moz-opacity': '1', '-webkit-opacity': '1', '-o-opacity': '1', 'filter': 'alpha(opacity=100)' }); } - } - } - // right html - $('#tabs_'+ this.name +'_right').html(this.right); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return; - // default action - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (typeof box !== 'undefined' && box !== null) { - if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-tabs') - .html(''); - } - this.box = box; - } - if (!this.box) return false; - // render all buttons - var html = ''+ - ' '+ - '
      '+ this.right +'
      '; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-tabs') - .html(html); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(); - return (new Date()).getTime() - time; - }, - - resize: function () { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; - - // intentionaly blank - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - // clean up - if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-tabs') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - // =================================================== - // -- Internal Event Handlers - - click: function (id, event) { - var tab = this.get(id); - if (tab === null || tab.disabled) return false; - // event before - var eventData = this.trigger({ phase: 'before', type: 'click', target: id, tab: tab, object: tab, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active) +' .w2ui-tab').removeClass('active'); - this.active = tab.id; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(id); - }, - - animateClose: function(id, event) { - var tab = this.get(id); - if (tab === null || tab.disabled) return false; - // event before - var eventData = this.trigger({ phase: 'before', type: 'close', target: id, object: this.get(id), originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - var obj = this; - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).css({ - '-webkit-transition': '.2s', - '-moz-transition': '2s', - '-ms-transition': '.2s', - '-o-transition': '.2s', - opacity: '0' }); - setTimeout(function () { - var width = $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).width(); - $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)) - .html('
      '); - setTimeout(function () { - $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).find(':first-child').css({ 'width': '0px' }); - }, 50); - }, 200); - setTimeout(function () { - obj.remove(id); - }, 450); - // event before - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(); - }, - - animateInsert: function(id, tab) { - if (this.get(id) === null) return; - if (!$.isPlainObject(tab)) return; - // check for unique - if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return; - // insert simple div - var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); - if (jq_el.length !== 0) return; // already exists - // measure width - if (typeof tab.caption !== 'undefined') tab.text = tab.caption; - var tmp = '
      '+ - ''+ - '
      '+ - (tab.closable ? '
      ' : '') + - '
      '+ tab.text +'
      '+ - '
      '+ - '
      '; - $('body').append(tmp); - // create dummy element - var tabHTML = '
       
      '; - var addStyle = ''; - if (tab.hidden) { addStyle += 'display: none;'; } - if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } - var html = ''+ tabHTML +''; - if (this.get(id, true) !== this.tabs.length && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).length > 0) { - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).before(html); - } else { - $(this.box).find('#tabs_'+ this.name +'_right').before(html); - } - // -- move - var obj = this; - setTimeout(function () { - var width = $('#_tmp_simple_tab').width(); - $('#_tmp_tabs').remove(); - $('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id) +' > div').css('width', width+'px'); - }, 1); - setTimeout(function () { - // insert for real - obj.insert(id, tab); - }, 200); - } - }; - - $.extend(w2tabs.prototype, w2utils.event); - w2obj.tabs = w2tabs; + var w2tabs = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.active = null; + this.tabs = []; + this.right = ''; + this.style = ''; + this.onClick = null; + this.onClose = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; + + $.extend(this, { handlers: [] }); + $.extend(true, this, w2obj.tabs, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2tabs = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2tabs')) return; + // extend tabs + var tabs = method.tabs || []; + var object = new w2tabs(method); + for (var i = 0; i < tabs.length; i++) { + object.tabs[i] = $.extend({}, w2tabs.prototype.tab, tabs[i]); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + return object; + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2tabs' ); + return undefined; + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2tabs.prototype = { + tab : { + id : null, // command to be sent to all event handlers + text : '', + hidden : false, + disabled : false, + closable : false, + hint : '', + onClick : null, + onRefresh : null, + onClose : null + }, + + add: function (tab) { + return this.insert(null, tab); + }, + + insert: function (id, tab) { + if (!$.isArray(tab)) tab = [tab]; + // assume it is array + for (var i = 0; i < tab.length; i++) { + // checks + if (typeof tab[i].id === 'undefined') { + console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); + return; + } + if (!w2utils.checkUniqueId(tab[i].id, this.tabs, 'tabs', this.name)) return; + // add tab + var newTab = $.extend({}, w2tabs.prototype.tab, tab[i]); + if (id === null || typeof id === 'undefined') { + this.tabs.push(newTab); + } else { + var middle = this.get(id, true); + this.tabs = this.tabs.slice(0, middle).concat([newTab], this.tabs.slice(middle)); + } + this.refresh(tab[i].id); + } + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab) return false; + removed++; + // remove from array + this.tabs.splice(this.get(tab.id, true), 1); + // remove from screen + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).remove(); + } + return removed; + }, + + select: function (id) { + if (this.active == id || this.get(id) === null) return false; + this.active = id; + this.refresh(); + return true; + }, + + set: function (id, tab) { + var index = this.get(id, true); + if (index === null) return false; + $.extend(this.tabs[index], tab); + this.refresh(id); + return true; + }, + + get: function (id, returnIndex) { + if (arguments.length === 0) { + var all = []; + for (var i1 = 0; i1 < this.tabs.length; i1++) { + if (this.tabs[i1].id != null) { + all.push(this.tabs[i1].id); + } + } + return all; + } else { + for (var i2 = 0; i2 < this.tabs.length; i2++) { + if (this.tabs[i2].id == id) { // need to be == since id can be numeric + return (returnIndex === true ? i2 : this.tabs[i2]); + } + } + } + return null; + }, + + show: function () { + var obj = this; + var shown = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.hidden === false) continue; + shown++; + tab.hidden = false; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return shown; + }, + + hide: function () { + var obj = this; + var hidden= 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.hidden === true) continue; + hidden++; + tab.hidden = true; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return hidden; + }, + + enable: function () { + var obj = this; + var enabled = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.disabled === false) continue; + enabled++; + tab.disabled = false; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return enabled; + }, + + disable: function () { + var obj = this; + var disabled = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.disabled === true) continue; + disabled++; + tab.disabled = true; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return disabled; + }, + + refresh: function (id) { + var time = (new Date()).getTime(); + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), object: this.get(id) }); + if (eventData.isCancelled === true) return; + if (typeof id === 'undefined') { + // refresh all + for (var i = 0; i < this.tabs.length; i++) this.refresh(this.tabs[i].id); + } else { + // create or refresh only one item + var tab = this.get(id); + if (tab === null) return false; + if (typeof tab.caption !== 'undefined') tab.text = tab.caption; + + var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); + var tabHTML = (tab.closable ? '
      ' : '') + + '
      ' + tab.text + '
      '; + if (jq_el.length === 0) { + // does not exist - create it + var addStyle = ''; + if (tab.hidden) { addStyle += 'display: none;'; } + if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } + var html = ''+ tabHTML + ''; + if (this.get(id, true) !== this.tabs.length-1 && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).length > 0) { + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).before(html); + } else { + $(this.box).find('#tabs_'+ this.name +'_right').before(html); + } + } else { + // refresh + jq_el.html(tabHTML); + if (tab.hidden) { jq_el.css('display', 'none'); } + else { jq_el.css('display', ''); } + if (tab.disabled) { jq_el.css({ 'opacity': '0.2', '-moz-opacity': '0.2', '-webkit-opacity': '0.2', '-o-opacity': '0.2', 'filter': 'alpha(opacity=20)' }); } + else { jq_el.css({ 'opacity': '1', '-moz-opacity': '1', '-webkit-opacity': '1', '-o-opacity': '1', 'filter': 'alpha(opacity=100)' }); } + } + } + // right html + $('#tabs_'+ this.name +'_right').html(this.right); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (eventData.isCancelled === true) return; + // default action + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (typeof box !== 'undefined' && box !== null) { + if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html(''); + } + this.box = box; + } + if (!this.box) return false; + // render all buttons + var html = ''+ + ' '+ + '
      '+ this.right +'
      '; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-tabs') + .html(html); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(); + return (new Date()).getTime() - time; + }, + + resize: function () { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; + + // intentionaly blank + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + // clean up + if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + // =================================================== + // -- Internal Event Handlers + + click: function (id, event) { + var tab = this.get(id); + if (tab === null || tab.disabled) return false; + // event before + var eventData = this.trigger({ phase: 'before', type: 'click', target: id, tab: tab, object: tab, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active) +' .w2ui-tab').removeClass('active'); + this.active = tab.id; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(id); + }, + + animateClose: function(id, event) { + var tab = this.get(id); + if (tab === null || tab.disabled) return false; + // event before + var eventData = this.trigger({ phase: 'before', type: 'close', target: id, object: this.get(id), originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + var obj = this; + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).css({ + '-webkit-transition': '.2s', + '-moz-transition': '2s', + '-ms-transition': '.2s', + '-o-transition': '.2s', + opacity: '0' }); + setTimeout(function () { + var width = $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).width(); + $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)) + .html('
      '); + setTimeout(function () { + $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).find(':first-child').css({ 'width': '0px' }); + }, 50); + }, 200); + setTimeout(function () { + obj.remove(id); + }, 450); + // event before + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(); + }, + + animateInsert: function(id, tab) { + if (this.get(id) === null) return; + if (!$.isPlainObject(tab)) return; + // check for unique + if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return; + // insert simple div + var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); + if (jq_el.length !== 0) return; // already exists + // measure width + if (typeof tab.caption !== 'undefined') tab.text = tab.caption; + var tmp = '
      '+ + ''+ + '
      '+ + (tab.closable ? '
      ' : '') + + '
      '+ tab.text +'
      '+ + '
      '+ + '
      '; + $('body').append(tmp); + // create dummy element + var tabHTML = '
       
      '; + var addStyle = ''; + if (tab.hidden) { addStyle += 'display: none;'; } + if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } + var html = ''+ tabHTML +''; + if (this.get(id, true) !== this.tabs.length && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).length > 0) { + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).before(html); + } else { + $(this.box).find('#tabs_'+ this.name +'_right').before(html); + } + // -- move + var obj = this; + setTimeout(function () { + var width = $('#_tmp_simple_tab').width(); + $('#_tmp_tabs').remove(); + $('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id) +' > div').css('width', width+'px'); + }, 1); + setTimeout(function () { + // insert for real + obj.insert(id, tab); + }, 200); + } + }; + + $.extend(w2tabs.prototype, w2utils.event); + w2obj.tabs = w2tabs; })(); /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2toolbar - toolbar widget -* - $().w2toolbar - jQuery wrapper -* - Dependencies: jQuery, w2utils +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2toolbar - toolbar widget +* - $().w2toolbar - jQuery wrapper +* - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - on overflow display << >> -* - verticle toolbar +* - on overflow display << >> +* - verticle toolbar * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - fixed submenu event bugs +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - fixed submenu event bugs * ************************************************************************/ (function () { - var w2toolbar = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.items = []; - this.right = ''; // HTML text on the right of toolbar - this.onClick = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; - - $.extend(true, this, w2obj.toolbar, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2toolbar = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2toolbar')) return; - // extend items - var items = method.items || []; - var object = new w2toolbar(method); - $.extend(object, { items: [], handlers: [] }); - for (var i = 0; i < items.length; i++) { - object.items[i] = $.extend({}, w2toolbar.prototype.item, items[i]); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - // register new object - w2ui[object.name] = object; - return object; - - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2toolbar' ); - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2toolbar.prototype = { - item: { - id : null, // command to be sent to all event handlers - type : 'button', // button, check, radio, drop, menu, break, html, spacer - text : '', - html : '', - img : null, - icon : null, - hidden : false, - disabled: false, - checked : false, // used for radio buttons - arrow : true, // arrow down for drop/menu types - hint : '', - group : null, // used for radio buttons - items : null, // for type menu it is an array of items in the menu - onClick : null - }, - - add: function (items) { - this.insert(null, items); - }, - - insert: function (id, items) { - if (!$.isArray(items)) items = [items]; - for (var o = 0; o < items.length; o++) { - // checks - if (typeof items[o].type === 'undefined') { - console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.'); - return; - } - if ($.inArray(String(items[o].type), ['button', 'check', 'radio', 'drop', 'menu', 'break', 'html', 'spacer']) === -1) { - console.log('ERROR: The parameter "type" should be one of the following [button, check, radio, drop, menu, break, html, spacer] '+ - 'in w2toolbar.add() method.'); - return; - } - if (typeof items[o].id === 'undefined') { - console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.'); - return; - } - if (!w2utils.checkUniqueId(items[o].id, this.items, 'toolbar items', this.name)) return; - // add item - var it = $.extend({}, w2toolbar.prototype.item, items[o]); - if (id == null) { - this.items.push(it); - } else { - var middle = this.get(id, true); - this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle)); - } - this.refresh(it.id); - } - }, - - remove: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - removed++; - // remove from screen - $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove(); - // remove from array - var ind = this.get(it.id, true); - if (ind) this.items.splice(ind, 1); - } - return removed; - }, - - set: function (id, item) { - var index = this.get(id, true); - if (index === null) return false; - $.extend(this.items[index], item); - this.refresh(id); - return true; - }, - - get: function (id, returnIndex) { - if (arguments.length === 0) { - var all = []; - for (var i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id !== null) all.push(this.items[i1].id); - return all; - } - for (var i2 = 0; i2 < this.items.length; i2++) { - if (this.items[i2].id === id) { - if (returnIndex === true) return i2; else return this.items[i2]; - } - } - return null; - }, - - show: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.hidden = false; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - hide: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.hidden = true; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - enable: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.disabled = false; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - disable: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.disabled = true; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - check: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.checked = true; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - uncheck: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.checked = false; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return; - - if (box != null) { - if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-toolbar') - .html(''); - } - this.box = box; - } - if (!this.box) return; - // render all buttons - var html = ''+ - ''; - for (var i = 0; i < this.items.length; i++) { - var it = this.items[i]; - if (it.id == null) it.id = "item_" + i; - if (it === null) continue; - if (it.type === 'spacer') { - html += ''; - } else { - html += ''; - } - } - html += ''; - html += ''+ - '
      '+ this.getItemHTML(it) + - ''+ this.right +'
      '; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-toolbar') - .html(html); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - refresh: function (id) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), item: this.get(id) }); - if (eventData.isCancelled === true) return; - - if (id == null) { - // refresh all - for (var i = 0; i < this.items.length; i++) { - var it1 = this.items[i]; - if (it1.id == null) it1.id = "item_" + i; - this.refresh(it1.id); - } - } - // create or refresh only one item - var it = this.get(id); - if (it === null) return false; - - var el = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)); - var html = this.getItemHTML(it); - if (el.length === 0) { - // does not exist - create it - if (it.type === 'spacer') { - html = ''; - } else { - html = ''+ html + - ''; - } - if (this.get(id, true) === this.items.length-1) { - $(this.box).find('#tb_'+ this.name +'_right').before(html); - } else { - $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(this.items[parseInt(this.get(id, true))+1].id)).before(html); - } - } else { - // refresh - el.html(html); - if (it.hidden) { el.css('display', 'none'); } else { el.css('display', ''); } - if (it.disabled) { el.addClass('disabled'); } else { el.removeClass('disabled'); } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - resize: function () { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; - - // intentionaly blank - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - // clean up - if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-toolbar') - .html(''); - } - $(this.box).html(''); - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - // ======================================== - // --- Internal Functions - - getItemHTML: function (item) { - var html = ''; - - if (typeof item.caption !== 'undefined') item.text = item.caption; - if (typeof item.hint === 'undefined') item.hint = ''; - if (typeof item.text === 'undefined') item.text = ''; - - switch (item.type) { - case 'menu': - case 'button': - case 'check': - case 'radio': - case 'drop': - var img = ' '; - if (item.img) img = '
      '; - if (item.icon) img = '
      '; - html += ''+ - '
      '+ - ' '+ - ' ' + - img + - (item.text !== '' ? '' : '') + - (((item.type === 'drop' || item.type === 'menu') && item.arrow !== false) ? - '' : '') + - '
      '+ item.text +'
      '+ - '
      '; - break; - - case 'break': - html += ''+ - ' '+ - '
       
      '; - break; - - case 'html': - html += ''+ - ' '+ - '
      ' + item.html + '
      '; - break; - } - - var newHTML = ''; - if (typeof item.onRender === 'function') newHTML = item.onRender.call(this, item.id, html); - if (typeof this.onRender === 'function') newHTML = this.onRender(item.id, html); - if (newHTML !== '' && newHTML != null) html = newHTML; - return html; - }, - - menuClick: function (event) { - var obj = this; - if (event.item && !event.item.disabled) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'click', target: event.item.id + ':' + event.subItem.id, item: event.item, - subItem: event.subItem, originalEvent: event.originalEvent }); - if (eventData.isCancelled === true) return; - - // intentionaly blank - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - }, - - click: function (id, event) { - var obj = this; - var it = this.get(id); - if (it && !it.disabled) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'click', target: (typeof id !== 'undefined' ? id : this.name), - item: it, object: it, originalEvent: event }); - if (eventData.isCancelled === true) return; - - var btn = $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button'); - btn.removeClass('down'); - - if (it.type === 'radio') { - for (var i = 0; i < this.items.length; i++) { - var itt = this.items[i]; - if (itt == null || itt.id === it.id || itt.type !== 'radio') continue; - if (itt.group === it.group && itt.checked) { - itt.checked = false; - this.refresh(itt.id); - } - } - it.checked = true; - btn.addClass('checked'); - } - - if (it.type === 'drop' || it.type === 'menu') { - if (it.checked) { - // if it was already checked, second click will hide it - it.checked = false; - } else { - // show overlay - setTimeout(function () { - var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); - if (!$.isPlainObject(it.overlay)) it.overlay = {}; - var left = (el.width() - 50) / 2; - if (left > 19) left = 19; - if (it.type === 'drop') { - el.w2overlay(it.html, $.extend({ left: left, top: 3 }, it.overlay)); - } - if (it.type === 'menu') { - el.w2menu(it.items, $.extend({ left: left, top: 3 }, it.overlay, { - select: function (event) { - obj.menuClick({ item: it, subItem: event.item, originalEvent: event.originalEvent }); - hideDrop(); - } - })); - } - // window.click to hide it - $(document).on('click', hideDrop); - function hideDrop() { - $(document).off('click', hideDrop); - it.checked = false; - btn.removeClass('checked'); - } - }, 1); - } - } - - if (it.type === 'check' || it.type === 'drop' || it.type === 'menu') { - it.checked = !it.checked; - if (it.checked) { - btn.addClass('checked'); - } else { - btn.removeClass('checked'); - } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - } - }; - - $.extend(w2toolbar.prototype, w2utils.event); - w2obj.toolbar = w2toolbar; + var w2toolbar = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.items = []; + this.right = ''; // HTML text on the right of toolbar + this.onClick = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; + + $.extend(true, this, w2obj.toolbar, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2toolbar = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2toolbar')) return; + // extend items + var items = method.items || []; + var object = new w2toolbar(method); + $.extend(object, { items: [], handlers: [] }); + for (var i = 0; i < items.length; i++) { + object.items[i] = $.extend({}, w2toolbar.prototype.item, items[i]); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + return object; + + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2toolbar' ); + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2toolbar.prototype = { + item: { + id : null, // command to be sent to all event handlers + type : 'button', // button, check, radio, drop, menu, break, html, spacer + text : '', + html : '', + img : null, + icon : null, + hidden : false, + disabled : false, + checked : false, // used for radio buttons + arrow : true, // arrow down for drop/menu types + hint : '', + group : null, // used for radio buttons + items : null, // for type menu it is an array of items in the menu + onClick : null + }, + + add: function (items) { + this.insert(null, items); + }, + + insert: function (id, items) { + if (!$.isArray(items)) items = [items]; + for (var o = 0; o < items.length; o++) { + // checks + if (typeof items[o].type === 'undefined') { + console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.'); + return; + } + if ($.inArray(String(items[o].type), ['button', 'check', 'radio', 'drop', 'menu', 'break', 'html', 'spacer']) === -1) { + console.log('ERROR: The parameter "type" should be one of the following [button, check, radio, drop, menu, break, html, spacer] '+ + 'in w2toolbar.add() method.'); + return; + } + if (typeof items[o].id === 'undefined') { + console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.'); + return; + } + if (!w2utils.checkUniqueId(items[o].id, this.items, 'toolbar items', this.name)) return; + // add item + var it = $.extend({}, w2toolbar.prototype.item, items[o]); + if (id == null) { + this.items.push(it); + } else { + var middle = this.get(id, true); + this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle)); + } + this.refresh(it.id); + } + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + removed++; + // remove from screen + $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove(); + // remove from array + var ind = this.get(it.id, true); + if (ind) this.items.splice(ind, 1); + } + return removed; + }, + + set: function (id, item) { + var index = this.get(id, true); + if (index === null) return false; + $.extend(this.items[index], item); + this.refresh(id); + return true; + }, + + get: function (id, returnIndex) { + if (arguments.length === 0) { + var all = []; + for (var i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id !== null) all.push(this.items[i1].id); + return all; + } + for (var i2 = 0; i2 < this.items.length; i2++) { + if (this.items[i2].id === id) { + if (returnIndex === true) return i2; else return this.items[i2]; + } + } + return null; + }, + + show: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.hidden = false; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + hide: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.hidden = true; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + enable: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.disabled = false; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + disable: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.disabled = true; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + check: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.checked = true; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + uncheck: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.checked = false; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (eventData.isCancelled === true) return; + + if (box != null) { + if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html(''); + } + this.box = box; + } + if (!this.box) return; + // render all buttons + var html = ''+ + ''; + for (var i = 0; i < this.items.length; i++) { + var it = this.items[i]; + if (it.id == null) it.id = "item_" + i; + if (it === null) continue; + if (it.type === 'spacer') { + html += ''; + } else { + html += ''; + } + } + html += ''; + html += ''+ + '
      '+ this.getItemHTML(it) + + ''+ this.right +'
      '; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-toolbar') + .html(html); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + refresh: function (id) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), item: this.get(id) }); + if (eventData.isCancelled === true) return; + + if (id == null) { + // refresh all + for (var i = 0; i < this.items.length; i++) { + var it1 = this.items[i]; + if (it1.id == null) it1.id = "item_" + i; + this.refresh(it1.id); + } + } + // create or refresh only one item + var it = this.get(id); + if (it === null) return false; + + var el = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)); + var html = this.getItemHTML(it); + if (el.length === 0) { + // does not exist - create it + if (it.type === 'spacer') { + html = ''; + } else { + html = ''+ html + + ''; + } + if (this.get(id, true) === this.items.length-1) { + $(this.box).find('#tb_'+ this.name +'_right').before(html); + } else { + $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(this.items[parseInt(this.get(id, true))+1].id)).before(html); + } + } else { + // refresh + el.html(html); + if (it.hidden) { el.css('display', 'none'); } else { el.css('display', ''); } + if (it.disabled) { el.addClass('disabled'); } else { el.removeClass('disabled'); } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + resize: function () { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; + + // intentionaly blank + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + // clean up + if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html(''); + } + $(this.box).html(''); + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + // ======================================== + // --- Internal Functions + + getItemHTML: function (item) { + var html = ''; + + if (typeof item.caption !== 'undefined') item.text = item.caption; + if (typeof item.hint === 'undefined') item.hint = ''; + if (typeof item.text === 'undefined') item.text = ''; + + switch (item.type) { + case 'menu': + case 'button': + case 'check': + case 'radio': + case 'drop': + var img = ' '; + if (item.img) img = '
      '; + if (item.icon) img = '
      '; + html += ''+ + '
      '+ + ' '+ + ' ' + + img + + (item.text !== '' ? '' : '') + + (((item.type === 'drop' || item.type === 'menu') && item.arrow !== false) ? + '' : '') + + '
      '+ item.text +'
      '+ + '
      '; + break; + + case 'break': + html += ''+ + ' '+ + '
       
      '; + break; + + case 'html': + html += ''+ + ' '+ + '
      ' + item.html + '
      '; + break; + } + + var newHTML = ''; + if (typeof item.onRender === 'function') newHTML = item.onRender.call(this, item.id, html); + if (typeof this.onRender === 'function') newHTML = this.onRender(item.id, html); + if (newHTML !== '' && newHTML != null) html = newHTML; + return html; + }, + + menuClick: function (event) { + var obj = this; + if (event.item && !event.item.disabled) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'click', target: event.item.id + ':' + event.subItem.id, item: event.item, + subItem: event.subItem, originalEvent: event.originalEvent }); + if (eventData.isCancelled === true) return; + + // intentionaly blank + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + }, + + click: function (id, event) { + var obj = this; + var it = this.get(id); + if (it && !it.disabled) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'click', target: (typeof id !== 'undefined' ? id : this.name), + item: it, object: it, originalEvent: event }); + if (eventData.isCancelled === true) return; + + var btn = $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button'); + btn.removeClass('down'); + + if (it.type === 'radio') { + for (var i = 0; i < this.items.length; i++) { + var itt = this.items[i]; + if (itt == null || itt.id === it.id || itt.type !== 'radio') continue; + if (itt.group === it.group && itt.checked) { + itt.checked = false; + this.refresh(itt.id); + } + } + it.checked = true; + btn.addClass('checked'); + } + + if (it.type === 'drop' || it.type === 'menu') { + if (it.checked) { + // if it was already checked, second click will hide it + it.checked = false; + } else { + // show overlay + setTimeout(function () { + var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); + if (!$.isPlainObject(it.overlay)) it.overlay = {}; + var left = (el.width() - 50) / 2; + if (left > 19) left = 19; + if (it.type === 'drop') { + el.w2overlay(it.html, $.extend({ left: left, top: 3 }, it.overlay)); + } + if (it.type === 'menu') { + el.w2menu(it.items, $.extend({ left: left, top: 3 }, it.overlay, { + select: function (event) { + obj.menuClick({ item: it, subItem: event.item, originalEvent: event.originalEvent }); + hideDrop(); + } + })); + } + // window.click to hide it + $(document).on('click', hideDrop); + function hideDrop() { + $(document).off('click', hideDrop); + it.checked = false; + btn.removeClass('checked'); + } + }, 1); + } + } + + if (it.type === 'check' || it.type === 'drop' || it.type === 'menu') { + it.checked = !it.checked; + if (it.checked) { + btn.addClass('checked'); + } else { + btn.removeClass('checked'); + } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + } + }; + + $.extend(w2toolbar.prototype, w2utils.event); + w2obj.toolbar = w2toolbar; })(); /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2sidebar - sidebar widget -* - $().w2sidebar - jQuery wrapper -* - Dependencies: jQuery, w2utils +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2sidebar - sidebar widget +* - $().w2sidebar - jQuery wrapper +* - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - return ids of all subitems -* - add find() method to find nodes by a specific criteria (I want all nodes for exampe) -* - dbl click should be like it is in grid (with timer not HTML dbl click event) -* - reorder with grag and drop -* - add route property that would navigate to a #route -* - node.style is missleading - should be there to apply color for example +* - return ids of all subitems +* - add find() method to find nodes by a specific criteria (I want all nodes for exampe) +* - dbl click should be like it is in grid (with timer not HTML dbl click event) +* - reorder with grag and drop +* - add route property that would navigate to a #route +* - node.style is missleading - should be there to apply color for example * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - bug: bixed bug with selection -* - new: find({ params }) - returns all matched nodes -* - change: get() w/o params returns all node ids +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - bug: bixed bug with selection +* - new: find({ params }) - returns all matched nodes +* - change: get() w/o params returns all node ids * ************************************************************************/ (function () { - var w2sidebar = function (options) { - this.name = null; - this.box = null; - this.sidebar = null; - this.parent = null; - this.nodes = []; // Sidebar child nodes - this.menu = []; - this.selected = null; // current selected node (readonly) - this.img = null; - this.icon = null; - this.style = ''; - this.topHTML = ''; - this.bottomHTML = ''; - this.keyboard = true; - this.onClick = null; // Fire when user click on Node Text - this.onDblClick = null; // Fire when user dbl clicks - this.onContextMenu = null; - this.onMenuClick = null; // when context menu item selected - this.onExpand = null; // Fire when node Expands - this.onCollapse = null; // Fire when node Colapses - this.onKeydown = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; - - $.extend(true, this, w2obj.sidebar, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2sidebar = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2sidebar')) return; - // extend items - var nodes = method.nodes; - var object = new w2sidebar(method); - $.extend(object, { handlers: [], nodes: [] }); - if (typeof nodes != 'undefined') { - object.add(object, nodes); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - object.sidebar = object; - // register new object - w2ui[object.name] = object; - return object; - - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2sidebar' ); - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2sidebar.prototype = { - - node: { - id : null, - text : '', - count : null, - img : null, - icon : null, - nodes : [], - style : '', // additional style for subitems - selected : false, - expanded : false, - hidden : false, - disabled : false, - group : false, // if true, it will build as a group - groupShowHide : true, - plus : false, // if true, plus will be shown even if there is no sub nodes - // events - onClick : null, - onDblClick : null, - onContextMenu : null, - onExpand : null, - onCollapse : null, - // internal - parent : null, // node object - sidebar : null - }, - - add: function (parent, nodes) { - if (arguments.length == 1) { - // need to be in reverse order - nodes = arguments[0]; - parent = this; - } - if (typeof parent == 'string') parent = this.get(parent); - return this.insert(parent, null, nodes); - }, - - insert: function (parent, before, nodes) { - var txt, ind, tmp, node, nd; - if (arguments.length == 2) { - // need to be in reverse order - nodes = arguments[1]; - before = arguments[0]; - ind = this.get(before); - if (ind === null) { - if (!$.isArray(nodes)) nodes = [nodes]; - txt = (nodes[0].caption != null ? nodes[0].caption : nodes[0].text); - console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); - return null; - } - parent = this.get(before).parent; - } - if (typeof parent == 'string') parent = this.get(parent); - if (!$.isArray(nodes)) nodes = [nodes]; - for (var o in nodes) { - node = nodes[o]; - if (typeof node.id == null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.'); - continue; - } - if (this.get(this, node.id) !== null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ txt + ') because another node with the same id already exists.'); - continue; - } - tmp = $.extend({}, w2sidebar.prototype.node, node); - tmp.sidebar = this; - tmp.parent = parent; - nd = tmp.nodes || []; - tmp.nodes = []; // very important to re-init empty nodes array - if (before === null) { // append to the end - parent.nodes.push(tmp); - } else { - ind = this.get(parent, before, true); - if (ind === null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); - return null; - } - parent.nodes.splice(ind, 0, tmp); - } - if (nd.length > 0) { - this.insert(tmp, null, nd); - } - } - this.refresh(parent.id); - return tmp; - }, - - remove: function () { // multiple arguments - var deleted = 0; - var tmp; - for (var a = 0; a < arguments.length; a++) { - tmp = this.get(arguments[a]); - if (tmp === null) continue; - if (this.selected !== null && this.selected === tmp.id) { - this.selected = null; - } - var ind = this.get(tmp.parent, arguments[a], true); - if (ind === null) continue; - if (tmp.parent.nodes[ind].selected) tmp.sidebar.unselect(tmp.id); - tmp.parent.nodes.splice(ind, 1); - deleted++; - } - if (deleted > 0 && arguments.length == 1) this.refresh(tmp.parent.id); else this.refresh(); - return deleted; - }, - - set: function (parent, id, node) { - if (arguments.length == 2) { - // need to be in reverse order - node = id; - id = parent; - parent = this; - } - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return null; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].id === id) { - // make sure nodes inserted correctly - var nodes = node.nodes; - $.extend(parent.nodes[i], node, { nodes: [] }); - if (nodes != null) { - this.add(parent.nodes[i], nodes); - } - this.refresh(id); - return true; - } else { - var rv = this.set(parent.nodes[i], id, node); - if (rv) return true; - } - } - return false; - }, - - get: function (parent, id, returnIndex) { // can be just called get(id) or get(id, true) - if (arguments.length === 0) { - var all = []; - var tmp = this.find({}); - for (var t = 0; t < tmp.length; t++) { - if (tmp[t].id != null) all.push(tmp[t].id); - } - return all; - } else { - if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { - // need to be in reverse order - returnIndex = id; - id = parent; - parent = this; - } - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return null; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].id == id) { - if (returnIndex === true) return i; else return parent.nodes[i]; - } else { - var rv = this.get(parent.nodes[i], id, returnIndex); - if (rv || rv === 0) return rv; - } - } - return null; - } - }, - - find: function (parent, params, results) { // can be just called find({ selected: true }) - if (arguments.length == 1) { - // need to be in reverse order - params = parent; - parent = this; - } - if (!results) results = []; - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return results; - for (var i = 0; i < parent.nodes.length; i++) { - var match = true; - for (var prop in params) { - if (parent.nodes[i][prop] != params[prop]) match = false; - } - if (match) results.push(parent.nodes[i]); - if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results); - } - return results; - }, - - hide: function () { // multiple arguments - var hidden = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.hidden = true; - hidden++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return hidden; - }, - - show: function () { // multiple arguments - var shown = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.hidden = false; - shown++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return shown; - }, - - disable: function () { // multiple arguments - var disabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.disabled = true; - if (tmp.selected) this.unselect(tmp.id); - disabled++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return disabled; - }, - - enable: function () { // multiple arguments - var enabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.disabled = false; - enabled++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return enabled; - }, - - select: function (id) { - var new_node = this.get(id); - if (!new_node) return false; - if (this.selected == id && new_node.selected) return false; - this.unselect(this.selected); - $(this.box).find('#node_'+ w2utils.escapeId(id)) - .addClass('w2ui-selected') - .find('.w2ui-icon').addClass('w2ui-icon-selected'); - new_node.selected = true; - this.selected = id; - return true; - }, - - unselect: function (id) { - var current = this.get(id); - if (!current) return false; - current.selected = false; - $(this.box).find('#node_'+ w2utils.escapeId(id)) - .removeClass('w2ui-selected') - .find('.w2ui-icon').removeClass('w2ui-icon-selected'); - if (this.selected == id) this.selected = null; - return true; - }, - - toggle: function(id) { - var nd = this.get(id); - if (nd === null) return false; - if (nd.plus) { - this.set(id, { plus: false }); - this.expand(id); - this.refresh(id); - return; - } - if (nd.nodes.length === 0) return false; - if (this.get(id).expanded) return this.collapse(id); else return this.expand(id); - }, - - collapse: function (id) { - var obj = this; - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'collapse', target: id, object: nd }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideUp(200); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      +
      '); - nd.expanded = false; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - setTimeout(function () { obj.refresh(id); }, 200); - return true; - }, - - collapseAll: function (parent) { - if (typeof parent == 'undefined') parent = this; - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return false; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false; - if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); - } - this.refresh(parent.id); - return true; - }, - - expand: function (id) { - var obj = this; - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'expand', target: id, object: nd }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideDown(200); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      -
      '); - nd.expanded = true; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - setTimeout(function () { obj.refresh(id); }, 200); - return true; - }, - - expandAll: function (parent) { - if (typeof parent == 'undefined') parent = this; - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return false; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true; - if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); - } - this.refresh(parent.id); - }, - - expandParents: function (id) { - var node = this.get(id); - if (node === null) return false; - if (node.parent) { - node.parent.expanded = true; - this.expandParents(node.parent.id); - } - this.refresh(id); - return true; - }, - - click: function (id, event) { - var obj = this; - var nd = this.get(id); - if (nd === null) return; - if (nd.disabled || nd.group) return; // should click event if already selected - // unselect all previsously - $(obj.box).find('.w2ui-node.w2ui-selected').each(function (index, el) { - var oldID = $(el).attr('id').replace('node_', ''); - var oldNode = obj.get(oldID); - if (oldNode != null) oldNode.selected = false; - $(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - }); - // select new one - var newNode = $(obj.box).find('#node_'+ w2utils.escapeId(id)); - var oldNode = $(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)); - newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); - // need timeout to allow rendering - setTimeout(function () { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, node: nd, object: nd }); - if (eventData.isCancelled === true) { - // restore selection - newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); - return; - } - // default action - if (oldNode !== null) oldNode.selected = false; - obj.get(id).selected = true; - obj.selected = id; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 1); - }, - - keydown: function (event) { - var obj = this; - var nd = obj.get(obj.selected); - if (!nd || obj.keyboard !== true) return; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behaviour - if (event.keyCode == 13 || event.keyCode == 32) { // enter or space - if (nd.nodes.length > 0) obj.toggle(obj.selected); - } - if (event.keyCode == 37) { // left - if (nd.nodes.length > 0 && nd.expanded) { - obj.collapse(obj.selected); - } else { - selectNode(nd.parent); - if (!nd.parent.group) obj.collapse(nd.parent.id); - } - } - if (event.keyCode == 39) { // right - if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected); - } - if (event.keyCode == 38) { // up - selectNode(neighbor(nd, prev)); - } - if (event.keyCode == 40) { // down - selectNode(neighbor(nd, next)); - } - // cancel event if needed - if ($.inArray(event.keyCode, [13, 32, 37, 38, 39, 40]) != -1) { - if (event.preventDefault) event.preventDefault(); - if (event.stopPropagation) event.stopPropagation(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - - function selectNode (node, event) { - if (node !== null && !node.hidden && !node.disabled && !node.group) { - obj.click(node.id, event); - setTimeout(function () { obj.scrollIntoView(); }, 50); - } - } - - function neighbor (node, neighborFunc) { - node = neighborFunc(node); - while (node !== null && (node.hidden || node.disabled)) { - if (node.group) break; else node = neighborFunc(node); - } - return node; - } - - function next (node, noSubs) { - if (node === null) return null; - var parent = node.parent; - var ind = obj.get(node.id, true); - var nextNode = null; - // jump inside - if (node.expanded && node.nodes.length > 0 && noSubs !== true) { - var t = node.nodes[0]; - if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t; - } else { - if (parent && ind + 1 < parent.nodes.length) { - nextNode = parent.nodes[ind + 1]; - } else { - nextNode = next(parent, true); // jump to the parent - } - } - if (nextNode !== null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode); - return nextNode; - } - - function prev (node) { - if (node === null) return null; - var parent = node.parent; - var ind = obj.get(node.id, true); - var prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent; - if (prevNode !== null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode); - return prevNode; - } - - function lastChild (node) { - if (node.expanded && node.nodes.length > 0) { - var t = node.nodes[node.nodes.length - 1]; - if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t); - } - return node; - } - }, - - scrollIntoView: function (id) { - if (typeof id == 'undefined') id = this.selected; - var nd = this.get(id); - if (nd === null) return; - var body = $(this.box).find('.w2ui-sidebar-div'); - var item = $(this.box).find('#node_'+ w2utils.escapeId(id)); - var offset = item.offset().top - body.offset().top; - if (offset + item.height() > body.height()) { - body.animate({ 'scrollTop': body.scrollTop() + body.height() / 1.3 }, 250, 'linear'); - } - if (offset <= 0) { - body.animate({ 'scrollTop': body.scrollTop() - body.height() / 1.3 }, 250, 'linear'); - } - }, - - dblClick: function (id, event) { - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: nd }); - if (eventData.isCancelled === true) return; - // default action - this.toggle(id); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - contextMenu: function (id, event) { - var obj = this; - var nd = obj.get(id); - if (id != obj.selected) obj.click(id); - // need timeout to allow click to finish first - setTimeout(function () { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: nd }); - if (eventData.isCancelled === true) return; - // default action - if (nd.group || nd.disabled) return; - if (obj.menu.length > 0) { - $(obj.box).find('#node_'+ w2utils.escapeId(id)) - .w2menu(obj.menu, { - left : (event ? event.offsetX || event.pageX : 50) - 25, - onSelect: function (event) { - obj.menuClick(id, parseInt(event.index), event.originalEvent); - } - } - ); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 150); // need timer 150 for FF - }, - - menuClick: function (itemId, index, event) { - var obj = this; - // event before - var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: obj.menu[index] }); - if (eventData.isCancelled === true) return; - // default action - // -- empty - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return; - // default action - if (typeof box != 'undefined' && box !== null) { - if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-sidebar') - .html(''); - } - this.box = box; - } - if (!this.box) return; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-sidebar') - .html('
      '+ - '
      ' + - '
      '+ - '
      '+ - '
      ' - ); - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height: $(this.box).height() + 'px' - }); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // adjust top and bottom - if (this.topHTML !== '') { - $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); - } - if (this.bottomHTML !== '') { - $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - // --- - this.refresh(); - return (new Date()).getTime() - time; - }, - - refresh: function (id) { - var time = (new Date()).getTime(); - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // event before - var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id != 'undefined' ? id : this.name) }); - if (eventData.isCancelled === true) return; - // adjust top and bottom - if (this.topHTML !== '') { - $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); - } - if (this.bottomHTML !== '') { - $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); - } - // default action - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height: $(this.box).height() + 'px' - }); - var obj = this; - var node, nd; - var nm; - if (typeof id == 'undefined') { - node = this; - nm = '.w2ui-sidebar-div'; - } else { - node = this.get(id); - if (node === null) return; - nm = '#node_'+ w2utils.escapeId(node.id) + '_sub'; - } - var nodeHTML; - if (node !== this) { - var tmp = '#node_'+ w2utils.escapeId(node.id); - nodeHTML = getNodeHTML(node); - $(this.box).find(tmp).before(''); - $(this.box).find(tmp).remove(); - $(this.box).find(nm).remove(); - $('#sidebar_'+ this.name + '_tmp').before(nodeHTML); - $('#sidebar_'+ this.name + '_tmp').remove(); - } - // refresh sub nodes - $(this.box).find(nm).html(''); - for (var i = 0; i < node.nodes.length; i++) { - nd = node.nodes[i]; - nodeHTML = getNodeHTML(nd); - $(this.box).find(nm).append(nodeHTML); - if (nd.nodes.length !== 0) { this.refresh(nd.id); } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - - function getNodeHTML(nd) { - var html = ''; - var img = nd.img; - if (img === null) img = this.img; - var icon = nd.icon; - if (icon === null) icon = this.icon; - // -- find out level - var tmp = nd.parent; - var level = 0; - while (tmp && tmp.parent !== null) { - if (tmp.group) level--; - tmp = tmp.parent; - level++; - } - if (typeof nd.caption != 'undefined') nd.text = nd.caption; - if (nd.group) { - html = - '
      '+ - (nd.groupShowHide ? ''+ (!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')) +'' : '') + - ' '+ nd.text +''+ - '
      '+ - '
      '; - } else { - if (nd.selected && !nd.disabled) obj.selected = nd.id; - tmp = ''; - if (img) tmp = '
      '; - if (icon) tmp = '
      '; - html = - '
      '+ - ''+ - ''+ - ''+ - '
      '+ - '
      ' + (nd.nodes.length > 0 ? (nd.expanded ? '-' : '+') : (nd.plus ? '+' : '')) + '
      ' + - '
      '+ - tmp + - (nd.count || nd.count === 0 ? '
      '+ nd.count +'
      ' : '') + - '
      '+ nd.text +'
      '+ - '
      '+ - '
      '+ - '
      '; - } - return html; - } - }, - - resize: function () { - var time = (new Date()).getTime(); - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).css('overflow', 'hidden'); // container should have no overflow - //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'hidden'); - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height : $(this.box).height() + 'px' - }); - //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'auto'); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - // clean up - if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-sidebar') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - lock: function (msg, showSpinner) { - var box = $(this.box).find('> div:first-child'); - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(box); - w2utils.lock.apply(window, args); - }, - - unlock: function () { - w2utils.unlock(this.box); - } - }; - - $.extend(w2sidebar.prototype, w2utils.event); - w2obj.sidebar = w2sidebar; + var w2sidebar = function (options) { + this.name = null; + this.box = null; + this.sidebar = null; + this.parent = null; + this.nodes = []; // Sidebar child nodes + this.menu = []; + this.selected = null; // current selected node (readonly) + this.img = null; + this.icon = null; + this.style = ''; + this.topHTML = ''; + this.bottomHTML = ''; + this.keyboard = true; + this.onClick = null; // Fire when user click on Node Text + this.onDblClick = null; // Fire when user dbl clicks + this.onContextMenu = null; + this.onMenuClick = null; // when context menu item selected + this.onExpand = null; // Fire when node Expands + this.onCollapse = null; // Fire when node Colapses + this.onKeydown = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; + + $.extend(true, this, w2obj.sidebar, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2sidebar = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2sidebar')) return; + // extend items + var nodes = method.nodes; + var object = new w2sidebar(method); + $.extend(object, { handlers: [], nodes: [] }); + if (typeof nodes != 'undefined') { + object.add(object, nodes); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + object.sidebar = object; + // register new object + w2ui[object.name] = object; + return object; + + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2sidebar' ); + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2sidebar.prototype = { + + node: { + id : null, + text : '', + count : null, + img : null, + icon : null, + nodes : [], + style : '', // additional style for subitems + selected : false, + expanded : false, + hidden : false, + disabled : false, + group : false, // if true, it will build as a group + groupShowHide : true, + plus : false, // if true, plus will be shown even if there is no sub nodes + // events + onClick : null, + onDblClick : null, + onContextMenu : null, + onExpand : null, + onCollapse : null, + // internal + parent : null, // node object + sidebar : null + }, + + add: function (parent, nodes) { + if (arguments.length == 1) { + // need to be in reverse order + nodes = arguments[0]; + parent = this; + } + if (typeof parent == 'string') parent = this.get(parent); + return this.insert(parent, null, nodes); + }, + + insert: function (parent, before, nodes) { + var txt, ind, tmp, node, nd; + if (arguments.length == 2) { + // need to be in reverse order + nodes = arguments[1]; + before = arguments[0]; + ind = this.get(before); + if (ind === null) { + if (!$.isArray(nodes)) nodes = [nodes]; + txt = (nodes[0].caption != null ? nodes[0].caption : nodes[0].text); + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); + return null; + } + parent = this.get(before).parent; + } + if (typeof parent == 'string') parent = this.get(parent); + if (!$.isArray(nodes)) nodes = [nodes]; + for (var o in nodes) { + node = nodes[o]; + if (typeof node.id == null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.'); + continue; + } + if (this.get(this, node.id) !== null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ txt + ') because another node with the same id already exists.'); + continue; + } + tmp = $.extend({}, w2sidebar.prototype.node, node); + tmp.sidebar = this; + tmp.parent = parent; + nd = tmp.nodes || []; + tmp.nodes = []; // very important to re-init empty nodes array + if (before === null) { // append to the end + parent.nodes.push(tmp); + } else { + ind = this.get(parent, before, true); + if (ind === null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); + return null; + } + parent.nodes.splice(ind, 0, tmp); + } + if (nd.length > 0) { + this.insert(tmp, null, nd); + } + } + this.refresh(parent.id); + return tmp; + }, + + remove: function () { // multiple arguments + var deleted = 0; + var tmp; + for (var a = 0; a < arguments.length; a++) { + tmp = this.get(arguments[a]); + if (tmp === null) continue; + if (this.selected !== null && this.selected === tmp.id) { + this.selected = null; + } + var ind = this.get(tmp.parent, arguments[a], true); + if (ind === null) continue; + if (tmp.parent.nodes[ind].selected) tmp.sidebar.unselect(tmp.id); + tmp.parent.nodes.splice(ind, 1); + deleted++; + } + if (deleted > 0 && arguments.length == 1) this.refresh(tmp.parent.id); else this.refresh(); + return deleted; + }, + + set: function (parent, id, node) { + if (arguments.length == 2) { + // need to be in reverse order + node = id; + id = parent; + parent = this; + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return null; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id === id) { + // make sure nodes inserted correctly + var nodes = node.nodes; + $.extend(parent.nodes[i], node, { nodes: [] }); + if (nodes != null) { + this.add(parent.nodes[i], nodes); + } + this.refresh(id); + return true; + } else { + var rv = this.set(parent.nodes[i], id, node); + if (rv) return true; + } + } + return false; + }, + + get: function (parent, id, returnIndex) { // can be just called get(id) or get(id, true) + if (arguments.length === 0) { + var all = []; + var tmp = this.find({}); + for (var t = 0; t < tmp.length; t++) { + if (tmp[t].id != null) all.push(tmp[t].id); + } + return all; + } else { + if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { + // need to be in reverse order + returnIndex = id; + id = parent; + parent = this; + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return null; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id == id) { + if (returnIndex === true) return i; else return parent.nodes[i]; + } else { + var rv = this.get(parent.nodes[i], id, returnIndex); + if (rv || rv === 0) return rv; + } + } + return null; + } + }, + + find: function (parent, params, results) { // can be just called find({ selected: true }) + if (arguments.length == 1) { + // need to be in reverse order + params = parent; + parent = this; + } + if (!results) results = []; + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return results; + for (var i = 0; i < parent.nodes.length; i++) { + var match = true; + for (var prop in params) { + if (parent.nodes[i][prop] != params[prop]) match = false; + } + if (match) results.push(parent.nodes[i]); + if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results); + } + return results; + }, + + hide: function () { // multiple arguments + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.hidden = true; + hidden++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return hidden; + }, + + show: function () { // multiple arguments + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.hidden = false; + shown++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return shown; + }, + + disable: function () { // multiple arguments + var disabled = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.disabled = true; + if (tmp.selected) this.unselect(tmp.id); + disabled++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return disabled; + }, + + enable: function () { // multiple arguments + var enabled = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.disabled = false; + enabled++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return enabled; + }, + + select: function (id) { + var new_node = this.get(id); + if (!new_node) return false; + if (this.selected == id && new_node.selected) return false; + this.unselect(this.selected); + $(this.box).find('#node_'+ w2utils.escapeId(id)) + .addClass('w2ui-selected') + .find('.w2ui-icon').addClass('w2ui-icon-selected'); + new_node.selected = true; + this.selected = id; + return true; + }, + + unselect: function (id) { + var current = this.get(id); + if (!current) return false; + current.selected = false; + $(this.box).find('#node_'+ w2utils.escapeId(id)) + .removeClass('w2ui-selected') + .find('.w2ui-icon').removeClass('w2ui-icon-selected'); + if (this.selected == id) this.selected = null; + return true; + }, + + toggle: function(id) { + var nd = this.get(id); + if (nd === null) return false; + if (nd.plus) { + this.set(id, { plus: false }); + this.expand(id); + this.refresh(id); + return; + } + if (nd.nodes.length === 0) return false; + if (this.get(id).expanded) return this.collapse(id); else return this.expand(id); + }, + + collapse: function (id) { + var obj = this; + var nd = this.get(id); + // event before + var eventData = this.trigger({ phase: 'before', type: 'collapse', target: id, object: nd }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideUp(200); + $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      +
      '); + nd.expanded = false; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + setTimeout(function () { obj.refresh(id); }, 200); + return true; + }, + + collapseAll: function (parent) { + if (typeof parent == 'undefined') parent = this; + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return false; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false; + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); + } + this.refresh(parent.id); + return true; + }, + + expand: function (id) { + var obj = this; + var nd = this.get(id); + // event before + var eventData = this.trigger({ phase: 'before', type: 'expand', target: id, object: nd }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideDown(200); + $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      -
      '); + nd.expanded = true; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + setTimeout(function () { obj.refresh(id); }, 200); + return true; + }, + + expandAll: function (parent) { + if (typeof parent == 'undefined') parent = this; + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return false; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true; + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); + } + this.refresh(parent.id); + }, + + expandParents: function (id) { + var node = this.get(id); + if (node === null) return false; + if (node.parent) { + node.parent.expanded = true; + this.expandParents(node.parent.id); + } + this.refresh(id); + return true; + }, + + click: function (id, event) { + var obj = this; + var nd = this.get(id); + if (nd === null) return; + if (nd.disabled || nd.group) return; // should click event if already selected + // unselect all previsously + $(obj.box).find('.w2ui-node.w2ui-selected').each(function (index, el) { + var oldID = $(el).attr('id').replace('node_', ''); + var oldNode = obj.get(oldID); + if (oldNode != null) oldNode.selected = false; + $(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); + }); + // select new one + var newNode = $(obj.box).find('#node_'+ w2utils.escapeId(id)); + var oldNode = $(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)); + newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); + // need timeout to allow rendering + setTimeout(function () { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, node: nd, object: nd }); + if (eventData.isCancelled === true) { + // restore selection + newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); + oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); + return; + } + // default action + if (oldNode !== null) oldNode.selected = false; + obj.get(id).selected = true; + obj.selected = id; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 1); + }, + + keydown: function (event) { + var obj = this; + var nd = obj.get(obj.selected); + if (!nd || obj.keyboard !== true) return; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behaviour + if (event.keyCode == 13 || event.keyCode == 32) { // enter or space + if (nd.nodes.length > 0) obj.toggle(obj.selected); + } + if (event.keyCode == 37) { // left + if (nd.nodes.length > 0 && nd.expanded) { + obj.collapse(obj.selected); + } else { + selectNode(nd.parent); + if (!nd.parent.group) obj.collapse(nd.parent.id); + } + } + if (event.keyCode == 39) { // right + if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected); + } + if (event.keyCode == 38) { // up + selectNode(neighbor(nd, prev)); + } + if (event.keyCode == 40) { // down + selectNode(neighbor(nd, next)); + } + // cancel event if needed + if ($.inArray(event.keyCode, [13, 32, 37, 38, 39, 40]) != -1) { + if (event.preventDefault) event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + + function selectNode (node, event) { + if (node !== null && !node.hidden && !node.disabled && !node.group) { + obj.click(node.id, event); + setTimeout(function () { obj.scrollIntoView(); }, 50); + } + } + + function neighbor (node, neighborFunc) { + node = neighborFunc(node); + while (node !== null && (node.hidden || node.disabled)) { + if (node.group) break; else node = neighborFunc(node); + } + return node; + } + + function next (node, noSubs) { + if (node === null) return null; + var parent = node.parent; + var ind = obj.get(node.id, true); + var nextNode = null; + // jump inside + if (node.expanded && node.nodes.length > 0 && noSubs !== true) { + var t = node.nodes[0]; + if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t; + } else { + if (parent && ind + 1 < parent.nodes.length) { + nextNode = parent.nodes[ind + 1]; + } else { + nextNode = next(parent, true); // jump to the parent + } + } + if (nextNode !== null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode); + return nextNode; + } + + function prev (node) { + if (node === null) return null; + var parent = node.parent; + var ind = obj.get(node.id, true); + var prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent; + if (prevNode !== null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode); + return prevNode; + } + + function lastChild (node) { + if (node.expanded && node.nodes.length > 0) { + var t = node.nodes[node.nodes.length - 1]; + if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t); + } + return node; + } + }, + + scrollIntoView: function (id) { + if (typeof id == 'undefined') id = this.selected; + var nd = this.get(id); + if (nd === null) return; + var body = $(this.box).find('.w2ui-sidebar-div'); + var item = $(this.box).find('#node_'+ w2utils.escapeId(id)); + var offset = item.offset().top - body.offset().top; + if (offset + item.height() > body.height()) { + body.animate({ 'scrollTop': body.scrollTop() + body.height() / 1.3 }, 250, 'linear'); + } + if (offset <= 0) { + body.animate({ 'scrollTop': body.scrollTop() - body.height() / 1.3 }, 250, 'linear'); + } + }, + + dblClick: function (id, event) { + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + var nd = this.get(id); + // event before + var eventData = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: nd }); + if (eventData.isCancelled === true) return; + // default action + this.toggle(id); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + contextMenu: function (id, event) { + var obj = this; + var nd = obj.get(id); + if (id != obj.selected) obj.click(id); + // need timeout to allow click to finish first + setTimeout(function () { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: nd }); + if (eventData.isCancelled === true) return; + // default action + if (nd.group || nd.disabled) return; + if (obj.menu.length > 0) { + $(obj.box).find('#node_'+ w2utils.escapeId(id)) + .w2menu(obj.menu, { + left : (event ? event.offsetX || event.pageX : 50) - 25, + onSelect: function (event) { + obj.menuClick(id, parseInt(event.index), event.originalEvent); + } + } + ); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 150); // need timer 150 for FF + }, + + menuClick: function (itemId, index, event) { + var obj = this; + // event before + var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: obj.menu[index] }); + if (eventData.isCancelled === true) return; + // default action + // -- empty + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (eventData.isCancelled === true) return; + // default action + if (typeof box != 'undefined' && box !== null) { + if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html(''); + } + this.box = box; + } + if (!this.box) return; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-sidebar') + .html('
      '+ + '
      ' + + '
      '+ + '
      '+ + '
      ' + ); + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height: $(this.box).height() + 'px' + }); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // adjust top and bottom + if (this.topHTML !== '') { + $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); + } + if (this.bottomHTML !== '') { + $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + // --- + this.refresh(); + return (new Date()).getTime() - time; + }, + + refresh: function (id) { + var time = (new Date()).getTime(); + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id != 'undefined' ? id : this.name) }); + if (eventData.isCancelled === true) return; + // adjust top and bottom + if (this.topHTML !== '') { + $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); + } + if (this.bottomHTML !== '') { + $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); + } + // default action + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height: $(this.box).height() + 'px' + }); + var obj = this; + var node, nd; + var nm; + if (typeof id == 'undefined') { + node = this; + nm = '.w2ui-sidebar-div'; + } else { + node = this.get(id); + if (node === null) return; + nm = '#node_'+ w2utils.escapeId(node.id) + '_sub'; + } + var nodeHTML; + if (node !== this) { + var tmp = '#node_'+ w2utils.escapeId(node.id); + nodeHTML = getNodeHTML(node); + $(this.box).find(tmp).before(''); + $(this.box).find(tmp).remove(); + $(this.box).find(nm).remove(); + $('#sidebar_'+ this.name + '_tmp').before(nodeHTML); + $('#sidebar_'+ this.name + '_tmp').remove(); + } + // refresh sub nodes + $(this.box).find(nm).html(''); + for (var i = 0; i < node.nodes.length; i++) { + nd = node.nodes[i]; + nodeHTML = getNodeHTML(nd); + $(this.box).find(nm).append(nodeHTML); + if (nd.nodes.length !== 0) { this.refresh(nd.id); } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + + function getNodeHTML(nd) { + var html = ''; + var img = nd.img; + if (img === null) img = this.img; + var icon = nd.icon; + if (icon === null) icon = this.icon; + // -- find out level + var tmp = nd.parent; + var level = 0; + while (tmp && tmp.parent !== null) { + if (tmp.group) level--; + tmp = tmp.parent; + level++; + } + if (typeof nd.caption != 'undefined') nd.text = nd.caption; + if (nd.group) { + html = + '
      '+ + (nd.groupShowHide ? ''+ (!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')) +'' : '') + + ' '+ nd.text +''+ + '
      '+ + '
      '; + } else { + if (nd.selected && !nd.disabled) obj.selected = nd.id; + tmp = ''; + if (img) tmp = '
      '; + if (icon) tmp = '
      '; + html = + '
      '+ + ''+ + ''+ + ''+ + '
      '+ + '
      ' + (nd.nodes.length > 0 ? (nd.expanded ? '-' : '+') : (nd.plus ? '+' : '')) + '
      ' + + '
      '+ + tmp + + (nd.count || nd.count === 0 ? '
      '+ nd.count +'
      ' : '') + + '
      '+ nd.text +'
      '+ + '
      '+ + '
      '+ + '
      '; + } + return html; + } + }, + + resize: function () { + var time = (new Date()).getTime(); + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).css('overflow', 'hidden'); // container should have no overflow + //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'hidden'); + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height : $(this.box).height() + 'px' + }); + //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'auto'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + // clean up + if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + lock: function (msg, showSpinner) { + var box = $(this.box).find('> div:first-child'); + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(box); + w2utils.lock.apply(window, args); + }, + + unlock: function () { + w2utils.unlock(this.box); + } + }; + + $.extend(w2sidebar.prototype, w2utils.event); + w2obj.sidebar = w2sidebar; })(); /************************************************************************ * Library: Web 2.0 UI for jQuery (using prototypical inheritance) * - Following objects defined -* - w2field - various field controls -* - $().w2field - jQuery wrapper +* - w2field - various field controls +* - $().w2field - jQuery wrapper * - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - upload (regular files) -* - BUG with prefix/postfix and arrows (test in different contexts) -* - prefix and suffix are slow (100ms or so) -* - multiple date selection -* - month selection, year selections -* - arrows no longer work (for int) -* - add postData for autocomplete -* - form to support custom types -* - bug: if input is hidden and then enum is applied, then when it becomes visible, it will be 110px +* - upload (regular files) +* - BUG with prefix/postfix and arrows (test in different contexts) +* - prefix and suffix are slow (100ms or so) +* - multiple date selection +* - month selection, year selections +* - arrows no longer work (for int) +* - add postData for autocomplete +* - form to support custom types +* - bug: if input is hidden and then enum is applied, then when it becomes visible, it will be 110px * * == 1.4 Changes == -* - select - for select, list - for drop down (needs this in grid) -* - $().addType() - changes sligtly (this.el) -* - $().removeType() - new method -* - enum add events: onLoad, onRequest, onDelete, for already selected elements -* - enum - refresh happens on each key press even if not needed (for speed) -* - rewrire everythin in objects (w2ftext, w2fenum, w2fdate) -* - render calendar to the div -* - added .btn with colors -* - added enum.style and file.style attributes -* - test all fields as Read Only -* - added openOnFocus -* - deprecated -- change: showAll -> applyFilter -* - color: select with keyboard -* - enum: addNew event -* - added icon and onIconClick -* - new: clearCache -* - easy way to add icons -* - easy way to navigate month/year in dates -* - added step for numeric inputs -* - changed prepopulate -> minLength -* - added options.postData +* - select - for select, list - for drop down (needs this in grid) +* - $().addType() - changes sligtly (this.el) +* - $().removeType() - new method +* - enum add events: onLoad, onRequest, onDelete, for already selected elements +* - enum - refresh happens on each key press even if not needed (for speed) +* - rewrire everythin in objects (w2ftext, w2fenum, w2fdate) +* - render calendar to the div +* - added .btn with colors +* - added enum.style and file.style attributes +* - test all fields as Read Only +* - added openOnFocus +* - deprecated -- change: showAll -> applyFilter +* - color: select with keyboard +* - enum: addNew event +* - added icon and onIconClick +* - new: clearCache +* - easy way to add icons +* - easy way to navigate month/year in dates +* - added step for numeric inputs +* - changed prepopulate -> minLength +* - added options.postData * ************************************************************************/ (function ($) { - var w2field = function (options) { - // public properties - this.el = null - this.helpers = {}; // object or helper elements - this.type = options.type || 'text'; - this.options = $.extend(true, {}, options); - this.onSearch = options.onSearch || null; - this.onRequest = options.onRequest || null; - this.onLoad = options.onLoad || null; - this.onError = options.onError || null; - this.onClick = options.onClick || null; - this.onAdd = options.onAdd || null; - this.onNew = options.onNew || null; - this.onRemove = options.onRemove || null; - this.onMouseOver= options.onMouseOver || null; - this.onMouseOut = options.onMouseOut || null; - this.onIconClick= options.onIconClick || null; - this.tmp = {}; // temp object - // clean up some options - delete this.options.type; - delete this.options.onSearch; - delete this.options.onRequest; - delete this.options.onLoad; - delete this.options.onError; - delete this.options.onClick; - delete this.options.onMouseOver; - delete this.options.onMouseOut; - delete this.options.onIconClick; - // extend with defaults - $.extend(true, this, w2obj.field); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2field = function (method, options) { - // call direct - if (this.length == 0) { - var pr = w2field.prototype; - if (pr[method]) { - return pr[method].apply(pr, Array.prototype.slice.call(arguments, 1)); - } - } else { - if (typeof method == 'string' && typeof options == 'object') { - method = $.extend(true, {}, options, { type: method }); - } - if (typeof method == 'string' && typeof options == 'undefined') { - method = { type: method }; - } - method.type = String(method.type).toLowerCase(); - return this.each(function (index, el) { - var obj = $(el).data('w2field'); - // if object is not defined, define it - if (typeof obj == 'undefined') { - var obj = new w2field(method); - $.extend(obj, { handlers: [] }); - if (el) obj.el = $(el)[0]; - obj.init(); - $(el).data('w2field', obj); - return obj; - } else { // fully re-init - obj.clear(); - if (method.type == 'clear') return; - var obj = new w2field(method); - $.extend(obj, { handlers: [] }); - if (el) obj.el = $(el)[0]; - obj.init(); - $(el).data('w2field', obj); - return obj; - } - return null; - }); - } - } - - // ==================================================== - // -- Implementation of core functionality - - /* To add custom types - $().w2field('addType', 'myType', function (options) { - $(this.el).on('keypress', function (event) { - if (event.metaKey || event.ctrlKey || event.altKey - || (event.charCode != event.keyCode && event.keyCode > 0)) return; - var ch = String.fromCharCode(event.charCode); - if (ch != 'a' && ch != 'b' && ch != 'c') { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; - } - }); - $(this.el).on('blur', function (event) { // keyCode & charCode differ in FireFox - var ch = this.value; - if (ch != 'a' && ch != 'b' && ch != 'c') { - $(this).w2tag(w2utils.lang("Not a single charecter from the set of 'abc'")); - } - }); - }); - */ - - w2field.prototype = { - - custom: {}, // map of custom types - - pallete: [ - ['000000', '444444', '666666', '999999', 'CCCCCC', 'EEEEEE', 'F3F3F3', 'FFFFFF'], - ['FF011B', 'FF9838', 'FFFD59', '01FD55', '00FFFE', '0424F3', '9B24F4', 'FF21F5'], - ['F4CCCC', 'FCE5CD', 'FFF2CC', 'D9EAD3', 'D0E0E3', 'CFE2F3', 'D9D1E9', 'EAD1DC'], - ['EA9899', 'F9CB9C', 'FEE599', 'B6D7A8', 'A2C4C9', '9FC5E8', 'B4A7D6', 'D5A6BD'], - ['E06666', 'F6B26B', 'FED966', '93C47D', '76A5AF', '6FA8DC', '8E7CC3', 'C27BA0'], - ['CC0814', 'E69138', 'F1C232', '6AA84F', '45818E', '3D85C6', '674EA7', 'A54D79'], - ['99050C', 'B45F17', 'BF901F', '37761D', '124F5C', '0A5394', '351C75', '741B47'], - ['660205', '783F0B', '7F6011', '274E12', '0C343D', '063762', '20124D', '4C1030'] - ], - - addType: function (type, handler) { - type = String(type).toLowerCase(); - this.custom[type] = handler; - return true; - }, - - removeType: function (type) { - type = String(type).toLowerCase(); - if (!this.custom[type]) return false; - delete this.custom[type]; - return true - }, - - init: function () { - var obj = this; - var options = this.options; - var defaults; - - // Custom Types - if (typeof this.custom[this.type] == 'function') { - this.custom[this.type].call(this, options); - return; - } - // only for INPUT or TEXTAREA - if (['INPUT', 'TEXTAREA'].indexOf(this.el.tagName) == -1) { - console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el); - return; - } - - switch (this.type) { - case 'text': - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'alphanumeric': - case 'hex': - defaults = { - min : null, - max : null, - step : 1, - placeholder : '', - autoFormat : true, - currencyPrefix : w2utils.settings.currencyPrefix, - currencySuffix : w2utils.settings.currencySuffix, - currencyPrecision: w2utils.settings.currencyPrecision, - groupSymbol : w2utils.settings.groupSymbol, - arrows : false, - keyboard : true, - precision : null, - silent : true, - prefix : '', - suffix : '' - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g'); - options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol + ']', 'g'); - options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g'); - // no keyboard support needed - if (['text', 'alphanumeric', 'hex'].indexOf(this.type) != -1) { - options.arrows = false; - options.keyboard = false; - } - this.addPrefix(); // only will add if needed - this.addSuffix(); - $(this.el).attr('placeholder', options.placeholder); - break; - - case 'color': - defaults = { - prefix : '#', - suffix : '
       
      ', - placeholder : '', - arrows : false, - keyboard : false - }; - $.extend(options, defaults); - this.addPrefix(); // only will add if needed - this.addSuffix(); // only will add if needed - // additional checks - $(this.el).attr('maxlength', 6); - if ($(this.el).val() != '') setTimeout(function () { $(obj.el).change(); }, 1); - $(this.el).attr('placeholder', options.placeholder); - break; - - case 'date': - defaults = { - format : w2utils.settings.date_format, // date format - placeholder : '', - keyboard : true, - silent : true, - start : '', // string or jquery object - end : '', // string or jquery object - blocked : {}, // { '4/11/2011': 'yes' } - colored : {} // { '4/11/2011': 'red:white' } - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - $(this.el).attr('placeholder', options.placeholder ? options.placeholder : options.format); - break; - - case 'time': - defaults = { - format : w2utils.settings.time_format, - placeholder : '', - keyboard : true, - silent : true, - start : '', - end : '' - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - $(this.el).attr('placeholder', options.placeholder ? options.placeholder : (options.format == 'h12' ? 'hh:mi pm' : 'hh:mi')); - break; - - case 'datetime': - break; - - case 'list': - case 'combo': - defaults = { - items : [], - selected : {}, - placeholder : '', - url : null, // url to pull data from - postData : {}, - minLength : 1, - cacheMax : 250, - maxDropHeight : 350, // max height for drop down menu - match : 'begins', // ['contains', 'is', 'begins', 'ends'] - silent : true, - icon : null, - iconStyle : '', - onSearch : null, // when search needs to be performed - onRequest : null, // when request is submitted - onLoad : null, // when data is received - onError : null, // when data fails to load due to server error or other failure modes - onIconClick : null, - renderDrop : null, // render function for drop down item - prefix : '', - suffix : '', - openOnFocus : false, // if to show overlay onclick or when typing - markSearch : false - }; - if (this.type == 'list') { - // defaults.search = (options.items && options.items.length >= 10 ? true : false); - defaults.openOnFocus = true; - defaults.suffix = '
      '; - $(this.el).addClass('w2ui-select'); - // if simple value - look it up - if (!$.isPlainObject(options.selected)) { - for (var i in options.items) { - var item = options.items[i]; - if (item && item.id == options.selected) { - options.selected = $.extend(true, {}, item); - break; - } - } - } - } - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - altRows : true // alternate row color - }); - options.items = this.normMenu(options.items); - this.options = options; - if (!$.isPlainObject(options.selected)) options.selected = {}; - $(this.el).data('selected', options.selected); - if (options.url) this.request(0); - if (options.icon) { - options.prefix = ''+ - ''; - } - if (this.type == 'list') this.addFocus(); - this.addPrefix(); - this.addSuffix(); - setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh - $(this.el).attr('placeholder', options.placeholder).attr('autocomplete', 'off'); - if (typeof options.selected.text != 'undefined') $(this.el).val(options.selected.text); - break; - - case 'enum': - defaults = { - items : [], - selected : [], - placeholder : '', - max : 0, // max number of selected items, 0 - unlim - url : null, // not implemented - postData : {}, - minLength : 1, - cacheMax : 250, - maxWidth : 250, // max width for a single item - maxHeight : 350, // max height for input control to grow - maxDropHeight : 350, // max height for drop down menu - match : 'contains', // ['contains', 'is', 'begins', 'ends'] - silent : true, - openOnFocus : false, // if to show overlay onclick or when typing - markSearch : true, - renderDrop : null, // render function for drop down item - renderItem : null, // render selected item - style : '', // style for container div - onSearch : null, // when search needs to be performed - onRequest : null, // when request is submitted - onLoad : null, // when data is received - onError : null, // when data fails to load due to server error or other failure modes - onClick : null, // when an item is clicked - onAdd : null, // when an item is added - onNew : null, // when new item should be added - onRemove : null, // when an item is removed - onMouseOver : null, // when an item is mouse over - onMouseOut : null // when an item is mouse out - }; - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - suffix : '', - altRows : true // alternate row color - }); - options.items = this.normMenu(options.items); - options.selected = this.normMenu(options.selected); - this.options = options; - if (!$.isArray(options.selected)) options.selected = []; - $(this.el).data('selected', options.selected); - if (options.url) this.request(0); - this.addSuffix(); - this.addMulti(); - break; - - case 'file': - defaults = { - selected : [], - placeholder : w2utils.lang('Attach files by dragging and dropping or Click to Select'), - max : 0, - maxSize : 0, // max size of all files, 0 - unlim - maxFileSize : 0, // max size of a single file, 0 -unlim - maxWidth : 250, // max width for a single item - maxHeight : 350, // max height for input control to grow - maxDropHeight : 350, // max height for drop down menu - silent : true, - renderItem : null, // render selected item - style : '', // style for container div - onClick : null, // when an item is clicked - onAdd : null, // when an item is added - onRemove : null, // when an item is removed - onMouseOver : null, // when an item is mouse over - onMouseOut : null, // when an item is mouse out - }; - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - altRows : true // alternate row color - }); - this.options = options; - if (!$.isArray(options.selected)) options.selected = []; - $(this.el).data('selected', options.selected); - this.addMulti(); - break; - } - // attach events - this.tmp = { - onChange : function (event) { obj.change.call(obj, event) }, - onClick : function (event) { obj.click.call(obj, event) }, - onFocus : function (event) { obj.focus.call(obj, event) }, - onBlur : function (event) { obj.blur.call(obj, event) }, - onKeydown : function (event) { obj.keyDown.call(obj, event) }, - onKeyup : function (event) { obj.keyUp.call(obj, event) }, - onKeypress : function (event) { obj.keyPress.call(obj, event) } - } - $(this.el) - .addClass('w2field') - .data('w2field', this) - .on('change', this.tmp.onChange) - .on('click', this.tmp.onClick) // ignore click because it messes overlays - .on('focus', this.tmp.onFocus) - .on('blur', this.tmp.onBlur) - .on('keydown', this.tmp.onKeydown) - .on('keyup', this.tmp.onKeyup) - .on('keypress', this.tmp.onKeypress) - .css({ - 'box-sizing' : 'border-box', - '-webkit-box-sizing': 'border-box', - '-moz-box-sizing' : 'border-box', - '-ms-box-sizing' : 'border-box', - '-o-box-sizing' : 'border-box' - }); - // format initial value - this.change($.Event('change')); - }, - - clear: function () { - var obj = this; - var options = this.options; - // if money then clear value - if (['money', 'currency'].indexOf(this.type) != -1) { - $(this.el).val($(this.el).val().replace(options.moneyRE, '')); - } - if (this.type == 'percent') { - $(this.el).val($(this.el).val().replace(/%/g, '')); - } - if (this.type == 'color') { - $(this.el).removeAttr('maxlength'); - } - if (this.type == 'list') { - $(this.el).removeClass('w2ui-select'); - } - this.type = 'clear'; - var tmp = $(this.el).data('tmp'); - if (!this.tmp) return; - // restore paddings - if (typeof tmp != 'undefined') { - if (tmp && tmp['old-padding-left']) $(this.el).css('padding-left', tmp['old-padding-left']); - if (tmp && tmp['old-padding-right']) $(this.el).css('padding-right', tmp['old-padding-right']); - } - // remove events and data - $(this.el) - .val(this.clean($(this.el).val())) - .removeClass('w2field') - .removeData() // removes all attached data - .off('change', this.tmp.onChange) - .off('click', this.tmp.onClick) - .off('focus', this.tmp.onFocus) - .off('blur', this.tmp.onBlur) - .off('keydown', this.tmp.onKeydown) - .off('keyup', this.tmp.onKeyup) - .off('keypress',this.tmp.onKeypress); - // remove helpers - for (var h in this.helpers) $(this.helpers[h]).remove(); - this.helpers = {}; - }, - - refresh: function () { - var obj = this; - var options = this.options; - var selected = $(this.el).data('selected'); - var time = (new Date()).getTime(); - // enum - if (['list'].indexOf(this.type) != -1) { - $(obj.el).parent().css('white-space', 'nowrap'); // needs this for arrow alway to appear on the right side - // hide focus and show text - if (obj.helpers.prefix) obj.helpers.prefix.hide(); - setTimeout(function () { - var focus = obj.helpers.focus.find('input'); - if ($(focus).val() == '') { - $(focus).css('opacity', 0).prev().css('opacity', 0); - $(obj.el).val(selected && selected.text != null ? selected.text : ''); - $(obj.el).attr('placeholder', $(obj.el).attr('_placeholder')); - // if empty show no icon - if ($.isEmptyObject(selected)) { - if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); - } else { - if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.show(); - } - } else { - $(focus).css('opacity', 1).prev().css('opacity', 1); - if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); - $(obj.el).val(''); - $(obj.el).attr('_placeholder', $(obj.el).attr('placeholder')).removeAttr('placeholder'); - } - }, 1); - } - if (['enum', 'file'].indexOf(this.type) != -1) { - var html = ''; - for (var s in selected) { - var it = selected[s]; - var ren = ''; - if (typeof options.renderItem == 'function') { - ren = options.renderItem(it, s, '
        
      '); - } else { - ren = '
        
      '+ - (obj.type == 'enum' ? it.text : it.name + ' - '+ w2utils.size(it.size) +''); - } - html += '
    • '+ - ren +'
    • '; - } - var div = obj.helpers.multi; - var ul = div.find('ul'); - div.attr('style', div.attr('style') + ';' + options.style); - if ($(obj.el).attr('readonly')) div.addClass('w2ui-readonly'); else div.removeClass('w2ui-readonly'); - // celan - div.find('.w2ui-enum-placeholder').remove(); - ul.find('li').not('li.nomouse').remove(); - // add new list - if (html != '') { - ul.prepend(html); - } else if (typeof options.placeholder != 'undefined') { - var style = - 'padding-top: ' + $(this.el).css('padding-top') + ';'+ - 'padding-left: ' + $(this.el).css('padding-left') + '; ' + - 'box-sizing: ' + $(this.el).css('box-sizing') + '; ' + - 'line-height: ' + $(this.el).css('line-height') + '; ' + - 'font-size: ' + $(this.el).css('font-size') + '; ' + - 'font-family: ' + $(this.el).css('font-family') + '; '; - div.prepend('
      '+ options.placeholder + '
      '); - } - // ITEMS events - div.find('li') - .data('mouse', 'out') - .on('click', function (event) { - var item = selected[$(event.target).attr('index')]; - if ($(event.target).hasClass('nomouse')) return; - event.stopPropagation(); - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'click', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // default behavior - if ($(event.target).hasClass('w2ui-list-remove')) { - if ($(obj.el).attr('readonly')) return; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // default behavior - $().w2overlay(); - selected.splice($(event.target).attr('index'), 1); - $(obj.el).trigger('change'); - $(event.target).parent().fadeOut('fast'); - setTimeout(function () { - obj.refresh(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 300); - } - if (obj.type == 'file' && !$(event.target).hasClass('w2ui-list-remove')) { - var preview = ''; - if ((/image/i).test(item.type)) { // image - preview = '
      '+ - ' '+ - '
      '; - } - var td1 = 'style="padding: 3px; text-align: right; color: #777;"'; - var td2 = 'style="padding: 3px"'; - preview += '
      '+ - ' '+ - ' '+ - ' '+ - ' '+ - ' '+ - '
      Name:'+ item.name +'
      Size:'+ w2utils.size(item.size) +'
      Type:' + - ' '+ item.type +''+ - '
      Modified:'+ w2utils.date(item.modified) +'
      '+ - '
      '; - $(event.target).w2overlay(preview); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }) - .on('mouseover', function (event) { - var tmp = event.target; - if (tmp.tagName != 'LI') tmp = tmp.parentNode; - if ($(tmp).hasClass('nomouse')) return; - if ($(tmp).data('mouse') == 'out') { - var item = selected[$(tmp).attr('index')]; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'mouseOver', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - $(tmp).data('mouse', 'over'); - }) - .on('mouseout', function (event) { - var tmp = event.target; - if (tmp.tagName != 'LI') tmp = tmp.parentNode; - if ($(tmp).hasClass('nomouse')) return; - $(tmp).data('mouse', 'leaving'); - setTimeout(function () { - if ($(tmp).data('mouse') == 'leaving') { - $(tmp).data('mouse', 'out'); - var item = selected[$(tmp).attr('index')]; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'f', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - }, 0); - }); - // adjust height - $(this.el).height('auto'); - var cntHeight = $(div).find('> div').height() + w2utils.getSize(div, '+height') * 2; - if (cntHeight < 26) cntHeight = 26; - if (cntHeight > options.maxHeight) cntHeight = options.maxHeight; - if (div.length > 0) div[0].scrollTop = 1000; - var inpHeight = w2utils.getSize($(this.el), 'height') - 2; - if (inpHeight > cntHeight) cntHeight = inpHeight - $(div).css({ 'height': cntHeight + 'px', overflow: (cntHeight == options.maxHeight ? 'auto' : 'hidden') }); - if (cntHeight < options.maxHeight) $(div).prop('scrollTop', 0); - $(this.el).css({ 'height' : (cntHeight + 2) + 'px' }); - } - return (new Date()).getTime() - time; - }, - - reset: function () { - var obj = this; - var type = this.type; - this.clear(); - this.type = type; - this.init(); - }, - - clean: function (val) { - var options = this.options; - val = String(val).trim(); - // clean - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { - if (options.autoFormat && ['money', 'currency'].indexOf(this.type) != -1) val = String(val).replace(options.moneyRE, ''); - if (options.autoFormat && this.type == 'percent') val = String(val).replace(options.percentRE, ''); - if (options.autoFormat && ['int', 'float'].indexOf(this.type) != -1) val = String(val).replace(options.numberRE, ''); - if (parseFloat(val) == val) { - if (options.min !== null && val < options.min) { val = options.min; $(this.el).val(options.min); } - if (options.max !== null && val > options.max) { val = options.max; $(this.el).val(options.max); } - } - if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = ''; - } - return val; - }, - - format: function (val) { - var options = this.options; - // autoformat numbers or money - if (options.autoFormat && val != '') { - switch (this.type) { - case 'money': - case 'currency': - val = w2utils.formatNumber(Number(val).toFixed(options.currencyPrecision), options.groupSymbol); - if (val != '') val = options.currencyPrefix + val + options.currencySuffix; - break; - case 'percent': - val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); - if (val != '') val += '%'; - break; - case 'float': - val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); - break; - case 'int': - val = w2utils.formatNumber(val, options.groupSymbol); - break; - } - } - return val; - }, - - change: function (event) { - var obj = this; - var options = obj.options; - // numeric - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { - // check max/min - var val = $(this.el).val(); - var new_val = this.format(this.clean($(this.el).val())); - // if was modified - if (val != '' && val != new_val) { - $(this.el).val(new_val).change(); - // cancel event - event.stopPropagation(); - event.preventDefault(); - return false; - } - } - // color - if (this.type == 'color') { - var color = '#' + $(this.el).val(); - if ($(this.el).val().length != 6 && $(this.el).val().length != 3) color = ''; - $(this.el).next().find('div').css('background-color', color); - if ($(obj.el).is(':focus')) this.updateOverlay(); - } - }, - - click: function (event) { - event.stopPropagation(); - // lists - if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { - if (!$(this.el).is(':focus')) this.focus(event); - } - // other fields with drops - if (['date', 'time', 'color'].indexOf(this.type) != -1) { - this.updateOverlay(); - } - }, - - focus: function (event) { - var obj = this; - var options = this.options; - // color, date, time - if (['color', 'date', 'time'].indexOf(obj.type) !== -1) { - if ($(obj.el).attr('readonly')) return; - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - setTimeout(function () { obj.updateOverlay(); }, 150); - } - // menu - if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($(obj.el).attr('readonly')) return; - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - setTimeout(function () { - if (obj.type == 'list' && $(obj.el).is(':focus')) { - $(obj.helpers.focus).find('input').focus(); - return; - } - obj.search(); - setTimeout(function () { obj.updateOverlay(); }, 1); - }, 1); - } - // file - if (obj.type == 'file') { - $(obj.helpers.multi).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - } - }, - - blur: function (event) { - var obj = this; - var options = obj.options; - var val = $(obj.el).val().trim(); - // hide overlay - if (['color', 'date', 'time', 'list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - } - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { - if (val !== '' && !obj.checkType(val)) { - $(obj.el).val('').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid number'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - } - // date or time - if (['date', 'time'].indexOf(obj.type) != -1) { - if (w2utils.isInt(obj.el.value)) { - $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); - } - // check if in range - if (val !== '' && !obj.inRange(obj.el.value)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not in range'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } else { - if (obj.type == 'date' && val !== '' && !w2utils.isDate(obj.el.value, options.format)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid date'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - if (obj.type == 'time' && val !== '' && !w2utils.isTime(obj.el.value)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid time'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - } - } - // clear search input - if (obj.type == 'enum') { - $(obj.helpers.multi).find('input').val('').width(20); - } - // file - if (obj.type == 'file') { - $(obj.helpers.multi).css({ 'outline': 'none' }); - } - }, - - keyPress: function (event) { - var obj = this; - var options = obj.options; - // ignore wrong pressed key - if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'color', 'alphanumeric'].indexOf(obj.type) != -1) { - // keyCode & charCode differ in FireFox - if (event.metaKey || event.ctrlKey || event.altKey || (event.charCode != event.keyCode && event.keyCode > 0)) return; - var ch = String.fromCharCode(event.charCode); - if (!obj.checkType(ch, true) && event.keyCode != 13) { - event.preventDefault(); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; - } - } - // update date popup - if (['date', 'time'].indexOf(obj.type) != -1) { - setTimeout(function () { obj.updateOverlay(); }, 1); - } - }, - - keyDown: function (event, extra) { - var obj = this; - var options = obj.options; - var key = event.keyCode || (extra && extra.keyCode); - // numeric - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { - if (!options.keyboard || $(obj.el).attr('readonly')) return; - var cancel = false; - var val = parseFloat($(obj.el).val().replace(options.moneyRE, '')) || 0; - var inc = options.step; - if (event.ctrlKey || event.metaKey) inc = 10; - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - $(obj.el).val((val + inc <= options.max || options.max === null ? Number((val + inc).toFixed(12)) : options.max)).change(); - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - $(obj.el).val((val - inc >= options.min || options.min === null ? Number((val - inc).toFixed(12)) : options.min)).change(); - cancel = true; - break; - } - if (cancel) { - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - }, 0); - } - } - // date - if (obj.type == 'date') { - if (!options.keyboard || $(obj.el).attr('readonly')) return; - var cancel = false; - var daymil = 24*60*60*1000; - var inc = 1; - if (event.ctrlKey || event.metaKey) inc = 10; - if (w2utils.isInt(obj.el.value)) { - $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); - } - var dt = w2utils.isDate($(obj.el).val(), options.format, true); - if (!dt) { dt = new Date(); daymil = 0; } - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDate(dt.getTime() + daymil, options.format); - if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDate(dt.getTime() - daymil, options.format); - if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - } - if (cancel) { - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - obj.updateOverlay(); - }, 0); - } - } - // time - if (obj.type == 'time') { - if (!options.keyboard || $(obj.el).attr('readonly')) return; - var cancel = false; - var inc = 1; - if (event.ctrlKey || event.metaKey) inc = 60; - if (w2utils.isInt(obj.el.value)) { - $(obj.el).val(w2utils.formatTime(new Date(parseInt(obj.el.value)), options.format)).change(); - } - var val = $(obj.el).val(); - var time = obj.toMin(val) || obj.toMin((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)); - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - time += inc; - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - time -= inc; - cancel = true; - break; - } - if (cancel) { - $(obj.el).val(obj.fromMin(time)).change(); - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - }, 0); - } - } - // color - if (obj.type == 'color') { - if ($(obj.el).attr('readonly')) return; - // paste - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { - $(obj.el).prop('maxlength', 7); - setTimeout(function () { - var val = $(obj).val(); - if (val.substr(0, 1) == '#') val = val.substr(1); - if (!w2utils.isHex(val)) val = ''; - $(obj).val(val).prop('maxlength', 6).change(); - }, 20); - } - if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { - if (typeof obj.tmp.cind1 == 'undefined') { - obj.tmp.cind1 = -1; - obj.tmp.cind2 = -1; - } else { - switch (key) { - case 38: // up - obj.tmp.cind1--; - break; - case 40: // down - obj.tmp.cind1++; - break; - case 39: // right - obj.tmp.cind2++; - break; - case 37: // left - obj.tmp.cind2--; - break; - } - if (obj.tmp.cind1 < 0) obj.tmp.cind1 = 0; - if (obj.tmp.cind1 > this.pallete.length - 1) obj.tmp.cind1 = this.pallete.length - 1; - if (obj.tmp.cind2 < 0) obj.tmp.cind2 = 0; - if (obj.tmp.cind2 > this.pallete[0].length - 1) obj.tmp.cind2 = this.pallete[0].length - 1; - } - if ([37, 38, 39, 40].indexOf(key) != -1) { - $(obj.el).val(this.pallete[obj.tmp.cind1][obj.tmp.cind2]).change(); - event.preventDefault(); - } - } - } - // list/select/combo - if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($(obj.el).attr('readonly')) return; - var cancel = false; - var selected = $(obj.el).data('selected'); - var focus = $(obj.helpers.focus).find('input'); - if (obj.type == 'list') { - if ([37, 38, 39, 40].indexOf(key) == -1) obj.refresh(); // arrows - } - // apply arrows - switch (key) { - case 27: // escape - if (obj.type == 'list') { - if ($(focus).val() == '') { - $(obj.el).data('selected', {}); - } else { - $(focus).val(''); - } - obj.refresh(); - event.stopPropagation(); // escape in field should not close popup - } - break; - case 37: // left - case 39: // right - // cancel = true; - break; - case 13: // enter - if ($('#w2ui-overlay').length == 0) break; // no action if overlay not open - var item = options.items[options.index]; - var multi = $(obj.helpers.multi).find('input'); - if (obj.type == 'enum') { - if (item != null) { - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - item = eventData.item; // need to reassign because it could be recreated by user - // default behavior - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete item.hidden; - delete obj.tmp.force_open; - selected.push(item); - $(obj.el).change(); - multi.val('').width(20); - obj.refresh(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } else { - // trigger event - item = { id: multi.val(), text: multi.val() } - var eventData = obj.trigger({ phase: 'before', type: 'new', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - item = eventData.item; // need to reassign because it could be recreated by user - // default behavior - if (typeof obj.onNew == 'function') { - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete obj.tmp.force_open; - selected.push(item); - $(obj.el).change(); - multi.val('').width(20); - obj.refresh(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - } else { - if (item) $(obj.el).data('selected', item).val(item.text).change(); - if ($(obj.el).val() == '' && $(obj.el).data('selected')) $(obj.el).removeData('selected').val('').change(); - if (obj.type == 'list') { - focus.val(''); - obj.refresh(); - } - // hide overlay - obj.tmp.force_hide = true; - } - break; - case 8: // delete - if (['enum'].indexOf(obj.type) != -1) { - if ($(obj.helpers.multi).find('input').val() == '' && selected.length > 0) { - var item = selected[selected.length - 1]; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (eventData.isCancelled === true) return; - // default behavior - selected.pop(); - $(obj.el).trigger('change'); - obj.refresh(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - } - break; - case 38: // up - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index--; - while (options.index > 0 && options.items[options.index].hidden) options.index--; - if (options.index == 0 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } - cancel = true; - break; - case 40: // down - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : -1; - options.index++; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (options.index == options.items.length-1 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index--; - } - // show overlay if not shown - var input = obj.el; - if (['enum'].indexOf(obj.type) != -1) input = obj.helpers.multi.find('input'); - if ($(input).val() == '' && $('#w2ui-overlay').length == 0) { - obj.tmp.force_open = true; - } else { - cancel = true; - } - break; - } - if (cancel) { - if (options.index < 0) options.index = 0; - if (options.index >= options.items.length) options.index = options.items.length -1; - obj.updateOverlay(); - // cancel event - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - if (obj.type == 'enum') { - var tmp = obj.helpers.multi.find('input').get(0); - tmp.setSelectionRange(tmp.value.length, tmp.value.length); - } else if (obj.type == 'list') { - var tmp = obj.helpers.focus.find('input').get(0); - tmp.setSelectionRange(tmp.value.length, tmp.value.length); - } else { - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - } - }, 0); - return; - } - // expand input - if (obj.type == 'enum') { - var input = obj.helpers.multi.find('input'); - var search = input.val(); - input.width(((search.length + 2) * 8) + 'px'); - } - // run search - if ([16, 17, 18, 20, 37, 39, 91].indexOf(key) == -1) { // no refreah on crtl, shift, left/right arrows, etc - setTimeout(function () { - if (!obj.tmp.force_hide) obj.request(); - obj.search(); - }, 1); - } - } - }, - - keyUp: function (event) { - if (this.type == 'color') { - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) $(this).prop('maxlength', 6); - } - }, - - clearCache: function () { - var options = this.options; - options.items = []; - this.tmp.xhr_loading = false; - this.tmp.xhr_search = ''; - this.tmp.xhr_total = -1; - this.search(); - }, - - request: function (interval) { - var obj = this; - var options = this.options; - var search = $(obj.el).val() || ''; - // if no url - do nothing - if (!options.url) return; - // -- - if (obj.type == 'enum') { - var tmp = $(obj.helpers.multi).find('input'); - if (tmp.length == 0) search = ''; else search = tmp.val(); - } - if (obj.type == 'list') { - var tmp = $(obj.helpers.focus).find('input'); - if (tmp.length == 0) search = ''; else search = tmp.val(); - } - if (options.minLength != 0 && search.length < options.minLength) { - options.items = []; // need to empty the list - this.updateOverlay(); - return; - } - if (typeof interval == 'undefined') interval = 350; - if (typeof obj.tmp.xhr_search == 'undefined') obj.tmp.xhr_search = ''; - if (typeof obj.tmp.xhr_total == 'undefined') obj.tmp.xhr_total = -1; - // check if need to search - if (options.url && ( - (options.items.length === 0 && obj.tmp.xhr_total !== 0) || - (obj.tmp.xhr_total == options.cacheMax && search.length > obj.tmp.xhr_search.length) || - (search.length >= obj.tmp.xhr_search.length && search.substr(0, obj.tmp.xhr_search.length) != obj.tmp.xhr_search) || - (search.length < obj.tmp.xhr_search.length) - )) { - // empty list - obj.tmp.xhr_loading = true; - obj.search(); - // timeout - clearTimeout(obj.tmp.timeout); - obj.tmp.timeout = setTimeout(function () { - // trigger event - var url = options.url; - var postData = { - search : search, - max : options.cacheMax - }; - $.extend(postData, options.postData); - var eventData = obj.trigger({ phase: 'before', type: 'request', target: obj.el, url: url, postData: postData }); - if (eventData.isCancelled === true) return; - url = eventData.url; - postData = eventData.postData; - // console.log('REMOTE SEARCH:', search); - if (obj.tmp.xhr) obj.tmp.xhr.abort(); - obj.tmp.xhr = $.ajax({ - type : 'POST', - url : url, - data : postData - }) - .done(function (data, status, xhr) { - // trigger event - var eventData2 = obj.trigger({ phase: 'before', type: 'load', target: obj.el, search: postData.search, data: data, xhr: xhr }); - if (eventData2.isCancelled === true) return; - // default behavior - data = eventData2.data; - if (typeof data == 'string') data = JSON.parse(data); - if (data.status != 'success') { - console.log('ERROR: server did not return proper structure. It should return', { status: 'success', items: [{ id: 1, text: 'item' }] }); - return; - } - // remove all extra items if more then needed for cache - if (data.items.length > options.cacheMax) data.items.splice(options.cacheMax, 100000); - // remember stats - obj.tmp.xhr_loading = false; - obj.tmp.xhr_search = search; - obj.tmp.xhr_total = data.items.length; - options.items = data.items; - if (search == '' && data.items.length == 0) obj.tmp.emptySet = true; else obj.tmp.emptySet = false; - obj.search(); - // console.log('-->', 'retrieved:', obj.tmp.xhr_total); - // event after - obj.trigger($.extend(eventData2, { phase: 'after' })); - }) - .error(function (xhr, status, exceptionThrown) { - // trigger event - var errorObj = { status: status, exceptionThrown: exceptionThrown, rawResponseText: xhr.responseText }; - var eventData2 = obj.trigger({ phase: 'before', type: 'error', target: obj.el, search: search, error: errorObj, xhr: xhr }); - if (eventData2.isCancelled === true) return; - // default behavior - console.log('ERROR: server communication failed. The server should return', { status: 'success', items: [{ id: 1, text: 'item' }] }, ', instead the AJAX request produced this: ', errorObj); - // reset stats - obj.clearCache(); - // event after - obj.trigger($.extend(eventData2, { phase: 'after' })); - }); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, interval); - } - }, - - search: function () { - var obj = this; - var options = this.options; - var search = $(obj.el).val(); - var target = obj.el; - var ids = []; - var selected= $(obj.el).data('selected'); - if (obj.type == 'enum') { - target = $(obj.helpers.multi).find('input'); - search = target.val(); - for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } - } - if (obj.type == 'list') { - target = $(obj.helpers.focus).find('input'); - search = target.val(); - for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } - } - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'search', target: target, search: search }); - if (eventData.isCancelled === true) return; - if (obj.tmp.xhr_loading !== true) { - var shown = 0; - for (var i in options.items) { - var item = options.items[i]; - var prefix = ''; - var suffix = ''; - if (['is', 'begins'].indexOf(options.match) != -1) prefix = '^'; - if (['is', 'ends'].indexOf(options.match) != -1) suffix = '$'; - try { - var re = new RegExp(prefix + search + suffix, 'i'); - if (re.test(item.text) || item.text == '...') item.hidden = false; else item.hidden = true; - } catch (e) {} - // do not show selected items - if (obj.type == 'enum' && $.inArray(item.id, ids) != -1) item.hidden = true; - if (item.hidden !== true) shown++; - } - if (obj.type != 'combo') { // don't preselect first for combo - options.index = 0; - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } else { - options.index = -1; - } - if (shown <= 0) options.index = -1; - options.spinner = false; - obj.updateOverlay(); - setTimeout(function () { - var html = $('#w2ui-overlay').html() || ''; - if (options.markSearch && html.indexOf('$.fn.w2menuHandler') != -1) { // do not highlight when no items - $('#w2ui-overlay').w2marker(search); - } - }, 1); - } else { - options.items.splice(0, options.cacheMax); - options.spinner = true; - obj.updateOverlay(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - updateOverlay: function () { - var obj = this; - var options = this.options; - // color - if (this.type == 'color') { - if ($(obj.el).attr('readonly')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay(obj.getColorHTML()); - } else { - $('#w2ui-overlay').html(obj.getColorHTML()); - } - // bind events - $('#w2ui-overlay .color') - .on('mousedown', function (event) { - var color = $(event.originalEvent.target).attr('name'); - var index = $(event.originalEvent.target).attr('index').split(':'); - obj.tmp.cind1 = index[0]; - obj.tmp.cind2 = index[1]; - $(obj.el).val(color).change(); - $(this).html('•'); - }) - .on('mouseup', function () { - setTimeout(function () { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); - }, 10); - }); - } - // date - if (this.type == 'date') { - if ($(obj.el).attr('readonly')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay('
      ', { - css: { "background-color": "#f5f5f5" } - }); - } - var month, year; - var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true); - if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } - (function refreshCalendar(month, year) { - $('#w2ui-overlay > div > div').html(obj.getMonthHTML(month, year)); - $('#w2ui-overlay .w2ui-calendar-title') - .on('mousedown', function () { - if ($(this).next().hasClass('w2ui-calendar-jump')) { - $(this).next().remove(); - } else { - var selYear, selMonth; - $(this).after('
      '); - $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); - setTimeout(function () { - $('#w2ui-overlay .w2ui-calendar-jump') - .find('.w2ui-jump-month, .w2ui-jump-year') - .on('click', function () { - if ($(this).hasClass('w2ui-jump-month')) { - $(this).parent().find('.w2ui-jump-month').removeClass('selected'); - $(this).addClass('selected'); - selMonth = $(this).attr('name'); - } - if ($(this).hasClass('w2ui-jump-year')) { - $(this).parent().find('.w2ui-jump-year').removeClass('selected'); - $(this).addClass('selected'); - selYear = $(this).attr('name'); - } - if (selYear != null && selMonth != null) { - $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); - setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); - } - }); - $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); - }, 1); - } - }); - $('#w2ui-overlay .w2ui-date') - .on('mousedown', function () { - var day = $(this).attr('date'); - $(obj.el).val(day).change(); - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - }) - .on('mouseup', function () { - setTimeout(function () { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); - }, 10); - }); - $('#w2ui-overlay .previous').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) - 1; - refreshCalendar(tmp[0], tmp[1]); - }); - $('#w2ui-overlay .next').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) + 1; - refreshCalendar(tmp[0], tmp[1]); - }); - }) (month, year); - } - // date - if (this.type == 'time') { - if ($(obj.el).attr('readonly')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay('
      ', { - css: { "background-color": "#fff" } - }); - } - var h24 = (this.options.format == 'h24' ? true : false); - $('#w2ui-overlay > div').html(obj.getHourHTML()); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function (event) { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - var hour = $(this).attr('hour'); - $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }) - .on('mouseup', function () { - var hour = $(this).attr('hour'); - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - $(obj.el).w2overlay('
      ', { css: { "background-color": "#fff" } }); - $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function () { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - var min = $(this).attr('min'); - $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }) - .on('mouseup', function () { - setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); - }); - }); - } - // list - if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { - var el = this.el; - var input = this.el; - if (this.type == 'enum') { - el = $(this.helpers.multi); - input = $(el).find('input'); - } - if (this.type == 'list') { - input = $(this.helpers.focus).find('input'); - } - if ($(input).is(':focus')) { - if (options.openOnFocus === false && $(input).val() == '' && obj.tmp.force_open !== true) { - $().w2overlay(); - return; - } - if (obj.tmp.force_hide) { - $().w2overlay(); - setTimeout(function () { - delete obj.tmp.force_hide; - }, 1); - return; - } - if ($(input).val() != '') delete obj.tmp.force_open; - if ($('#w2ui-overlay').length == 0) options.index = 0; - var msgNoItems = w2utils.lang('No matches'); - if (options.url != null && $(input).val().length < options.minLength && obj.tmp.emptySet !== true) msgNoItems = options.minLength + ' ' + w2utils.lang('letters or more...'); - if (options.url != null && $(input).val() == '' && obj.tmp.emptySet !== true) msgNoItems = w2utils.lang('Type to search....'); - $(el).w2menu('refresh', $.extend(true, {}, options, { - search : false, - render : options.renderDrop, - maxHeight : options.maxDropHeight, - msgNoItems : msgNoItems, - // selected with mouse - onSelect: function (event) { - if (obj.type == 'enum') { - var selected = $(obj.el).data('selected'); - if (event.item) { - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: event.item }); - if (eventData.isCancelled === true) return; - // default behavior - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete event.item.hidden; - selected.push(event.item); - $(obj.el).data('selected', selected).change(); - $(obj.helpers.multi).find('input').val('').width(20); - obj.refresh(); - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - } else { - $(obj.el).data('selected', event.item).val(event.item.text).change(); - if (obj.helpers.focus) { - obj.helpers.focus.find('input').val(''); - obj.refresh(); - } - } - } - })); - } - } - }, - - inRange: function (str) { - var inRange = false; - if (this.type == 'date') { - var dt = w2utils.isDate(str, this.options.format, true); - if (dt) { - // enable range - if (this.options.start || this.options.end) { - var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); - var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); - var start = w2utils.isDate(st, this.options.format, true); - var end = w2utils.isDate(en, this.options.format, true); - var current = new Date(dt); - if (!start) start = current; - if (!end) end = current; - if (current >= start && current <= end) inRange = true; - } else { - inRange = true; - } - // block predefined dates - if (this.options.blocked && $.inArray(str, this.options.blocked) != -1) inRange = false; - } - } - if (this.type == 'time') { - if (this.options.start || this.options.end) { - var tm = this.toMin(str); - var tm1 = this.toMin(this.options.start); - var tm2 = this.toMin(this.options.end); - if (!tm1) tm1 = tm; - if (!tm2) tm2 = tm; - if (tm >= tm1 && tm <= tm2) inRange = true; - } else { - inRange = true; - } - } - return inRange; - }, - - /* - * INTERNAL FUNCTIONS - */ - - checkType: function (ch, loose) { - var obj = this; - switch (obj.type) { - case 'int': - if (loose && ['-'].indexOf(ch) != -1) return true; - return w2utils.isInt(ch.replace(obj.options.numberRE, '')); - case 'percent': - ch = ch.replace(/%/g, ''); - case 'float': - if (loose && ['-','.'].indexOf(ch) != -1) return true; - return w2utils.isFloat(ch.replace(obj.options.numberRE, '')); - case 'money': - case 'currency': - if (loose && ['-', '.', obj.options.groupSymbol, obj.options.currencyPrefix, obj.options.currencySuffix].indexOf(ch) != -1) return true; - return w2utils.isFloat(ch.replace(obj.options.moneyRE, '')); - case 'hex': - case 'color': - return w2utils.isHex(ch); - case 'alphanumeric': - return w2utils.isAlphaNumeric(ch); - } - return true; - }, - - addPrefix: function () { - var obj = this; - setTimeout(function () { - if (obj.type === 'clear') return; - var helper; - var tmp = $(obj.el).data('tmp') || {}; - if (tmp['old-padding-left']) $(obj.el).css('padding-left', tmp['old-padding-left']); - tmp['old-padding-left'] = $(obj.el).css('padding-left'); - $(obj.el).data('tmp', tmp); - if (obj.options.prefix !== '') { - // remove if already displaed - if (obj.helpers.prefix) $(obj.helpers.prefix).remove(); - // add fresh - $(obj.el).before( - '
      '+ - obj.options.prefix + - '
      ' - ); - helper = $(obj.el).prev(); - helper - .css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'padding-top' : $(obj.el).css('padding-top'), - 'padding-bottom' : $(obj.el).css('padding-bottom'), - 'padding-left' : $(obj.el).css('padding-left'), - 'padding-right' : 0, - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', - 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px', - 'margin-left' : $(obj.el).css('margin-left'), - 'margin-right' : 0 - }) - .on('click', function (event) { - if (obj.options.icon && typeof obj.onIconClick == 'function') { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'iconClick', target: obj.el, el: $(this).find('span.w2ui-icon')[0] }); - if (eventData.isCancelled === true) return; - - // intentionally empty - - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } else { - if (obj.type == 'list') { - $(obj.helpers.focus).find('input').focus(); - } else { - $(obj.el).focus(); - } - } - }); - $(obj.el).css('padding-left', (helper.width() + parseInt($(obj.el).css('padding-left'), 10)) + 'px'); - // remember helper - obj.helpers.prefix = helper; - } - }, 1); - }, - - addSuffix: function () { - var obj = this; - var helper, pr; - setTimeout(function () { - if (obj.type === 'clear') return; - var tmp = $(obj.el).data('tmp') || {}; - if (tmp['old-padding-right']) $(obj.el).css('padding-right', tmp['old-padding-right']); - tmp['old-padding-right'] = $(obj.el).css('padding-right'); - $(obj.el).data('tmp', tmp); - pr = parseInt($(obj.el).css('padding-right'), 10); - if (obj.options.arrows) { - // remove if already displaed - if (obj.helpers.arrows) $(obj.helpers.arrows).remove(); - // add fresh - $(obj.el).after( - '
       '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '); - var height = w2utils.getSize(obj.el, 'height'); - helper = $(obj.el).next(); - helper.css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'height' : ($(obj.el).height() + parseInt($(obj.el).css('padding-top'), 10) + parseInt($(obj.el).css('padding-bottom'), 10) ) + 'px', - 'padding' : 0, - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', - 'margin-bottom' : 0, - 'border-left' : '1px solid silver' - }) - .css('margin-left', '-'+ (helper.width() + parseInt($(obj.el).css('margin-right'), 10) + 12) + 'px') - .on('mousedown', function (event) { - $('body').on('mouseup', tmp); - $('body').data('_field_update_timer', setTimeout(update, 700)); - update(false); - // timer function - function tmp() { - clearTimeout($('body').data('_field_update_timer')); - $('body').off('mouseup', tmp); - } - // update function - function update(notimer) { - $(obj.el).focus(); - obj.keyDown($.Event("keydown"), { - keyCode : ($(event.target).attr('type') == 'up' ? 38 : 40) - }); - if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60)); - } - }); - pr += helper.width() + 12; - $(obj.el).css('padding-right', pr + 'px'); - // remember helper - obj.helpers.arrows = helper; - } - if (obj.options.suffix !== '') { - // remove if already displaed - if (obj.helpers.suffix) $(obj.helpers.suffix).remove(); - // add fresh - $(obj.el).after( - '
      '+ - obj.options.suffix + - '
      '); - helper = $(obj.el).next(); - helper - .css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'padding-top' : $(obj.el).css('padding-top'), - 'padding-bottom' : $(obj.el).css('padding-bottom'), - 'padding-left' : '3px', - 'padding-right' : $(obj.el).css('padding-right'), - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', - 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px' - }) - .on('click', function (event) { - if (obj.type == 'list') { - $(obj.helpers.focus).find('input').focus(); - } else { - $(obj.el).focus(); - } - }); - - helper.css('margin-left', '-'+ (w2utils.getSize(helper, 'width') + parseInt($(obj.el).css('margin-right'), 10) + 2) + 'px'); - pr += helper.width() + 3; - $(obj.el).css('padding-right', pr + 'px'); - // remember helper - obj.helpers.suffix = helper; - } - }, 1); - }, - - addFocus: function () { - var obj = this; - var options = this.options; - var width = 0; // 11 - show search icon, 0 do not show - if (options.icon) width = 11; - // clean up & init - $(obj.helpers.focus).remove(); - // build helper - var html = - '
      '+ - ' '+ - ' '+ - '
      '; - $(obj.el).attr('tabindex', -1).before(html); - var helper = $(obj.el).prev(); - obj.helpers.focus = helper; - helper.css({ - width : $(obj.el).width(), - "margin-top" : $(obj.el).css('margin-top'), - "margin-left" : (parseInt($(obj.el).css('margin-left')) + parseInt($(obj.el).css('padding-left'))) + 'px', - "margin-bottom" : $(obj.el).css('margin-bottom'), - "margin-right" : $(obj.el).css('margin-right'), - }) - .find('input') - .css({ - cursor : 'default', - width : '100%', - outline : 'none', - opacity : 1, - margin : 0, - border : '1px solid transparent', - padding : $(obj.el).css('padding-top'), - "padding-left" : 0, - "margin-left" : width + (width > 0 ? 6 : 0), - "background-color" : 'transparent' - }); - // INPUT events - helper.find('input') - .on('click', function (event) { - if ($('#w2ui-overlay').length == 0) obj.focus(event); - event.stopPropagation(); - }) - .on('focus', function (event) { - $(obj.el).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - $(this).val(''); - $(obj.el).triggerHandler('focus'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('blur', function (event) { - $(obj.el).css('outline', 'none'); - $(this).val(''); - obj.refresh(); - $(obj.el).triggerHandler('blur'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('keyup', function (event) { obj.keyUp(event) }) - .on('keydown', function (event) { obj.keyDown(event) }) - .on('keypress', function (event) { obj.keyPress(event); }); - // MAIN div - helper.on('click', function (event) { $(this).find('input').focus(); }); - obj.refresh(); - }, - - addMulti: function () { - var obj = this; - var options = this.options; - // clean up & init - $(obj.helpers.multi).remove(); - // build helper - var html = ''; - var margin = - 'margin-top : 0px; ' + - 'margin-bottom : 0px; ' + - 'margin-left : ' + $(obj.el).css('margin-left') + '; ' + - 'margin-right : ' + $(obj.el).css('margin-right') + '; '+ - 'width : ' + (w2utils.getSize(obj.el, 'width') - - parseInt($(obj.el).css('margin-left'), 10) - - parseInt($(obj.el).css('margin-right'), 10)) - + 'px;'; - if (obj.type == 'enum') { - html = '
      '+ - '
      '+ - '
        '+ - '
      • '+ - ' '+ - '
      • ' - '
      '+ - '
      '+ - '
      '; - } - if (obj.type == 'file') { - html = '
      '+ - '
      '+ - '
      '+ - ' ' - '
      '+ - '
      '; - } - $(obj.el) - .before(html) - .css({ - 'background-color' : 'transparent', - 'border-color' : 'transparent' - }); - - var div = $(obj.el).prev(); - obj.helpers.multi = div; - if (obj.type == 'enum') { - $(obj.el).attr('tabindex', -1); - // INPUT events - div.find('input') - .on('click', function (event) { - if ($('#w2ui-overlay').length == 0) obj.focus(event); - $(obj.el).triggerHandler('click'); - }) - .on('focus', function (event) { - $(div).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - $(obj.el).triggerHandler('focus'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('blur', function (event) { - $(div).css('outline', 'none'); - $(obj.el).triggerHandler('blur'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('keyup', function (event) { obj.keyUp(event) }) - .on('keydown', function (event) { obj.keyDown(event) }) - .on('keypress', function (event) { div.find('.w2ui-enum-placeholder').remove(); obj.keyPress(event); }); - // MAIN div - div.on('click', function (event) { $(this).find('input').focus(); }); - } - if (obj.type == 'file') { - $(obj.el).css('outline', 'none'); - div.on('click', function (event) { - $(obj.el).focus(); - if ($(obj.el).attr('readonly')) return; - obj.blur(event); - div.find('input').click(); - }) - .on('dragenter', function (event) { - if ($(obj.el).attr('readonly')) return; - $(div).addClass('w2ui-file-dragover'); - }) - .on('dragleave', function (event) { - if ($(obj.el).attr('readonly')) return; - var tmp = $(event.target).parents('.w2ui-field-helper'); - if (tmp.length == 0) $(div).removeClass('w2ui-file-dragover'); - }) - .on('drop', function (event) { - if ($(obj.el).attr('readonly')) return; - $(div).removeClass('w2ui-file-dragover'); - var files = event.originalEvent.dataTransfer.files; - for (var i=0, l=files.length; i options.maxFileSize) { - err = 'Maximum file size is '+ w2utils.size(options.maxFileSize); - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { - err = 'Maximum total size is '+ w2utils.size(options.maxSize); - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (options.max !== 0 && cnt >= options.max) { - err = 'Maximum number of files is '+ options.max; - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - selected.push(newItem); - // read file as base64 - if (typeof FileReader !== "undefined") { - var reader = new FileReader(); - // need a closure - reader.onload = (function () { - return function (event) { - var fl = event.target.result; - var ind = fl.indexOf(','); - newItem.content = fl.substr(ind+1); - obj.refresh(); - $(obj.el).trigger('change'); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }; - })(); - reader.readAsDataURL(file); - } else { - obj.refresh(); - $(obj.el).trigger('change'); - } - }, - - normMenu: function (menu) { - if ($.isArray(menu)) { - for (var m = 0; m < menu.length; m++) { - if (typeof menu[m] == 'string') { - menu[m] = { id: menu[m], text: menu[m] }; - } else { - if (typeof menu[m].text != 'undefined' && typeof menu[m].id == 'undefined') menu[m].id = menu[m].text; - if (typeof menu[m].text == 'undefined' && typeof menu[m].id != 'undefined') menu[m].text = menu[m].id; - if (typeof menu[m].caption != 'undefined') menu[m].text = menu[m].caption; - } - } - return menu; - } else if (typeof menu == 'object') { - var tmp = [] - for (var m in menu) tmp.push({ id: m, text: menu[m] }); - return tmp; - } - }, - - getColorHTML: function () { - var html = '
      '+ - ''; - for (var i = 0; i < 8; i++) { - html += ''; - for (var j = 0; j < 8; j++) { - html += ''; - } - html += ''; - if (i < 2) html += ''; - } - html += '
      '+ - '
      '+ - ' '+ ($(this.el).val() == this.pallete[i][j] ? '•' : ' ')+ - '
      '+ - '
      '; - return html; - }, - - getMonthHTML: function (month, year) { - var td = new Date(); - var months = w2utils.settings.fullmonths; - var days = w2utils.settings.fulldays; - var daysCount = ['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31']; - var today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate(); - // normalize date - year = w2utils.isInt(year) ? parseInt(year) : td.getFullYear(); - month = w2utils.isInt(month) ? parseInt(month) : td.getMonth() + 1; - if (month > 12) { month -= 12; year++; } - if (month < 1 || month === 0) { month += 12; year--; } - if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; } - this.options.current = month + '/' + year; - - // start with the required date - td = new Date(year, month-1, 1); - var weekDay = td.getDay(); - var tabDays = w2utils.settings.shortdays; - var dayTitle = ''; - for ( var i = 0, len = tabDays.length; i < len; i++) { - dayTitle += '' + tabDays[i] + ''; - } - var html = - '
      '+ - ' '+ - ' '+ - months[month-1] +', '+ year + - '
      '+ - ''+ - ' ' + dayTitle + ''+ - ' '; - - var day = 1; - for (var ci=1; ci<43; ci++) { - if (weekDay === 0 && ci == 1) { - for (var ti=0; ti<6; ti++) html += ''; - ci += 6; - } else { - if (ci < weekDay || day > daysCount[month-1]) { - html += ''; - if ((ci) % 7 === 0) html += ''; - continue; - } - } - var dt = year + '/' + month + '/' + day; - - var className = ''; - if (ci % 7 == 6) className = ' w2ui-saturday'; - if (ci % 7 === 0) className = ' w2ui-sunday'; - if (dt == today) className += ' w2ui-today'; - - var dspDay = day; - var col = ''; - var bgcol = ''; - var tmp_dt = w2utils.formatDate(dt, this.options.format); - if (this.options.colored && this.options.colored[tmp_dt] !== undefined) { // if there is predefined colors for dates - tmp = this.options.colored[tmp_dt].split(':'); - bgcol = 'background-color: ' + tmp[0] + ';'; - col = 'color: ' + tmp[1] + ';'; - } - html += ''; - if (ci % 7 === 0 || (weekDay === 0 && ci == 1)) html += ''; - day++; - } - html += '
        
      '+ - dspDay + - '
      '; - return html; - }, - - getYearHTML: function () { - var months = w2utils.settings.shortmonths; - var mhtml = ''; - var yhtml = ''; - for (var m in months) { - mhtml += '
      '+ months[m] + '
      '; - } - for (var y = 1950; y <= 2020; y++) { - yhtml += '
      '+ y + '
      ' - } - return '
      '+ mhtml +'
      '+ yhtml +'
      '; - }, - - getHourHTML: function () { - var tmp = []; - var h24 = (this.options.format == 'h24' ? true : false); - for (var a=0; a<24; a++) { - var time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : ''); - if (a == 12 && !h24) time = '12:00 pm'; - if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = ''; - var tm1 = this.fromMin(this.toMin(time)); - var tm2 = this.fromMin(this.toMin(time) + 59); - tmp[Math.floor(a/8)] += '
      '+ time +'
      '; - } - var html = - '
      '+ - ' ' + - ' ' + - ' ' + - '
      '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
      '; - return html; - }, - - getMinHTML: function (hour) { - if (typeof hour == 'undefined') hour = 0; - var h24 = (this.options.format == 'h24' ? true : false); - var tmp = []; - for (var a=0; a<60; a+=5) { - var time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : ''); - var ind = a < 20 ? 0 : (a < 40 ? 1 : 2); - if (!tmp[ind]) tmp[ind] = ''; - tmp[ind] += '
      '+ time +'
      '; - } - var html = - '
      '+ - ' ' + - ' ' + - ' ' + - '
      '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
      '; - return html; - }, - - toMin: function (str) { - if (typeof str != 'string') return null; - var tmp = str.split(':'); - if (tmp.length == 2) { - tmp[0] = parseInt(tmp[0]); - tmp[1] = parseInt(tmp[1]); - if (str.indexOf('pm') != -1 && tmp[0] != 12) tmp[0] += 12; - } else { - return null; - } - return tmp[0] * 60 + tmp[1]; - }, - - fromMin: function (time) { - var ret = ''; - if (time >= 24 * 60) time = time % (24 * 60); - if (time < 0) time = 24 * 60 + time; - var hour = Math.floor(time/60); - var min = ((time % 60) < 10 ? '0' : '') + (time % 60); - if (this.options.format.indexOf('h24') != -1) { - ret = hour + ':' + min; - } else { - ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am'); - } - return ret; - } - } - - $.extend(w2field.prototype, w2utils.event); - w2obj.field = w2field; + var w2field = function (options) { + // public properties + this.el = null + this.helpers = {}; // object or helper elements + this.type = options.type || 'text'; + this.options = $.extend(true, {}, options); + this.onSearch = options.onSearch || null; + this.onRequest = options.onRequest || null; + this.onLoad = options.onLoad || null; + this.onError = options.onError || null; + this.onClick = options.onClick || null; + this.onAdd = options.onAdd || null; + this.onNew = options.onNew || null; + this.onRemove = options.onRemove || null; + this.onMouseOver = options.onMouseOver || null; + this.onMouseOut = options.onMouseOut || null; + this.onIconClick = options.onIconClick || null; + this.tmp = {}; // temp object + // clean up some options + delete this.options.type; + delete this.options.onSearch; + delete this.options.onRequest; + delete this.options.onLoad; + delete this.options.onError; + delete this.options.onClick; + delete this.options.onMouseOver; + delete this.options.onMouseOut; + delete this.options.onIconClick; + // extend with defaults + $.extend(true, this, w2obj.field); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2field = function (method, options) { + // call direct + if (this.length == 0) { + var pr = w2field.prototype; + if (pr[method]) { + return pr[method].apply(pr, Array.prototype.slice.call(arguments, 1)); + } + } else { + if (typeof method == 'string' && typeof options == 'object') { + method = $.extend(true, {}, options, { type: method }); + } + if (typeof method == 'string' && typeof options == 'undefined') { + method = { type: method }; + } + method.type = String(method.type).toLowerCase(); + return this.each(function (index, el) { + var obj = $(el).data('w2field'); + // if object is not defined, define it + if (typeof obj == 'undefined') { + var obj = new w2field(method); + $.extend(obj, { handlers: [] }); + if (el) obj.el = $(el)[0]; + obj.init(); + $(el).data('w2field', obj); + return obj; + } else { // fully re-init + obj.clear(); + if (method.type == 'clear') return; + var obj = new w2field(method); + $.extend(obj, { handlers: [] }); + if (el) obj.el = $(el)[0]; + obj.init(); + $(el).data('w2field', obj); + return obj; + } + return null; + }); + } + } + + // ==================================================== + // -- Implementation of core functionality + + /* To add custom types + $().w2field('addType', 'myType', function (options) { + $(this.el).on('keypress', function (event) { + if (event.metaKey || event.ctrlKey || event.altKey + || (event.charCode != event.keyCode && event.keyCode > 0)) return; + var ch = String.fromCharCode(event.charCode); + if (ch != 'a' && ch != 'b' && ch != 'c') { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + return false; + } + }); + $(this.el).on('blur', function (event) { // keyCode & charCode differ in FireFox + var ch = this.value; + if (ch != 'a' && ch != 'b' && ch != 'c') { + $(this).w2tag(w2utils.lang("Not a single charecter from the set of 'abc'")); + } + }); + }); + */ + + w2field.prototype = { + + custom: {}, // map of custom types + + pallete: [ + ['000000', '444444', '666666', '999999', 'CCCCCC', 'EEEEEE', 'F3F3F3', 'FFFFFF'], + ['FF011B', 'FF9838', 'FFFD59', '01FD55', '00FFFE', '0424F3', '9B24F4', 'FF21F5'], + ['F4CCCC', 'FCE5CD', 'FFF2CC', 'D9EAD3', 'D0E0E3', 'CFE2F3', 'D9D1E9', 'EAD1DC'], + ['EA9899', 'F9CB9C', 'FEE599', 'B6D7A8', 'A2C4C9', '9FC5E8', 'B4A7D6', 'D5A6BD'], + ['E06666', 'F6B26B', 'FED966', '93C47D', '76A5AF', '6FA8DC', '8E7CC3', 'C27BA0'], + ['CC0814', 'E69138', 'F1C232', '6AA84F', '45818E', '3D85C6', '674EA7', 'A54D79'], + ['99050C', 'B45F17', 'BF901F', '37761D', '124F5C', '0A5394', '351C75', '741B47'], + ['660205', '783F0B', '7F6011', '274E12', '0C343D', '063762', '20124D', '4C1030'] + ], + + addType: function (type, handler) { + type = String(type).toLowerCase(); + this.custom[type] = handler; + return true; + }, + + removeType: function (type) { + type = String(type).toLowerCase(); + if (!this.custom[type]) return false; + delete this.custom[type]; + return true + }, + + init: function () { + var obj = this; + var options = this.options; + var defaults; + + // Custom Types + if (typeof this.custom[this.type] == 'function') { + this.custom[this.type].call(this, options); + return; + } + // only for INPUT or TEXTAREA + if (['INPUT', 'TEXTAREA'].indexOf(this.el.tagName) == -1) { + console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el); + return; + } + + switch (this.type) { + case 'text': + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'alphanumeric': + case 'hex': + defaults = { + min : null, + max : null, + step : 1, + placeholder : '', + autoFormat : true, + currencyPrefix : w2utils.settings.currencyPrefix, + currencySuffix : w2utils.settings.currencySuffix, + currencyPrecision : w2utils.settings.currencyPrecision, + groupSymbol : w2utils.settings.groupSymbol, + arrows : false, + keyboard : true, + precision : null, + silent : true, + prefix : '', + suffix : '' + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g'); + options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol + ']', 'g'); + options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g'); + // no keyboard support needed + if (['text', 'alphanumeric', 'hex'].indexOf(this.type) != -1) { + options.arrows = false; + options.keyboard = false; + } + this.addPrefix(); // only will add if needed + this.addSuffix(); + $(this.el).attr('placeholder', options.placeholder); + break; + + case 'color': + defaults = { + prefix : '#', + suffix : '
       
      ', + placeholder : '', + arrows : false, + keyboard : false + }; + $.extend(options, defaults); + this.addPrefix(); // only will add if needed + this.addSuffix(); // only will add if needed + // additional checks + $(this.el).attr('maxlength', 6); + if ($(this.el).val() != '') setTimeout(function () { $(obj.el).change(); }, 1); + $(this.el).attr('placeholder', options.placeholder); + break; + + case 'date': + defaults = { + format : w2utils.settings.date_format, // date format + placeholder : '', + keyboard : true, + silent : true, + start : '', // string or jquery object + end : '', // string or jquery object + blocked : {}, // { '4/11/2011': 'yes' } + colored : {} // { '4/11/2011': 'red:white' } + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + $(this.el).attr('placeholder', options.placeholder ? options.placeholder : options.format); + break; + + case 'time': + defaults = { + format : w2utils.settings.time_format, + placeholder : '', + keyboard : true, + silent : true, + start : '', + end : '' + }; + this.options = $.extend(true, {}, defaults, options); + options = this.options; // since object is re-created, need to re-assign + $(this.el).attr('placeholder', options.placeholder ? options.placeholder : (options.format == 'h12' ? 'hh:mi pm' : 'hh:mi')); + break; + + case 'datetime': + break; + + case 'list': + case 'combo': + defaults = { + items : [], + selected : {}, + placeholder : '', + url : null, // url to pull data from + postData : {}, + minLength : 1, + cacheMax : 250, + maxDropHeight : 350, // max height for drop down menu + match : 'begins', // ['contains', 'is', 'begins', 'ends'] + silent : true, + icon : null, + iconStyle : '', + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onIconClick : null, + renderDrop : null, // render function for drop down item + prefix : '', + suffix : '', + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : false + }; + if (this.type == 'list') { + // defaults.search = (options.items && options.items.length >= 10 ? true : false); + defaults.openOnFocus = true; + defaults.suffix = '
      '; + $(this.el).addClass('w2ui-select'); + // if simple value - look it up + if (!$.isPlainObject(options.selected)) { + for (var i in options.items) { + var item = options.items[i]; + if (item && item.id == options.selected) { + options.selected = $.extend(true, {}, item); + break; + } + } + } + } + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + altRows : true // alternate row color + }); + options.items = this.normMenu(options.items); + this.options = options; + if (!$.isPlainObject(options.selected)) options.selected = {}; + $(this.el).data('selected', options.selected); + if (options.url) this.request(0); + if (options.icon) { + options.prefix = ''+ + ''; + } + if (this.type == 'list') this.addFocus(); + this.addPrefix(); + this.addSuffix(); + setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh + $(this.el).attr('placeholder', options.placeholder).attr('autocomplete', 'off'); + if (typeof options.selected.text != 'undefined') $(this.el).val(options.selected.text); + break; + + case 'enum': + defaults = { + items : [], + selected : [], + placeholder : '', + max : 0, // max number of selected items, 0 - unlim + url : null, // not implemented + postData : {}, + minLength : 1, + cacheMax : 250, + maxWidth : 250, // max width for a single item + maxHeight : 350, // max height for input control to grow + maxDropHeight : 350, // max height for drop down menu + match : 'contains', // ['contains', 'is', 'begins', 'ends'] + silent : true, + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : true, + renderDrop : null, // render function for drop down item + renderItem : null, // render selected item + style : '', // style for container div + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onNew : null, // when new item should be added + onRemove : null, // when an item is removed + onMouseOver : null, // when an item is mouse over + onMouseOut : null // when an item is mouse out + }; + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + suffix : '', + altRows : true // alternate row color + }); + options.items = this.normMenu(options.items); + options.selected = this.normMenu(options.selected); + this.options = options; + if (!$.isArray(options.selected)) options.selected = []; + $(this.el).data('selected', options.selected); + if (options.url) this.request(0); + this.addSuffix(); + this.addMulti(); + break; + + case 'file': + defaults = { + selected : [], + placeholder : w2utils.lang('Attach files by dragging and dropping or Click to Select'), + max : 0, + maxSize : 0, // max size of all files, 0 - unlim + maxFileSize : 0, // max size of a single file, 0 -unlim + maxWidth : 250, // max width for a single item + maxHeight : 350, // max height for input control to grow + maxDropHeight : 350, // max height for drop down menu + silent : true, + renderItem : null, // render selected item + style : '', // style for container div + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onRemove : null, // when an item is removed + onMouseOver : null, // when an item is mouse over + onMouseOut : null, // when an item is mouse out + }; + options = $.extend({}, defaults, options, { + align : 'both', // same width as control + altRows : true // alternate row color + }); + this.options = options; + if (!$.isArray(options.selected)) options.selected = []; + $(this.el).data('selected', options.selected); + this.addMulti(); + break; + } + // attach events + this.tmp = { + onChange : function (event) { obj.change.call(obj, event) }, + onClick : function (event) { obj.click.call(obj, event) }, + onFocus : function (event) { obj.focus.call(obj, event) }, + onBlur : function (event) { obj.blur.call(obj, event) }, + onKeydown : function (event) { obj.keyDown.call(obj, event) }, + onKeyup : function (event) { obj.keyUp.call(obj, event) }, + onKeypress : function (event) { obj.keyPress.call(obj, event) } + } + $(this.el) + .addClass('w2field') + .data('w2field', this) + .on('change', this.tmp.onChange) + .on('click', this.tmp.onClick) // ignore click because it messes overlays + .on('focus', this.tmp.onFocus) + .on('blur', this.tmp.onBlur) + .on('keydown', this.tmp.onKeydown) + .on('keyup', this.tmp.onKeyup) + .on('keypress', this.tmp.onKeypress) + .css({ + 'box-sizing' : 'border-box', + '-webkit-box-sizing' : 'border-box', + '-moz-box-sizing' : 'border-box', + '-ms-box-sizing' : 'border-box', + '-o-box-sizing' : 'border-box' + }); + // format initial value + this.change($.Event('change')); + }, + + clear: function () { + var obj = this; + var options = this.options; + // if money then clear value + if (['money', 'currency'].indexOf(this.type) != -1) { + $(this.el).val($(this.el).val().replace(options.moneyRE, '')); + } + if (this.type == 'percent') { + $(this.el).val($(this.el).val().replace(/%/g, '')); + } + if (this.type == 'color') { + $(this.el).removeAttr('maxlength'); + } + if (this.type == 'list') { + $(this.el).removeClass('w2ui-select'); + } + this.type = 'clear'; + var tmp = $(this.el).data('tmp'); + if (!this.tmp) return; + // restore paddings + if (typeof tmp != 'undefined') { + if (tmp && tmp['old-padding-left']) $(this.el).css('padding-left', tmp['old-padding-left']); + if (tmp && tmp['old-padding-right']) $(this.el).css('padding-right', tmp['old-padding-right']); + } + // remove events and data + $(this.el) + .val(this.clean($(this.el).val())) + .removeClass('w2field') + .removeData() // removes all attached data + .off('change', this.tmp.onChange) + .off('click', this.tmp.onClick) + .off('focus', this.tmp.onFocus) + .off('blur', this.tmp.onBlur) + .off('keydown', this.tmp.onKeydown) + .off('keyup', this.tmp.onKeyup) + .off('keypress', this.tmp.onKeypress); + // remove helpers + for (var h in this.helpers) $(this.helpers[h]).remove(); + this.helpers = {}; + }, + + refresh: function () { + var obj = this; + var options = this.options; + var selected = $(this.el).data('selected'); + var time = (new Date()).getTime(); + // enum + if (['list'].indexOf(this.type) != -1) { + $(obj.el).parent().css('white-space', 'nowrap'); // needs this for arrow alway to appear on the right side + // hide focus and show text + if (obj.helpers.prefix) obj.helpers.prefix.hide(); + setTimeout(function () { + var focus = obj.helpers.focus.find('input'); + if ($(focus).val() == '') { + $(focus).css('opacity', 0).prev().css('opacity', 0); + $(obj.el).val(selected && selected.text != null ? selected.text : ''); + $(obj.el).attr('placeholder', $(obj.el).attr('_placeholder')); + // if empty show no icon + if ($.isEmptyObject(selected)) { + if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); + } else { + if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.show(); + } + } else { + $(focus).css('opacity', 1).prev().css('opacity', 1); + if (obj.helpers && obj.helpers.prefix) obj.helpers.prefix.hide(); + $(obj.el).val(''); + $(obj.el).attr('_placeholder', $(obj.el).attr('placeholder')).removeAttr('placeholder'); + } + }, 1); + } + if (['enum', 'file'].indexOf(this.type) != -1) { + var html = ''; + for (var s in selected) { + var it = selected[s]; + var ren = ''; + if (typeof options.renderItem == 'function') { + ren = options.renderItem(it, s, '
        
      '); + } else { + ren = '
        
      '+ + (obj.type == 'enum' ? it.text : it.name + ' - '+ w2utils.size(it.size) +''); + } + html += '
    • '+ + ren +'
    • '; + } + var div = obj.helpers.multi; + var ul = div.find('ul'); + div.attr('style', div.attr('style') + ';' + options.style); + if ($(obj.el).attr('readonly')) div.addClass('w2ui-readonly'); else div.removeClass('w2ui-readonly'); + // celan + div.find('.w2ui-enum-placeholder').remove(); + ul.find('li').not('li.nomouse').remove(); + // add new list + if (html != '') { + ul.prepend(html); + } else if (typeof options.placeholder != 'undefined') { + var style = + 'padding-top: ' + $(this.el).css('padding-top') + ';'+ + 'padding-left: ' + $(this.el).css('padding-left') + '; ' + + 'box-sizing: ' + $(this.el).css('box-sizing') + '; ' + + 'line-height: ' + $(this.el).css('line-height') + '; ' + + 'font-size: ' + $(this.el).css('font-size') + '; ' + + 'font-family: ' + $(this.el).css('font-family') + '; '; + div.prepend('
      '+ options.placeholder + '
      '); + } + // ITEMS events + div.find('li') + .data('mouse', 'out') + .on('click', function (event) { + var item = selected[$(event.target).attr('index')]; + if ($(event.target).hasClass('nomouse')) return; + event.stopPropagation(); + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'click', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // default behavior + if ($(event.target).hasClass('w2ui-list-remove')) { + if ($(obj.el).attr('readonly')) return; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // default behavior + $().w2overlay(); + selected.splice($(event.target).attr('index'), 1); + $(obj.el).trigger('change'); + $(event.target).parent().fadeOut('fast'); + setTimeout(function () { + obj.refresh(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 300); + } + if (obj.type == 'file' && !$(event.target).hasClass('w2ui-list-remove')) { + var preview = ''; + if ((/image/i).test(item.type)) { // image + preview = '
      '+ + ' '+ + '
      '; + } + var td1 = 'style="padding: 3px; text-align: right; color: #777;"'; + var td2 = 'style="padding: 3px"'; + preview += '
      '+ + ' '+ + ' '+ + ' '+ + ' '+ + ' '+ + '
      Name:'+ item.name +'
      Size:'+ w2utils.size(item.size) +'
      Type:' + + ' '+ item.type +''+ + '
      Modified:'+ w2utils.date(item.modified) +'
      '+ + '
      '; + $(event.target).w2overlay(preview); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }) + .on('mouseover', function (event) { + var tmp = event.target; + if (tmp.tagName != 'LI') tmp = tmp.parentNode; + if ($(tmp).hasClass('nomouse')) return; + if ($(tmp).data('mouse') == 'out') { + var item = selected[$(tmp).attr('index')]; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'mouseOver', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + $(tmp).data('mouse', 'over'); + }) + .on('mouseout', function (event) { + var tmp = event.target; + if (tmp.tagName != 'LI') tmp = tmp.parentNode; + if ($(tmp).hasClass('nomouse')) return; + $(tmp).data('mouse', 'leaving'); + setTimeout(function () { + if ($(tmp).data('mouse') == 'leaving') { + $(tmp).data('mouse', 'out'); + var item = selected[$(tmp).attr('index')]; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'f', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + }, 0); + }); + // adjust height + $(this.el).height('auto'); + var cntHeight = $(div).find('> div').height() + w2utils.getSize(div, '+height') * 2; + if (cntHeight < 26) cntHeight = 26; + if (cntHeight > options.maxHeight) cntHeight = options.maxHeight; + if (div.length > 0) div[0].scrollTop = 1000; + var inpHeight = w2utils.getSize($(this.el), 'height') - 2; + if (inpHeight > cntHeight) cntHeight = inpHeight + $(div).css({ 'height': cntHeight + 'px', overflow: (cntHeight == options.maxHeight ? 'auto' : 'hidden') }); + if (cntHeight < options.maxHeight) $(div).prop('scrollTop', 0); + $(this.el).css({ 'height' : (cntHeight + 2) + 'px' }); + } + return (new Date()).getTime() - time; + }, + + reset: function () { + var obj = this; + var type = this.type; + this.clear(); + this.type = type; + this.init(); + }, + + clean: function (val) { + var options = this.options; + val = String(val).trim(); + // clean + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { + if (options.autoFormat && ['money', 'currency'].indexOf(this.type) != -1) val = String(val).replace(options.moneyRE, ''); + if (options.autoFormat && this.type == 'percent') val = String(val).replace(options.percentRE, ''); + if (options.autoFormat && ['int', 'float'].indexOf(this.type) != -1) val = String(val).replace(options.numberRE, ''); + if (parseFloat(val) == val) { + if (options.min !== null && val < options.min) { val = options.min; $(this.el).val(options.min); } + if (options.max !== null && val > options.max) { val = options.max; $(this.el).val(options.max); } + } + if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = ''; + } + return val; + }, + + format: function (val) { + var options = this.options; + // autoformat numbers or money + if (options.autoFormat && val != '') { + switch (this.type) { + case 'money': + case 'currency': + val = w2utils.formatNumber(Number(val).toFixed(options.currencyPrecision), options.groupSymbol); + if (val != '') val = options.currencyPrefix + val + options.currencySuffix; + break; + case 'percent': + val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); + if (val != '') val += '%'; + break; + case 'float': + val = w2utils.formatNumber(options.precision ? Number(val).toFixed(options.precision) : val, options.groupSymbol); + break; + case 'int': + val = w2utils.formatNumber(val, options.groupSymbol); + break; + } + } + return val; + }, + + change: function (event) { + var obj = this; + var options = obj.options; + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { + // check max/min + var val = $(this.el).val(); + var new_val = this.format(this.clean($(this.el).val())); + // if was modified + if (val != '' && val != new_val) { + $(this.el).val(new_val).change(); + // cancel event + event.stopPropagation(); + event.preventDefault(); + return false; + } + } + // color + if (this.type == 'color') { + var color = '#' + $(this.el).val(); + if ($(this.el).val().length != 6 && $(this.el).val().length != 3) color = ''; + $(this.el).next().find('div').css('background-color', color); + if ($(obj.el).is(':focus')) this.updateOverlay(); + } + }, + + click: function (event) { + event.stopPropagation(); + // lists + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + if (!$(this.el).is(':focus')) this.focus(event); + } + // other fields with drops + if (['date', 'time', 'color'].indexOf(this.type) != -1) { + this.updateOverlay(); + } + }, + + focus: function (event) { + var obj = this; + var options = this.options; + // color, date, time + if (['color', 'date', 'time'].indexOf(obj.type) !== -1) { + if ($(obj.el).attr('readonly')) return; + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + setTimeout(function () { obj.updateOverlay(); }, 150); + } + // menu + if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($(obj.el).attr('readonly')) return; + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + setTimeout(function () { + if (obj.type == 'list' && $(obj.el).is(':focus')) { + $(obj.helpers.focus).find('input').focus(); + return; + } + obj.search(); + setTimeout(function () { obj.updateOverlay(); }, 1); + }, 1); + } + // file + if (obj.type == 'file') { + $(obj.helpers.multi).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); + } + }, + + blur: function (event) { + var obj = this; + var options = obj.options; + var val = $(obj.el).val().trim(); + // hide overlay + if (['color', 'date', 'time', 'list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + } + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { + if (val !== '' && !obj.checkType(val)) { + $(obj.el).val('').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid number'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + } + // date or time + if (['date', 'time'].indexOf(obj.type) != -1) { + if (w2utils.isInt(obj.el.value)) { + $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); + } + // check if in range + if (val !== '' && !obj.inRange(obj.el.value)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not in range'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } else { + if (obj.type == 'date' && val !== '' && !w2utils.isDate(obj.el.value, options.format)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid date'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + if (obj.type == 'time' && val !== '' && !w2utils.isTime(obj.el.value)) { + $(obj.el).val('').removeData('selected').change(); + if (options.silent === false) { + $(obj.el).w2tag('Not a valid time'); + setTimeout(function () { $(obj.el).w2tag(''); }, 3000); + } + } + } + } + // clear search input + if (obj.type == 'enum') { + $(obj.helpers.multi).find('input').val('').width(20); + } + // file + if (obj.type == 'file') { + $(obj.helpers.multi).css({ 'outline': 'none' }); + } + }, + + keyPress: function (event) { + var obj = this; + var options = obj.options; + // ignore wrong pressed key + if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'color', 'alphanumeric'].indexOf(obj.type) != -1) { + // keyCode & charCode differ in FireFox + if (event.metaKey || event.ctrlKey || event.altKey || (event.charCode != event.keyCode && event.keyCode > 0)) return; + var ch = String.fromCharCode(event.charCode); + if (!obj.checkType(ch, true) && event.keyCode != 13) { + event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + return false; + } + } + // update date popup + if (['date', 'time'].indexOf(obj.type) != -1) { + setTimeout(function () { obj.updateOverlay(); }, 1); + } + }, + + keyDown: function (event, extra) { + var obj = this; + var options = obj.options; + var key = event.keyCode || (extra && extra.keyCode); + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { + if (!options.keyboard || $(obj.el).attr('readonly')) return; + var cancel = false; + var val = parseFloat($(obj.el).val().replace(options.moneyRE, '')) || 0; + var inc = options.step; + if (event.ctrlKey || event.metaKey) inc = 10; + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + $(obj.el).val((val + inc <= options.max || options.max === null ? Number((val + inc).toFixed(12)) : options.max)).change(); + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + $(obj.el).val((val - inc >= options.min || options.min === null ? Number((val - inc).toFixed(12)) : options.min)).change(); + cancel = true; + break; + } + if (cancel) { + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + }, 0); + } + } + // date + if (obj.type == 'date') { + if (!options.keyboard || $(obj.el).attr('readonly')) return; + var cancel = false; + var daymil = 24*60*60*1000; + var inc = 1; + if (event.ctrlKey || event.metaKey) inc = 10; + if (w2utils.isInt(obj.el.value)) { + $(obj.el).val(w2utils.formatDate(new Date(parseInt(obj.el.value)), options.format)).change(); + } + var dt = w2utils.isDate($(obj.el).val(), options.format, true); + if (!dt) { dt = new Date(); daymil = 0; } + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDate(dt.getTime() + daymil, options.format); + if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + var newDT = w2utils.formatDate(dt.getTime() - daymil, options.format); + if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); + $(obj.el).val(newDT).change(); + cancel = true; + break; + } + if (cancel) { + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + obj.updateOverlay(); + }, 0); + } + } + // time + if (obj.type == 'time') { + if (!options.keyboard || $(obj.el).attr('readonly')) return; + var cancel = false; + var inc = 1; + if (event.ctrlKey || event.metaKey) inc = 60; + if (w2utils.isInt(obj.el.value)) { + $(obj.el).val(w2utils.formatTime(new Date(parseInt(obj.el.value)), options.format)).change(); + } + var val = $(obj.el).val(); + var time = obj.toMin(val) || obj.toMin((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)); + switch (key) { + case 38: // up + if (event.shiftKey) break; // no action if shift key is pressed + time += inc; + cancel = true; + break; + case 40: // down + if (event.shiftKey) break; // no action if shift key is pressed + time -= inc; + cancel = true; + break; + } + if (cancel) { + $(obj.el).val(obj.fromMin(time)).change(); + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + }, 0); + } + } + // color + if (obj.type == 'color') { + if ($(obj.el).attr('readonly')) return; + // paste + if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { + $(obj.el).prop('maxlength', 7); + setTimeout(function () { + var val = $(obj).val(); + if (val.substr(0, 1) == '#') val = val.substr(1); + if (!w2utils.isHex(val)) val = ''; + $(obj).val(val).prop('maxlength', 6).change(); + }, 20); + } + if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { + if (typeof obj.tmp.cind1 == 'undefined') { + obj.tmp.cind1 = -1; + obj.tmp.cind2 = -1; + } else { + switch (key) { + case 38: // up + obj.tmp.cind1--; + break; + case 40: // down + obj.tmp.cind1++; + break; + case 39: // right + obj.tmp.cind2++; + break; + case 37: // left + obj.tmp.cind2--; + break; + } + if (obj.tmp.cind1 < 0) obj.tmp.cind1 = 0; + if (obj.tmp.cind1 > this.pallete.length - 1) obj.tmp.cind1 = this.pallete.length - 1; + if (obj.tmp.cind2 < 0) obj.tmp.cind2 = 0; + if (obj.tmp.cind2 > this.pallete[0].length - 1) obj.tmp.cind2 = this.pallete[0].length - 1; + } + if ([37, 38, 39, 40].indexOf(key) != -1) { + $(obj.el).val(this.pallete[obj.tmp.cind1][obj.tmp.cind2]).change(); + event.preventDefault(); + } + } + } + // list/select/combo + if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { + if ($(obj.el).attr('readonly')) return; + var cancel = false; + var selected = $(obj.el).data('selected'); + var focus = $(obj.helpers.focus).find('input'); + if (obj.type == 'list') { + if ([37, 38, 39, 40].indexOf(key) == -1) obj.refresh(); // arrows + } + // apply arrows + switch (key) { + case 27: // escape + if (obj.type == 'list') { + if ($(focus).val() == '') { + $(obj.el).data('selected', {}); + } else { + $(focus).val(''); + } + obj.refresh(); + event.stopPropagation(); // escape in field should not close popup + } + break; + case 37: // left + case 39: // right + // cancel = true; + break; + case 13: // enter + if ($('#w2ui-overlay').length == 0) break; // no action if overlay not open + var item = options.items[options.index]; + var multi = $(obj.helpers.multi).find('input'); + if (obj.type == 'enum') { + if (item != null) { + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + item = eventData.item; // need to reassign because it could be recreated by user + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete item.hidden; + delete obj.tmp.force_open; + selected.push(item); + $(obj.el).change(); + multi.val('').width(20); + obj.refresh(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } else { + // trigger event + item = { id: multi.val(), text: multi.val() } + var eventData = obj.trigger({ phase: 'before', type: 'new', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + item = eventData.item; // need to reassign because it could be recreated by user + // default behavior + if (typeof obj.onNew == 'function') { + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete obj.tmp.force_open; + selected.push(item); + $(obj.el).change(); + multi.val('').width(20); + obj.refresh(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + } else { + if (item) $(obj.el).data('selected', item).val(item.text).change(); + if ($(obj.el).val() == '' && $(obj.el).data('selected')) $(obj.el).removeData('selected').val('').change(); + if (obj.type == 'list') { + focus.val(''); + obj.refresh(); + } + // hide overlay + obj.tmp.force_hide = true; + } + break; + case 8: // delete + if (['enum'].indexOf(obj.type) != -1) { + if ($(obj.helpers.multi).find('input').val() == '' && selected.length > 0) { + var item = selected[selected.length - 1]; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); + if (eventData.isCancelled === true) return; + // default behavior + selected.pop(); + $(obj.el).trigger('change'); + obj.refresh(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + } + break; + case 38: // up + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index--; + while (options.index > 0 && options.items[options.index].hidden) options.index--; + if (options.index == 0 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } + cancel = true; + break; + case 40: // down + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : -1; + options.index++; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (options.index == options.items.length-1 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index--; + } + // show overlay if not shown + var input = obj.el; + if (['enum'].indexOf(obj.type) != -1) input = obj.helpers.multi.find('input'); + if ($(input).val() == '' && $('#w2ui-overlay').length == 0) { + obj.tmp.force_open = true; + } else { + cancel = true; + } + break; + } + if (cancel) { + if (options.index < 0) options.index = 0; + if (options.index >= options.items.length) options.index = options.items.length -1; + obj.updateOverlay(); + // cancel event + event.preventDefault(); + setTimeout(function () { + // set cursor to the end + if (obj.type == 'enum') { + var tmp = obj.helpers.multi.find('input').get(0); + tmp.setSelectionRange(tmp.value.length, tmp.value.length); + } else if (obj.type == 'list') { + var tmp = obj.helpers.focus.find('input').get(0); + tmp.setSelectionRange(tmp.value.length, tmp.value.length); + } else { + obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); + } + }, 0); + return; + } + // expand input + if (obj.type == 'enum') { + var input = obj.helpers.multi.find('input'); + var search = input.val(); + input.width(((search.length + 2) * 8) + 'px'); + } + // run search + if ([16, 17, 18, 20, 37, 39, 91].indexOf(key) == -1) { // no refreah on crtl, shift, left/right arrows, etc + setTimeout(function () { + if (!obj.tmp.force_hide) obj.request(); + obj.search(); + }, 1); + } + } + }, + + keyUp: function (event) { + if (this.type == 'color') { + if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) $(this).prop('maxlength', 6); + } + }, + + clearCache: function () { + var options = this.options; + options.items = []; + this.tmp.xhr_loading = false; + this.tmp.xhr_search = ''; + this.tmp.xhr_total = -1; + this.search(); + }, + + request: function (interval) { + var obj = this; + var options = this.options; + var search = $(obj.el).val() || ''; + // if no url - do nothing + if (!options.url) return; + // -- + if (obj.type == 'enum') { + var tmp = $(obj.helpers.multi).find('input'); + if (tmp.length == 0) search = ''; else search = tmp.val(); + } + if (obj.type == 'list') { + var tmp = $(obj.helpers.focus).find('input'); + if (tmp.length == 0) search = ''; else search = tmp.val(); + } + if (options.minLength != 0 && search.length < options.minLength) { + options.items = []; // need to empty the list + this.updateOverlay(); + return; + } + if (typeof interval == 'undefined') interval = 350; + if (typeof obj.tmp.xhr_search == 'undefined') obj.tmp.xhr_search = ''; + if (typeof obj.tmp.xhr_total == 'undefined') obj.tmp.xhr_total = -1; + // check if need to search + if (options.url && ( + (options.items.length === 0 && obj.tmp.xhr_total !== 0) || + (obj.tmp.xhr_total == options.cacheMax && search.length > obj.tmp.xhr_search.length) || + (search.length >= obj.tmp.xhr_search.length && search.substr(0, obj.tmp.xhr_search.length) != obj.tmp.xhr_search) || + (search.length < obj.tmp.xhr_search.length) + )) { + // empty list + obj.tmp.xhr_loading = true; + obj.search(); + // timeout + clearTimeout(obj.tmp.timeout); + obj.tmp.timeout = setTimeout(function () { + // trigger event + var url = options.url; + var postData = { + search : search, + max : options.cacheMax + }; + $.extend(postData, options.postData); + var eventData = obj.trigger({ phase: 'before', type: 'request', target: obj.el, url: url, postData: postData }); + if (eventData.isCancelled === true) return; + url = eventData.url; + postData = eventData.postData; + // console.log('REMOTE SEARCH:', search); + if (obj.tmp.xhr) obj.tmp.xhr.abort(); + obj.tmp.xhr = $.ajax({ + type : 'POST', + url : url, + data : postData + }) + .done(function (data, status, xhr) { + // trigger event + var eventData2 = obj.trigger({ phase: 'before', type: 'load', target: obj.el, search: postData.search, data: data, xhr: xhr }); + if (eventData2.isCancelled === true) return; + // default behavior + data = eventData2.data; + if (typeof data == 'string') data = JSON.parse(data); + if (data.status != 'success') { + console.log('ERROR: server did not return proper structure. It should return', { status: 'success', items: [{ id: 1, text: 'item' }] }); + return; + } + // remove all extra items if more then needed for cache + if (data.items.length > options.cacheMax) data.items.splice(options.cacheMax, 100000); + // remember stats + obj.tmp.xhr_loading = false; + obj.tmp.xhr_search = search; + obj.tmp.xhr_total = data.items.length; + options.items = data.items; + if (search == '' && data.items.length == 0) obj.tmp.emptySet = true; else obj.tmp.emptySet = false; + obj.search(); + // console.log('-->', 'retrieved:', obj.tmp.xhr_total); + // event after + obj.trigger($.extend(eventData2, { phase: 'after' })); + }) + .error(function (xhr, status, exceptionThrown) { + // trigger event + var errorObj = { status: status, exceptionThrown: exceptionThrown, rawResponseText: xhr.responseText }; + var eventData2 = obj.trigger({ phase: 'before', type: 'error', target: obj.el, search: search, error: errorObj, xhr: xhr }); + if (eventData2.isCancelled === true) return; + // default behavior + console.log('ERROR: server communication failed. The server should return', { status: 'success', items: [{ id: 1, text: 'item' }] }, ', instead the AJAX request produced this: ', errorObj); + // reset stats + obj.clearCache(); + // event after + obj.trigger($.extend(eventData2, { phase: 'after' })); + }); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, interval); + } + }, + + search: function () { + var obj = this; + var options = this.options; + var search = $(obj.el).val(); + var target = obj.el; + var ids = []; + var selected= $(obj.el).data('selected'); + if (obj.type == 'enum') { + target = $(obj.helpers.multi).find('input'); + search = target.val(); + for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } + } + if (obj.type == 'list') { + target = $(obj.helpers.focus).find('input'); + search = target.val(); + for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } + } + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'search', target: target, search: search }); + if (eventData.isCancelled === true) return; + if (obj.tmp.xhr_loading !== true) { + var shown = 0; + for (var i in options.items) { + var item = options.items[i]; + var prefix = ''; + var suffix = ''; + if (['is', 'begins'].indexOf(options.match) != -1) prefix = '^'; + if (['is', 'ends'].indexOf(options.match) != -1) suffix = '$'; + try { + var re = new RegExp(prefix + search + suffix, 'i'); + if (re.test(item.text) || item.text == '...') item.hidden = false; else item.hidden = true; + } catch (e) {} + // do not show selected items + if (obj.type == 'enum' && $.inArray(item.id, ids) != -1) item.hidden = true; + if (item.hidden !== true) shown++; + } + if (obj.type != 'combo') { // don't preselect first for combo + options.index = 0; + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } else { + options.index = -1; + } + if (shown <= 0) options.index = -1; + options.spinner = false; + obj.updateOverlay(); + setTimeout(function () { + var html = $('#w2ui-overlay').html() || ''; + if (options.markSearch && html.indexOf('$.fn.w2menuHandler') != -1) { // do not highlight when no items + $('#w2ui-overlay').w2marker(search); + } + }, 1); + } else { + options.items.splice(0, options.cacheMax); + options.spinner = true; + obj.updateOverlay(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + updateOverlay: function () { + var obj = this; + var options = this.options; + // color + if (this.type == 'color') { + if ($(obj.el).attr('readonly')) return; + if ($('#w2ui-overlay').length == 0) { + $(obj.el).w2overlay(obj.getColorHTML()); + } else { + $('#w2ui-overlay').html(obj.getColorHTML()); + } + // bind events + $('#w2ui-overlay .color') + .on('mousedown', function (event) { + var color = $(event.originalEvent.target).attr('name'); + var index = $(event.originalEvent.target).attr('index').split(':'); + obj.tmp.cind1 = index[0]; + obj.tmp.cind2 = index[1]; + $(obj.el).val(color).change(); + $(this).html('•'); + }) + .on('mouseup', function () { + setTimeout(function () { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); + }, 10); + }); + } + // date + if (this.type == 'date') { + if ($(obj.el).attr('readonly')) return; + if ($('#w2ui-overlay').length == 0) { + $(obj.el).w2overlay('
      ', { + css: { "background-color": "#f5f5f5" } + }); + } + var month, year; + var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true); + if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } + (function refreshCalendar(month, year) { + $('#w2ui-overlay > div > div').html(obj.getMonthHTML(month, year)); + $('#w2ui-overlay .w2ui-calendar-title') + .on('mousedown', function () { + if ($(this).next().hasClass('w2ui-calendar-jump')) { + $(this).next().remove(); + } else { + var selYear, selMonth; + $(this).after('
      '); + $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); + setTimeout(function () { + $('#w2ui-overlay .w2ui-calendar-jump') + .find('.w2ui-jump-month, .w2ui-jump-year') + .on('click', function () { + if ($(this).hasClass('w2ui-jump-month')) { + $(this).parent().find('.w2ui-jump-month').removeClass('selected'); + $(this).addClass('selected'); + selMonth = $(this).attr('name'); + } + if ($(this).hasClass('w2ui-jump-year')) { + $(this).parent().find('.w2ui-jump-year').removeClass('selected'); + $(this).addClass('selected'); + selYear = $(this).attr('name'); + } + if (selYear != null && selMonth != null) { + $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); + setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); + } + }); + $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); + }, 1); + } + }); + $('#w2ui-overlay .w2ui-date') + .on('mousedown', function () { + var day = $(this).attr('date'); + $(obj.el).val(day).change(); + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + }) + .on('mouseup', function () { + setTimeout(function () { + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); + }, 10); + }); + $('#w2ui-overlay .previous').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) - 1; + refreshCalendar(tmp[0], tmp[1]); + }); + $('#w2ui-overlay .next').on('mousedown', function () { + var tmp = obj.options.current.split('/'); + tmp[0] = parseInt(tmp[0]) + 1; + refreshCalendar(tmp[0], tmp[1]); + }); + }) (month, year); + } + // date + if (this.type == 'time') { + if ($(obj.el).attr('readonly')) return; + if ($('#w2ui-overlay').length == 0) { + $(obj.el).w2overlay('
      ', { + css: { "background-color": "#fff" } + }); + } + var h24 = (this.options.format == 'h24' ? true : false); + $('#w2ui-overlay > div').html(obj.getHourHTML()); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function (event) { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + var hour = $(this).attr('hour'); + $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }) + .on('mouseup', function () { + var hour = $(this).attr('hour'); + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + $(obj.el).w2overlay('
      ', { css: { "background-color": "#fff" } }); + $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); + $('#w2ui-overlay .w2ui-time') + .on('mousedown', function () { + $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); + var min = $(this).attr('min'); + $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); + }) + .on('mouseup', function () { + setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); + }); + }); + } + // list + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + var el = this.el; + var input = this.el; + if (this.type == 'enum') { + el = $(this.helpers.multi); + input = $(el).find('input'); + } + if (this.type == 'list') { + input = $(this.helpers.focus).find('input'); + } + if ($(input).is(':focus')) { + if (options.openOnFocus === false && $(input).val() == '' && obj.tmp.force_open !== true) { + $().w2overlay(); + return; + } + if (obj.tmp.force_hide) { + $().w2overlay(); + setTimeout(function () { + delete obj.tmp.force_hide; + }, 1); + return; + } + if ($(input).val() != '') delete obj.tmp.force_open; + if ($('#w2ui-overlay').length == 0) options.index = 0; + var msgNoItems = w2utils.lang('No matches'); + if (options.url != null && $(input).val().length < options.minLength && obj.tmp.emptySet !== true) msgNoItems = options.minLength + ' ' + w2utils.lang('letters or more...'); + if (options.url != null && $(input).val() == '' && obj.tmp.emptySet !== true) msgNoItems = w2utils.lang('Type to search....'); + $(el).w2menu('refresh', $.extend(true, {}, options, { + search : false, + render : options.renderDrop, + maxHeight : options.maxDropHeight, + msgNoItems : msgNoItems, + // selected with mouse + onSelect: function (event) { + if (obj.type == 'enum') { + var selected = $(obj.el).data('selected'); + if (event.item) { + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: event.item }); + if (eventData.isCancelled === true) return; + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop(); + delete event.item.hidden; + selected.push(event.item); + $(obj.el).data('selected', selected).change(); + $(obj.helpers.multi).find('input').val('').width(20); + obj.refresh(); + if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + } else { + $(obj.el).data('selected', event.item).val(event.item.text).change(); + if (obj.helpers.focus) { + obj.helpers.focus.find('input').val(''); + obj.refresh(); + } + } + } + })); + } + } + }, + + inRange: function (str) { + var inRange = false; + if (this.type == 'date') { + var dt = w2utils.isDate(str, this.options.format, true); + if (dt) { + // enable range + if (this.options.start || this.options.end) { + var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); + var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); + var start = w2utils.isDate(st, this.options.format, true); + var end = w2utils.isDate(en, this.options.format, true); + var current = new Date(dt); + if (!start) start = current; + if (!end) end = current; + if (current >= start && current <= end) inRange = true; + } else { + inRange = true; + } + // block predefined dates + if (this.options.blocked && $.inArray(str, this.options.blocked) != -1) inRange = false; + } + } + if (this.type == 'time') { + if (this.options.start || this.options.end) { + var tm = this.toMin(str); + var tm1 = this.toMin(this.options.start); + var tm2 = this.toMin(this.options.end); + if (!tm1) tm1 = tm; + if (!tm2) tm2 = tm; + if (tm >= tm1 && tm <= tm2) inRange = true; + } else { + inRange = true; + } + } + return inRange; + }, + + /* + * INTERNAL FUNCTIONS + */ + + checkType: function (ch, loose) { + var obj = this; + switch (obj.type) { + case 'int': + if (loose && ['-'].indexOf(ch) != -1) return true; + return w2utils.isInt(ch.replace(obj.options.numberRE, '')); + case 'percent': + ch = ch.replace(/%/g, ''); + case 'float': + if (loose && ['-','.'].indexOf(ch) != -1) return true; + return w2utils.isFloat(ch.replace(obj.options.numberRE, '')); + case 'money': + case 'currency': + if (loose && ['-', '.', obj.options.groupSymbol, obj.options.currencyPrefix, obj.options.currencySuffix].indexOf(ch) != -1) return true; + return w2utils.isFloat(ch.replace(obj.options.moneyRE, '')); + case 'hex': + case 'color': + return w2utils.isHex(ch); + case 'alphanumeric': + return w2utils.isAlphaNumeric(ch); + } + return true; + }, + + addPrefix: function () { + var obj = this; + setTimeout(function () { + if (obj.type === 'clear') return; + var helper; + var tmp = $(obj.el).data('tmp') || {}; + if (tmp['old-padding-left']) $(obj.el).css('padding-left', tmp['old-padding-left']); + tmp['old-padding-left'] = $(obj.el).css('padding-left'); + $(obj.el).data('tmp', tmp); + if (obj.options.prefix !== '') { + // remove if already displaed + if (obj.helpers.prefix) $(obj.helpers.prefix).remove(); + // add fresh + $(obj.el).before( + '
      '+ + obj.options.prefix + + '
      ' + ); + helper = $(obj.el).prev(); + helper + .css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'padding-top' : $(obj.el).css('padding-top'), + 'padding-bottom' : $(obj.el).css('padding-bottom'), + 'padding-left' : $(obj.el).css('padding-left'), + 'padding-right' : 0, + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', + 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px', + 'margin-left' : $(obj.el).css('margin-left'), + 'margin-right' : 0 + }) + .on('click', function (event) { + if (obj.options.icon && typeof obj.onIconClick == 'function') { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'iconClick', target: obj.el, el: $(this).find('span.w2ui-icon')[0] }); + if (eventData.isCancelled === true) return; + + // intentionally empty + + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } else { + if (obj.type == 'list') { + $(obj.helpers.focus).find('input').focus(); + } else { + $(obj.el).focus(); + } + } + }); + $(obj.el).css('padding-left', (helper.width() + parseInt($(obj.el).css('padding-left'), 10)) + 'px'); + // remember helper + obj.helpers.prefix = helper; + } + }, 1); + }, + + addSuffix: function () { + var obj = this; + var helper, pr; + setTimeout(function () { + if (obj.type === 'clear') return; + var tmp = $(obj.el).data('tmp') || {}; + if (tmp['old-padding-right']) $(obj.el).css('padding-right', tmp['old-padding-right']); + tmp['old-padding-right'] = $(obj.el).css('padding-right'); + $(obj.el).data('tmp', tmp); + pr = parseInt($(obj.el).css('padding-right'), 10); + if (obj.options.arrows) { + // remove if already displaed + if (obj.helpers.arrows) $(obj.helpers.arrows).remove(); + // add fresh + $(obj.el).after( + '
       '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '); + var height = w2utils.getSize(obj.el, 'height'); + helper = $(obj.el).next(); + helper.css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'height' : ($(obj.el).height() + parseInt($(obj.el).css('padding-top'), 10) + parseInt($(obj.el).css('padding-bottom'), 10) ) + 'px', + 'padding' : 0, + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', + 'margin-bottom' : 0, + 'border-left' : '1px solid silver' + }) + .css('margin-left', '-'+ (helper.width() + parseInt($(obj.el).css('margin-right'), 10) + 12) + 'px') + .on('mousedown', function (event) { + $('body').on('mouseup', tmp); + $('body').data('_field_update_timer', setTimeout(update, 700)); + update(false); + // timer function + function tmp() { + clearTimeout($('body').data('_field_update_timer')); + $('body').off('mouseup', tmp); + } + // update function + function update(notimer) { + $(obj.el).focus(); + obj.keyDown($.Event("keydown"), { + keyCode : ($(event.target).attr('type') == 'up' ? 38 : 40) + }); + if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60)); + } + }); + pr += helper.width() + 12; + $(obj.el).css('padding-right', pr + 'px'); + // remember helper + obj.helpers.arrows = helper; + } + if (obj.options.suffix !== '') { + // remove if already displaed + if (obj.helpers.suffix) $(obj.helpers.suffix).remove(); + // add fresh + $(obj.el).after( + '
      '+ + obj.options.suffix + + '
      '); + helper = $(obj.el).next(); + helper + .css({ + 'color' : $(obj.el).css('color'), + 'font-family' : $(obj.el).css('font-family'), + 'font-size' : $(obj.el).css('font-size'), + 'padding-top' : $(obj.el).css('padding-top'), + 'padding-bottom' : $(obj.el).css('padding-bottom'), + 'padding-left' : '3px', + 'padding-right' : $(obj.el).css('padding-right'), + 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', + 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px' + }) + .on('click', function (event) { + if (obj.type == 'list') { + $(obj.helpers.focus).find('input').focus(); + } else { + $(obj.el).focus(); + } + }); + + helper.css('margin-left', '-'+ (w2utils.getSize(helper, 'width') + parseInt($(obj.el).css('margin-right'), 10) + 2) + 'px'); + pr += helper.width() + 3; + $(obj.el).css('padding-right', pr + 'px'); + // remember helper + obj.helpers.suffix = helper; + } + }, 1); + }, + + addFocus: function () { + var obj = this; + var options = this.options; + var width = 0; // 11 - show search icon, 0 do not show + if (options.icon) width = 11; + // clean up & init + $(obj.helpers.focus).remove(); + // build helper + var html = + '
      '+ + ' '+ + ' '+ + '
      '; + $(obj.el).attr('tabindex', -1).before(html); + var helper = $(obj.el).prev(); + obj.helpers.focus = helper; + helper.css({ + width : $(obj.el).width(), + "margin-top" : $(obj.el).css('margin-top'), + "margin-left" : (parseInt($(obj.el).css('margin-left')) + parseInt($(obj.el).css('padding-left'))) + 'px', + "margin-bottom" : $(obj.el).css('margin-bottom'), + "margin-right" : $(obj.el).css('margin-right'), + }) + .find('input') + .css({ + cursor : 'default', + width : '100%', + outline : 'none', + opacity : 1, + margin : 0, + border : '1px solid transparent', + padding : $(obj.el).css('padding-top'), + "padding-left" : 0, + "margin-left" : width + (width > 0 ? 6 : 0), + "background-color" : 'transparent' + }); + // INPUT events + helper.find('input') + .on('click', function (event) { + if ($('#w2ui-overlay').length == 0) obj.focus(event); + event.stopPropagation(); + }) + .on('focus', function (event) { + $(obj.el).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); + $(this).val(''); + $(obj.el).triggerHandler('focus'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('blur', function (event) { + $(obj.el).css('outline', 'none'); + $(this).val(''); + obj.refresh(); + $(obj.el).triggerHandler('blur'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('keyup', function (event) { obj.keyUp(event) }) + .on('keydown', function (event) { obj.keyDown(event) }) + .on('keypress', function (event) { obj.keyPress(event); }); + // MAIN div + helper.on('click', function (event) { $(this).find('input').focus(); }); + obj.refresh(); + }, + + addMulti: function () { + var obj = this; + var options = this.options; + // clean up & init + $(obj.helpers.multi).remove(); + // build helper + var html = ''; + var margin = + 'margin-top : 0px; ' + + 'margin-bottom : 0px; ' + + 'margin-left : ' + $(obj.el).css('margin-left') + '; ' + + 'margin-right : ' + $(obj.el).css('margin-right') + '; '+ + 'width : ' + (w2utils.getSize(obj.el, 'width') + - parseInt($(obj.el).css('margin-left'), 10) + - parseInt($(obj.el).css('margin-right'), 10)) + + 'px;'; + if (obj.type == 'enum') { + html = '
      '+ + '
      '+ + '
        '+ + '
      • '+ + ' '+ + '
      • ' + '
      '+ + '
      '+ + '
      '; + } + if (obj.type == 'file') { + html = '
      '+ + '
      '+ + '
      '+ + ' ' + '
      '+ + '
      '; + } + $(obj.el) + .before(html) + .css({ + 'background-color' : 'transparent', + 'border-color' : 'transparent' + }); + + var div = $(obj.el).prev(); + obj.helpers.multi = div; + if (obj.type == 'enum') { + $(obj.el).attr('tabindex', -1); + // INPUT events + div.find('input') + .on('click', function (event) { + if ($('#w2ui-overlay').length == 0) obj.focus(event); + $(obj.el).triggerHandler('click'); + }) + .on('focus', function (event) { + $(div).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); + $(obj.el).triggerHandler('focus'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('blur', function (event) { + $(div).css('outline', 'none'); + $(obj.el).triggerHandler('blur'); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + }) + .on('keyup', function (event) { obj.keyUp(event) }) + .on('keydown', function (event) { obj.keyDown(event) }) + .on('keypress', function (event) { div.find('.w2ui-enum-placeholder').remove(); obj.keyPress(event); }); + // MAIN div + div.on('click', function (event) { $(this).find('input').focus(); }); + } + if (obj.type == 'file') { + $(obj.el).css('outline', 'none'); + div.on('click', function (event) { + $(obj.el).focus(); + if ($(obj.el).attr('readonly')) return; + obj.blur(event); + div.find('input').click(); + }) + .on('dragenter', function (event) { + if ($(obj.el).attr('readonly')) return; + $(div).addClass('w2ui-file-dragover'); + }) + .on('dragleave', function (event) { + if ($(obj.el).attr('readonly')) return; + var tmp = $(event.target).parents('.w2ui-field-helper'); + if (tmp.length == 0) $(div).removeClass('w2ui-file-dragover'); + }) + .on('drop', function (event) { + if ($(obj.el).attr('readonly')) return; + $(div).removeClass('w2ui-file-dragover'); + var files = event.originalEvent.dataTransfer.files; + for (var i=0, l=files.length; i options.maxFileSize) { + err = 'Maximum file size is '+ w2utils.size(options.maxFileSize); + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { + err = 'Maximum total size is '+ w2utils.size(options.maxSize); + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + if (options.max !== 0 && cnt >= options.max) { + err = 'Maximum number of files is '+ options.max; + if (options.silent === false) $(obj.el).w2tag(err); + console.log('ERROR: '+ err); + return; + } + selected.push(newItem); + // read file as base64 + if (typeof FileReader !== "undefined") { + var reader = new FileReader(); + // need a closure + reader.onload = (function () { + return function (event) { + var fl = event.target.result; + var ind = fl.indexOf(','); + newItem.content = fl.substr(ind+1); + obj.refresh(); + $(obj.el).trigger('change'); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }; + })(); + reader.readAsDataURL(file); + } else { + obj.refresh(); + $(obj.el).trigger('change'); + } + }, + + normMenu: function (menu) { + if ($.isArray(menu)) { + for (var m = 0; m < menu.length; m++) { + if (typeof menu[m] == 'string') { + menu[m] = { id: menu[m], text: menu[m] }; + } else { + if (typeof menu[m].text != 'undefined' && typeof menu[m].id == 'undefined') menu[m].id = menu[m].text; + if (typeof menu[m].text == 'undefined' && typeof menu[m].id != 'undefined') menu[m].text = menu[m].id; + if (typeof menu[m].caption != 'undefined') menu[m].text = menu[m].caption; + } + } + return menu; + } else if (typeof menu == 'object') { + var tmp = [] + for (var m in menu) tmp.push({ id: m, text: menu[m] }); + return tmp; + } + }, + + getColorHTML: function () { + var html = '
      '+ + ''; + for (var i = 0; i < 8; i++) { + html += ''; + for (var j = 0; j < 8; j++) { + html += ''; + } + html += ''; + if (i < 2) html += ''; + } + html += '
      '+ + '
      '+ + ' '+ ($(this.el).val() == this.pallete[i][j] ? '•' : ' ')+ + '
      '+ + '
      '; + return html; + }, + + getMonthHTML: function (month, year) { + var td = new Date(); + var months = w2utils.settings.fullmonths; + var days = w2utils.settings.fulldays; + var daysCount = ['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31']; + var today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate(); + // normalize date + year = w2utils.isInt(year) ? parseInt(year) : td.getFullYear(); + month = w2utils.isInt(month) ? parseInt(month) : td.getMonth() + 1; + if (month > 12) { month -= 12; year++; } + if (month < 1 || month === 0) { month += 12; year--; } + if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; } + this.options.current = month + '/' + year; + + // start with the required date + td = new Date(year, month-1, 1); + var weekDay = td.getDay(); + var tabDays = w2utils.settings.shortdays; + var dayTitle = ''; + for ( var i = 0, len = tabDays.length; i < len; i++) { + dayTitle += '' + tabDays[i] + ''; + } + var html = + '
      '+ + ' '+ + ' '+ + months[month-1] +', '+ year + + '
      '+ + ''+ + ' ' + dayTitle + ''+ + ' '; + + var day = 1; + for (var ci=1; ci<43; ci++) { + if (weekDay === 0 && ci == 1) { + for (var ti=0; ti<6; ti++) html += ''; + ci += 6; + } else { + if (ci < weekDay || day > daysCount[month-1]) { + html += ''; + if ((ci) % 7 === 0) html += ''; + continue; + } + } + var dt = year + '/' + month + '/' + day; + + var className = ''; + if (ci % 7 == 6) className = ' w2ui-saturday'; + if (ci % 7 === 0) className = ' w2ui-sunday'; + if (dt == today) className += ' w2ui-today'; + + var dspDay = day; + var col = ''; + var bgcol = ''; + var tmp_dt = w2utils.formatDate(dt, this.options.format); + if (this.options.colored && this.options.colored[tmp_dt] !== undefined) { // if there is predefined colors for dates + tmp = this.options.colored[tmp_dt].split(':'); + bgcol = 'background-color: ' + tmp[0] + ';'; + col = 'color: ' + tmp[1] + ';'; + } + html += ''; + if (ci % 7 === 0 || (weekDay === 0 && ci == 1)) html += ''; + day++; + } + html += '
        
      '+ + dspDay + + '
      '; + return html; + }, + + getYearHTML: function () { + var months = w2utils.settings.shortmonths; + var mhtml = ''; + var yhtml = ''; + for (var m in months) { + mhtml += '
      '+ months[m] + '
      '; + } + for (var y = 1950; y <= 2020; y++) { + yhtml += '
      '+ y + '
      ' + } + return '
      '+ mhtml +'
      '+ yhtml +'
      '; + }, + + getHourHTML: function () { + var tmp = []; + var h24 = (this.options.format == 'h24' ? true : false); + for (var a=0; a<24; a++) { + var time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : ''); + if (a == 12 && !h24) time = '12:00 pm'; + if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = ''; + var tm1 = this.fromMin(this.toMin(time)); + var tm2 = this.fromMin(this.toMin(time) + 59); + tmp[Math.floor(a/8)] += '
      '+ time +'
      '; + } + var html = + '
      '+ + ' ' + + ' ' + + ' ' + + '
      '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
      '; + return html; + }, + + getMinHTML: function (hour) { + if (typeof hour == 'undefined') hour = 0; + var h24 = (this.options.format == 'h24' ? true : false); + var tmp = []; + for (var a=0; a<60; a+=5) { + var time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : ''); + var ind = a < 20 ? 0 : (a < 40 ? 1 : 2); + if (!tmp[ind]) tmp[ind] = ''; + tmp[ind] += '
      '+ time +'
      '; + } + var html = + '
      '+ + ' ' + + ' ' + + ' ' + + '
      '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
      '; + return html; + }, + + toMin: function (str) { + if (typeof str != 'string') return null; + var tmp = str.split(':'); + if (tmp.length == 2) { + tmp[0] = parseInt(tmp[0]); + tmp[1] = parseInt(tmp[1]); + if (str.indexOf('pm') != -1 && tmp[0] != 12) tmp[0] += 12; + } else { + return null; + } + return tmp[0] * 60 + tmp[1]; + }, + + fromMin: function (time) { + var ret = ''; + if (time >= 24 * 60) time = time % (24 * 60); + if (time < 0) time = 24 * 60 + time; + var hour = Math.floor(time/60); + var min = ((time % 60) < 10 ? '0' : '') + (time % 60); + if (this.options.format.indexOf('h24') != -1) { + ret = hour + ':' + min; + } else { + ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am'); + } + return ret; + } + } + + $.extend(w2field.prototype, w2utils.event); + w2obj.field = w2field; }) (jQuery); /************************************************************************ * Library: Web 2.0 UI for jQuery (using prototypical inheritance) * - Following objects defined -* - w2form - form widget -* - $().w2form - jQuery wrapper +* - w2form - form widget +* - $().w2form - jQuery wrapper * - Dependencies: jQuery, w2utils, w2fields, w2tabs, w2toolbar, w2alert * * == NICE TO HAVE == -* - refresh(field) - would refresh only one field -* - include delta on save -* - create an example how to do cascadic dropdown -* - form should read into items +* - two way data bindings +* - verify validation of fields +* - when field is blank, set record.field = null +* - show/hide a field * * == 1.4 Changes == -* - refactored for the new fields -* - added getChanges() - not complete -* - change: get() w/o params returns all field names +* - refactored for the new fields +* - added getChanges() - not complete +* - change: get() w/o params returns all field names * ************************************************************************/ (function () { - var w2form = function(options) { - // public properties - this.name = null; - this.header = ''; - this.box = null; // HTML element that hold this element - this.url = ''; - this.formURL = ''; // url where to get form HTML - this.formHTML = ''; // form HTML (might be loaded from the url) - this.page = 0; // current page - this.recid = 0; // can be null or 0 - this.fields = []; - this.actions = {}; - this.record = {}; - this.original = {}; - this.postData = {}; - this.toolbar = {}; // if not empty, then it is toolbar - this.tabs = {}; // if not empty, then it is tabs object - - this.style = ''; - this.focus = 0; // focus first or other element - this.msgNotJSON = w2utils.lang('Return data is not in JSON format.'); - this.msgAJAXerror = w2utils.lang('AJAX error. See console for more details.'); - this.msgRefresh = w2utils.lang('Refreshing...'); - this.msgSaving = w2utils.lang('Saving...'); - - // events - this.onRequest = null; - this.onLoad = null; - this.onValidate = null; - this.onSubmit = null; - this.onSave = null; - this.onChange = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; - this.onAction = null; - this.onToolbar = null; - this.onError = null; - - // internal - this.isGenerated = false; - this.last = { - xhr : null // jquery xhr requests - } - - $.extend(true, this, w2obj.form, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2form = function(method) { - if (typeof method === 'object' || !method ) { - var obj = this; - // check name parameter - if (!w2utils.checkName(method, 'w2form')) return; - // remember items - var record = method.record; - var original = method.original; - var fields = method.fields; - var toolbar = method.toolbar; - var tabs = method.tabs; - // extend items - var object = new w2form(method); - $.extend(object, { record: {}, original: {}, fields: [], tabs: {}, toolbar: {}, handlers: [] }); - if ($.isArray(tabs)) { - $.extend(true, object.tabs, { tabs: [] }); - for (var t in tabs) { - var tmp = tabs[t]; - if (typeof tmp === 'object') object.tabs.tabs.push(tmp); else object.tabs.tabs.push({ id: tmp, caption: tmp }); - } - } else { - $.extend(true, object.tabs, tabs); - } - $.extend(true, object.toolbar, toolbar); - // reassign variables - for (var p in fields) object.fields[p] = $.extend(true, {}, fields[p]); - for (var p in record) { - if ($.isPlainObject(record[p])) { - object.record[p] = $.extend(true, {}, record[p]); - } else { - object.record[p] = record[p]; - } - } - for (var p in original) { - if ($.isPlainObject(original[p])) { - object.original[p] = $.extend(true, {}, original[p]); - } else { - object.original[p] = original[p]; - } - } - if (obj.length > 0) object.box = obj[0]; - // render if necessary - if (object.formURL != '') { - $.get(object.formURL, function (data) { - object.formHTML = data; - object.isGenerated = true; - if ($(object.box).length != 0 || data.length != 0) { - $(object.box).html(data); - object.render(object.box); - } - }); - } else if (object.formHTML != '') { - // it is already loaded into formHTML - } else if ($(this).length != 0 && $.trim($(this).html()) != '') { - object.formHTML = $(this).html(); - } else { // try to generate it - object.formHTML = object.generateHTML(); - } - // register new object - w2ui[object.name] = object; - // render if not loaded from url - if (object.formURL == '') { - if (String(object.formHTML).indexOf('w2ui-page') == -1) { - object.formHTML = '
      '+ object.formHTML +'
      '; - } - $(object.box).html(object.formHTML); - object.isGenerated = true; - object.render(object.box); - } - return object; - - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2form'); - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2form.prototype = { - - get: function (field, returnIndex) { - if (arguments.length === 0) { - var all = []; - for (var f1 in this.fields) { - if (this.fields[f1].name != null) all.push(this.fields[f1].name); - } - return all; - } else { - for (var f2 in this.fields) { - if (this.fields[f2].name == field) { - if (returnIndex === true) return f2; else return this.fields[f2]; - } - } - return null; - } - }, - - set: function (field, obj) { - for (var f in this.fields) { - if (this.fields[f].name == field) { - $.extend(this.fields[f] , obj); - this.refresh(); - return true; - } - } - return false; - }, - - reload: function (callBack) { - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (url && this.recid != 0) { - //this.clear(); - this.request(callBack); - } else { - this.refresh(); - if (typeof callBack == 'function') callBack(); - } - }, - - clear: function () { - this.recid = 0; - this.record = {}; - $().w2tag(); - this.refresh(); - }, - - error: function (msg) { - var obj = this; - // let the management of the error outside of the grid - var eventData = this.trigger({ target: this.name, type: 'error', message: msg , xhr: this.last.xhr }); - if (eventData.isCancelled === true) { - if (typeof callBack == 'function') callBack(); - return; - } - // need a time out because message might be already up) - setTimeout(function () { w2alert(msg, 'Error'); }, 1); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - validate: function (showErrors) { - if (typeof showErrors == 'undefined') showErrors = true; - $().w2tag(); // hide all tags before validating - // validate before saving - var errors = []; - for (var f in this.fields) { - var field = this.fields[f]; - if (this.record[field.name] == null) this.record[field.name] = ''; - switch (field.type) { - case 'int': - if (this.record[field.name] && !w2utils.isInt(this.record[field.name])) { - errors.push({ field: field, error: w2utils.lang('Not an integer') }); - } - break; - case 'float': - if (this.record[field.name] && !w2utils.isFloat(this.record[field.name])) { - errors.push({ field: field, error: w2utils.lang('Not a float') }); - } - break; - case 'money': - if (this.record[field.name] && !w2utils.isMoney(this.record[field.name])) { - errors.push({ field: field, error: w2utils.lang('Not in money format') }); - } - break; - case 'color': - case 'hex': - if (this.record[field.name] && !w2utils.isHex(this.record[field.name])) { - errors.push({ field: field, error: w2utils.lang('Not a hex number') }); - } - break; - case 'email': - if (this.record[field.name] && !w2utils.isEmail(this.record[field.name])) { - errors.push({ field: field, error: w2utils.lang('Not a valid email') }); - } - break; - case 'checkbox': - // convert true/false - if (this.record[field.name] == true) this.record[field.name] = 1; else this.record[field.name] = 0; - break; - case 'date': - // format date before submit - if (this.record[field.name] && !w2utils.isDate(this.record[field.name], field.options.format)) { - errors.push({ field: field, error: w2utils.lang('Not a valid date') + ': ' + field.options.format }); - } else { - } - break; - case 'list': - case 'combo': - break; - case 'enum': - break; - } - // === check required - if field is '0' it should be considered not empty - var val = this.record[field.name]; - if ( field.required && (val === '' || ($.isArray(val) && val.length == 0)) ) { - errors.push({ field: field, error: w2utils.lang('Required field') }); - } - if ( field.equalto && this.record[field.name]!=this.record[field.equalto] ) { - errors.push({ field: field, error: w2utils.lang('Field should be equal to ')+field.equalto }); - } - } - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'validate', errors: errors }); - if (eventData.isCancelled === true) return; - // show error - if (showErrors) for (var e in eventData.errors) { - var err = eventData.errors[e]; - if (err.field.type == 'radio') { // for radio and checkboxes - $($(err.field.el).parents('div')[0]).w2tag(err.error, { "class": 'w2ui-error' }); - } else if (['enum', 'file'].indexOf(err.field.type) != -1) { - (function (err) { - setTimeout(function () { - var fld = $(err.field.el).data('w2field').helpers.multi; - $(err.field.el).w2tag(err.error); - $(fld).addClass('w2ui-error'); - }, 1); - })(err); - } else { - $(err.field.el).w2tag(err.error, { "class": 'w2ui-error' }); - } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return errors; - }, - - getChanges: function () { - var differ = function(record, original, result) { - for (var i in record) { - if (typeof record[i] == "object") { - result[i] = differ(record[i], original[i] || {}, {}); - if (!result[i] || $.isEmptyObject(result[i])) delete result[i]; - } else if (record[i] != original[i]) { - result[i] = record[i]; - } - } - return result; - } - return differ(this.record, this.original, {}); - }, - - request: function (postData, callBack) { // if (1) param then it is call back if (2) then postData and callBack - var obj = this; - // check for multiple params - if (typeof postData == 'function') { - callBack = postData; - postData = null; - } - if (typeof postData == 'undefined' || postData == null) postData = {}; - if (!this.url || (typeof this.url == 'object' && !this.url.get)) return; - if (this.recid == null || typeof this.recid == 'undefined') this.recid = 0; - // build parameters list - var params = {}; - // add list params - params['cmd'] = 'get-record'; - params['name'] = this.name; - params['recid'] = this.recid; - // append other params - $.extend(params, this.postData); - $.extend(params, postData); - // event before - var eventData = this.trigger({ phase: 'before', type: 'request', target: this.name, url: this.url, postData: params }); - if (eventData.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } - // default action - this.record = {}; - this.original = {}; - // call server to get data - this.lock(this.msgRefresh); - var url = eventData.url; - if (typeof eventData.url == 'object' && eventData.url.get) url = eventData.url.get; - if (this.last.xhr) try { this.last.xhr.abort(); } catch (e) {}; - this.last.xhr = $.ajax({ - type : 'GET', - url : url, - data : String($.param(eventData.postData, false)).replace(/%5B/g, '[').replace(/%5D/g, ']'), - dataType : 'text', - complete : function (xhr, status) { - obj.unlock(); - // event before - var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'load', xhr: xhr, status: status }); - if (eventData.isCancelled === true) { - if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); - return; - } - // parse server response - var data; - var responseText = obj.last.xhr.responseText; - if (status != 'error') { - // default action - if (typeof responseText != 'undefined' && responseText != '') { - // check if the onLoad handler has not already parsed the data - if (typeof responseText == "object") { - data = responseText; - } else { - // $.parseJSON or $.getJSON did not work because those expect perfect JSON data - where everything is in double quotes - // - // TODO: avoid (potentially malicious) code injection from the response. - try { eval('data = '+ responseText); } catch (e) { } - } - if (typeof data == 'undefined') { - data = { - status : 'error', - message : obj.msgNotJSON, - responseText : responseText - } - } - if (data['status'] == 'error') { - obj.error(data['message']); - } else { - obj.record = $.extend({}, data.record); - obj.original = $.extend({}, data.record); - } - } - } else { - obj.error('AJAX Error ' + xhr.status + ': '+ xhr.statusText); - data = { - status : 'error', - message : obj.msgAJAXerror, - responseText : responseText - }; - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.refresh(); - // call back - if (typeof callBack == 'function') callBack(data); - } - }); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - submit: function (postData, callBack) { - return this.save(postData, callBack); - }, - - save: function (postData, callBack) { - var obj = this; - $(this.box).find(':focus').change(); // trigger onchange - // check for multiple params - if (typeof postData == 'function') { - callBack = postData; - postData = null; - } - // validation - var errors = obj.validate(true); - if (errors.length !== 0) { - obj.goto(errors[0].field.page); - return; - } - // submit save - if (typeof postData == 'undefined' || postData == null) postData = {}; - if (!obj.url || (typeof obj.url == 'object' && !obj.url.save)) { - console.log("ERROR: Form cannot be saved because no url is defined."); - return; - } - obj.lock(obj.msgSaving + ' '); - // need timer to allow to lock - setTimeout(function () { - // build parameters list - var params = {}; - // add list params - params['cmd'] = 'save-record'; - params['name'] = obj.name; - params['recid'] = obj.recid; - // append other params - $.extend(params, obj.postData); - $.extend(params, postData); - params.record = $.extend(true, {}, obj.record); - // event before - var eventData = obj.trigger({ phase: 'before', type: 'submit', target: obj.name, url: obj.url, postData: params }); - if (eventData.isCancelled === true) { - if (typeof callBack == 'function') callBack({ status: 'error', message: 'Saving aborted.' }); - return; - } - // default action - var url = eventData.url; - if (typeof eventData.url == 'object' && eventData.url.save) url = eventData.url.save; - if (obj.last.xhr) try { obj.last.xhr.abort(); } catch (e) {}; - obj.last.xhr = $.ajax({ - type : (w2utils.settings.RESTfull ? (obj.recid == 0 ? 'POST' : 'PUT') : 'POST'), - url : url, - data : String($.param(eventData.postData, false)).replace(/%5B/g, '[').replace(/%5D/g, ']'), - dataType : 'text', - xhr : function() { - var xhr = new window.XMLHttpRequest(); - // upload - xhr.upload.addEventListener("progress", function(evt) { - if (evt.lengthComputable) { - var percent = Math.round(evt.loaded / evt.total * 100); - $('#'+ obj.name + '_progress').text(''+ percent + '%'); - } - }, false); - return xhr; - }, - complete : function (xhr, status) { - obj.unlock(); - - // event before - var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'save', xhr: xhr, status: status }); - if (eventData.isCancelled === true) { - if (typeof callBack == 'function') callBack({ status: 'error', message: 'Saving aborted.' }); - return; - } - // parse server response - var data; - var responseText = xhr.responseText; - if (status != 'error') { - // default action - if (typeof responseText != 'undefined' && responseText != '') { - // check if the onLoad handler has not already parsed the data - if (typeof responseText == "object") { - data = responseText; - } else { - // $.parseJSON or $.getJSON did not work because those expect perfect JSON data - where everything is in double quotes - // - // TODO: avoid (potentially malicious) code injection from the response. - try { eval('data = '+ responseText); } catch (e) { } - } - if (typeof data == 'undefined') { - data = { - status : 'error', - message : obj.msgNotJSON, - responseText : responseText - } - } - if (data['status'] == 'error') { - obj.error(data['message']); - } else { - obj.original = $.extend({}, obj.record); - } - } - } else { - obj.error('AJAX Error ' + xhr.status + ': '+ xhr.statusText); - data = { - status : 'error', - message : obj.msgAJAXerror, - responseText : responseText - }; - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.refresh(); - // call back - if (typeof callBack == 'function') callBack(data); - } - }); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 50); - }, - - lock: function (msg, showSpinner) { - var box = $(this.box).find('> div:first-child'); - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(box); - w2utils.lock.apply(window, args); - }, - - unlock: function () { - var obj = this; - setTimeout(function () { w2utils.unlock(obj.box); }, 25); // needed timer so if server fast, it will not flash - }, - - goto: function (page) { - if (typeof page != 'undefined') this.page = page; - // if it was auto size, resize it - if ($(this.box).data('auto-size') === true) $(this.box).height(0); - this.refresh(); - }, - - generateHTML: function () { - var pages = []; // array for each page - for (var f in this.fields) { - var html = ''; - var field = this.fields[f]; - if (typeof field.html == 'undefined') field.html = {}; - field.html = $.extend(true, { caption: '', span: 6, attr: '', text: '', page: 0 }, field.html); - if (field.html.caption == '') field.html.caption = field.name; - var input = ''; - // if (field.type == 'list') input = ''; - if ((field.type === 'pass') || (field.type === 'password')){ - input = ''; - } - if (field.type == 'checkbox') input = ''; - if (field.type == 'textarea') input = ''; - html += '\n
      '+ field.html.caption +':
      '+ - '\n
      '+ - input + field.html.text + - '
      '; - if (typeof pages[field.html.page] == 'undefined') pages[field.html.page] = '
      '; - pages[field.html.page] += html; - } - for (var p in pages) pages[p] += '\n
      '; - // buttons if any - var buttons = ''; - if (!$.isEmptyObject(this.actions)) { - buttons += '\n
      '; - for (var a in this.actions) { - buttons += '\n '; - } - buttons += '\n
      '; - } - return pages.join('') + buttons; - }, - - action: function (action, event) { - // event before - var eventData = this.trigger({ phase: 'before', target: action, type: 'action', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default actions - if (typeof (this.actions[action]) == 'function') { - this.actions[action].call(this, event); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - resize: function () { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'resize' }); - if (eventData.isCancelled === true) return; - // default behaviour - var main = $(this.box).find('> div'); - var header = $(this.box).find('> div .w2ui-form-header'); - var toolbar = $(this.box).find('> div .w2ui-form-toolbar'); - var tabs = $(this.box).find('> div .w2ui-form-tabs'); - var page = $(this.box).find('> div .w2ui-page'); - var cpage = $(this.box).find('> div .w2ui-page.page-'+ this.page); - var dpage = $(this.box).find('> div .w2ui-page.page-'+ this.page + ' > div'); - var buttons = $(this.box).find('> div .w2ui-buttons'); - // if no height, calculate it - resizeElements(); - if (parseInt($(this.box).height()) == 0 || $(this.box).data('auto-size') === true) { - $(this.box).height( - (header.length > 0 ? w2utils.getSize(header, 'height') : 0) + - ((typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') : 0) + - ((typeof this.toolbar == 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0) + - (page.length > 0 ? w2utils.getSize(dpage, 'height') + w2utils.getSize(cpage, '+height') + 12 : 0) + // why 12 ??? - (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) - ); - $(this.box).data('auto-size', true); - } - resizeElements(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - - function resizeElements() { - // resize elements - main.width($(obj.box).width()).height($(obj.box).height()); - toolbar.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0)); - tabs.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0) - + ((typeof obj.toolbar == 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0)); - page.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0) - + ((typeof obj.toolbar == 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') + 5 : 0) - + ((typeof obj.tabs === 'object' && $.isArray(obj.tabs.tabs) && obj.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') + 5 : 0)); - page.css('bottom', (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0)); - } - }, - - refresh: function () { - var time = (new Date()).getTime(); - var obj = this; - if (!this.box) return; - if (!this.isGenerated || typeof $(this.box).html() == 'undefined') return; - // update what page field belongs - $(this.box).find('input, textarea, select').each(function (index, el) { - var name = (typeof $(el).attr('name') != 'undefined' ? $(el).attr('name') : $(el).attr('id')); - var field = obj.get(name); - if (field) { - // find page - var div = $(el).parents('.w2ui-page'); - if (div.length > 0) { - for (var i = 0; i < 100; i++) { - if (div.hasClass('page-'+i)) { field.page = i; break; } - } - } - } - }); - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'refresh', page: this.page }) - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('.w2ui-page').hide(); - $(this.box).find('.w2ui-page.page-' + this.page).show(); - $(this.box).find('.w2ui-form-header').html(this.header); - // refresh tabs if needed - if (typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) { - $('#form_'+ this.name +'_tabs').show(); - this.tabs.active = this.tabs.tabs[this.page].id; - this.tabs.refresh(); - } else { - $('#form_'+ this.name +'_tabs').hide(); - } - // refresh tabs if needed - if (typeof this.toolbar == 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) { - $('#form_'+ this.name +'_toolbar').show(); - this.toolbar.refresh(); - } else { - $('#form_'+ this.name +'_toolbar').hide(); - } - // refresh values of all fields - for (var f in this.fields) { - var field = this.fields[f]; - field.$el = $(this.box).find('[name="'+ String(field.name).replace(/\\/g, '\\\\') +'"]'); - field.el = field.$el[0]; - if (typeof field.el == 'undefined') { - console.log('ERROR: Cannot associate field "'+ field.name + '" with html control. Make sure html control exists with the same name.'); - //return; - } - if (field.el) field.el.id = field.name; - var tmp = $(field).data('w2field'); - if (tmp) tmp.clear(); - $(field.$el).off('change').on('change', function () { - var value_new = this.value; - var value_previous = obj.record[this.name] ? obj.record[this.name] : ''; - var field = obj.get(this.name); - if (['list', 'enum', 'file'].indexOf(field.type) != -1 && $(this).data('selected')) { - var nv = $(this).data('selected'); - var cv = obj.record[this.name]; - if ($.isArray(nv)) { - value_new = []; - for (var i in nv) value_new[i] = $.extend(true, {}, nv[i]); // clone array - } - if ($.isPlainObject(nv)) { - value_new = $.extend(true, {}, nv); // clone object - } - if ($.isArray(cv)) { - value_previous = []; - for (var i in cv) value_previous[i] = $.extend(true, {}, cv[i]); // clone array - } - if ($.isPlainObject(cv)) { - value_previous = $.extend(true, {}, cv); // clone object - } - } - // clean extra chars - if (['int', 'float', 'percent', 'money', 'currency'].indexOf(field.type) != -1) { - value_new = $(this).data('w2field').clean(value_new); - } - if (value_new === value_previous) return; - // event before - var eventData = obj.trigger({ phase: 'before', target: this.name, type: 'change', value_new: value_new, value_previous: value_previous }); - if (eventData.isCancelled === true) { - $(this).val(obj.record[this.name]); // return previous value - return; - } - // default action - var val = this.value; - if (this.type == 'select') val = this.value; - if (this.type == 'checkbox') val = this.checked ? true : false; - if (this.type == 'radio') { - field.$el.each(function (index, el) { - if (el.checked) val = el.value; - }); - } - if (['int', 'float', 'percent', 'money', 'currency', 'list', 'combo', 'enum', 'file'].indexOf(field.type) != -1) { - val = value_new; - } - if (['enum', 'file'].indexOf(field.type) != -1) { - if (val.length > 0) { - var fld = $(field.el).data('w2field').helpers.multi; - $(fld).removeClass('w2ui-error'); - } - } - obj.record[this.name] = val; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }); - if (field.required) { - $(field.el).parent().addClass('w2ui-required'); - } else { - $(field.el).parent().removeClass('w2ui-required'); - } - } - // attach actions on buttons - $(this.box).find('button, input[type=button]').each(function (index, el) { - $(el).off('click').on('click', function (event) { - var action = this.value; - if (this.name) action = this.name; - if (this.id) action = this.id; - obj.action(action, event); - }); - }); - // init controls with record - for (var f in this.fields) { - var field = this.fields[f]; - var value = (typeof this.record[field.name] != 'undefined' ? this.record[field.name] : ''); - if (!field.el) continue; - field.type = String(field.type).toLowerCase(); - if (!field.options) field.options = {}; - switch (field.type) { - case 'text': - case 'textarea': - case 'email': - case 'password': - field.el.value = value; - break; - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'hex': - case 'alphanumeric': - case 'color': - case 'date': - case 'time': - field.el.value = value; - $(field.el).w2field($.extend({}, field.options, { type: field.type })); - break; - - // enums - case 'list': - case 'combo': - if (field.type == 'list' && !$.isPlainObject(value)) { - // find value from items - for (var i in field.options.items) { - var item = field.options.items[i]; - if (item && item.id == value) { - value = $.extend(true, {}, item); - obj.record[field.name] = value; - break; - } - } - } else if (field.type == 'combo' && !$.isPlainObject(value)) { - field.el.value = value; - } else if ($.isPlainObject(value) && typeof value.text != 'undefined') { - field.el.value = value.text; - } else { - field.el.value = ''; - } - if (!$.isPlainObject(value)) value = {}; - $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); - break; - case 'enum': - case 'file': - if (!$.isArray(value)) value = []; - $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); - break; - - // standard HTML - case 'select': - // generate options - var items = field.options.items; - if (typeof items != 'undefined' && items.length > 0) { - items = w2obj.field.prototype.normMenu(items); - $(field.el).html(''); - for (var it in items) { - $(field.el).append('
      '),i.markerLeft=$('
      ')),i.lastInt&&i.lastInt===a||(i.lastInt=a,i.marker.remove(),i.markerLeft.remove(),$(".w2ui-head").removeClass("w2ui-col-intersection"),a>=i.columns.length?($(i.columns[i.columns.length-1]).children("div:last").append(i.marker.addClass("right").removeClass("left")),$(i.columns[i.columns.length-1]).addClass("w2ui-col-intersection")):a<=i.numberPreColumnsPresent?($('.w2ui-head[col="0"]').prepend(i.marker.addClass("left").removeClass("right")).css({position:"relative"}),$('.w2ui-head[col="0"]').prev().addClass("w2ui-col-intersection")):($(i.columns[a]).children("div:last").prepend(i.marker.addClass("left").removeClass("right")),$(i.columns[a]).prev().children("div:last").append(i.markerLeft.addClass("right").removeClass("left")).css({position:"relative"}),$(i.columns[a-1]).addClass("w2ui-col-intersection")))}function f(a,b,c){if(a<=b[0])return 0;if(a>=b[b.length-1]+c)return b.length;for(var d=0,e=b.length;e>d;d++){var f=b[d],g=b[d+1]||b[d]+c,h=(g-b[d])/2+b[d];if(a>f&&h>=a)return d;if(a>h&&g>=a)return d+1}return intersection}function g(a,b){$(i.ghost).css({left:a-10,top:b-10})}if(this.columnGroups&&this.columnGroups.length)throw"Draggable columns are not currently supported with column groups.";var h=this,i={};return i.lastInt=null,i.pressed=!1,i.timeout=null,i.columnHead=null,$(h.box).on("mousedown",b),$(h.box).on("mouseup",a),{remove:function(){$(h.box).off("mousedown",b),$(h.box).off("mouseup",a),$(h.box).find(".w2ui-head").removeAttr("draggable"),h.last.columnDrag=!1}}},columnOnOff:function(a,b,c,d){var e=this.trigger({phase:"before",target:this.name,type:"columnOnOff",checkbox:a,field:c,originalEvent:b});if(e.isCancelled!==!0){var f=this;for(var g in this.records)this.records[g].expanded===!0&&(this.records[g].expanded=!1);var h=!0;if("line-numbers"==c)this.show.lineNumbers=!this.show.lineNumbers,this.refresh();else if("skip"==c)w2utils.isInt(d)||(d=0),f.skip(d);else if("resize"==c){for(var i in this.columns)"undefined"!=typeof this.columns[i].sizeOriginal&&(this.columns[i].size=this.columns[i].sizeOriginal);this.initResize(),this.resize()}else{var j=this.getColumn(c);j.hidden?($(a).prop("checked",!0),this.showColumn(j.field)):($(a).prop("checked",!1),this.hideColumn(j.field)),h=!1}this.initColumnOnOff(),h&&setTimeout(function(){$().w2overlay("",{name:"searches-"+this.name}),f.toolbar.uncheck("column-on-off")},100),this.trigger($.extend(e,{phase:"after"}))}},initToolbar:function(){if("undefined"==typeof this.toolbar.render){var a=this.toolbar.items;if(this.toolbar.items=[],this.toolbar=$().w2toolbar($.extend(!0,{},this.toolbar,{name:this.name+"_toolbar",owner:this})),this.show.toolbarReload&&this.toolbar.items.push($.extend(!0,{},this.buttons.reload)),this.show.toolbarColumns&&(this.toolbar.items.push($.extend(!0,{},this.buttons.columns)),this.initColumnOnOff()),(this.show.toolbarReload||this.show.toolbarColumn)&&this.toolbar.items.push({type:"break",id:"w2ui-break0"}),this.show.toolbarSearch){var b='";this.toolbar.items.push({type:"html",id:"w2ui-search",html:b}),this.multiSearch&&this.searches.length>0&&this.toolbar.items.push($.extend(!0,{},this.buttons["search-go"]))}this.show.toolbarSearch&&(this.show.toolbarAdd||this.show.toolbarEdit||this.show.toolbarDelete||this.show.toolbarSave)&&this.toolbar.items.push({type:"break",id:"w2ui-break1"}),this.show.toolbarAdd&&this.toolbar.items.push($.extend(!0,{},this.buttons.add)),this.show.toolbarEdit&&this.toolbar.items.push($.extend(!0,{},this.buttons.edit)),this.show.toolbarDelete&&this.toolbar.items.push($.extend(!0,{},this.buttons["delete"])),this.show.toolbarSave&&((this.show.toolbarAdd||this.show.toolbarDelete||this.show.toolbarEdit)&&this.toolbar.items.push({type:"break",id:"w2ui-break2"}),this.toolbar.items.push($.extend(!0,{},this.buttons.save)));for(var c in a)this.toolbar.items.push(a[c]);var d=this;this.toolbar.on("click",function(a){function b(){$("#w2ui-overlay-searches-"+d.name).data("keepOpen")!==!0&&(h.uncheck(e),$(document).off("click","body",b))}var c=d.trigger({phase:"before",type:"toolbar",target:a.target,originalEvent:a});if(c.isCancelled!==!0){var e=a.target;switch(e){case"w2ui-reload":var f=d.trigger({phase:"before",type:"reload",target:d.name});if(f.isCancelled===!0)return!1;d.reload(),d.trigger($.extend(f,{phase:"after"}));break;case"w2ui-column-on-off":for(var g in d.columns)d.columns[g].hidden?$("#grid_"+d.name+"_column_"+g+"_check").prop("checked",!1):$("#grid_"+d.name+"_column_"+g+"_check").prop("checked",!0);d.initResize(),d.resize();break;case"w2ui-search-advanced":var h=this,i=this.get(e);i.checked?(d.searchClose(),setTimeout(function(){h.uncheck(e)},1)):(d.searchOpen(),a.originalEvent.stopPropagation(),$(document).on("click","body",b));break;case"w2ui-add":var c=d.trigger({phase:"before",target:d.name,type:"add",recid:null});d.trigger($.extend(c,{phase:"after"}));break;case"w2ui-edit":var j=d.getSelection(),k=null;1==j.length&&(k=j[0]);var c=d.trigger({phase:"before",target:d.name,type:"edit",recid:k});d.trigger($.extend(c,{phase:"after"}));break;case"w2ui-delete":d.delete();break;case"w2ui-save":d.save()}d.trigger($.extend(c,{phase:"after"}))}})}},initResize:function(){var a=this;$(this.box).find(".w2ui-resizer").off("click").on("click",function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,a.preventDefault&&a.preventDefault()}).off("mousedown").on("mousedown",function(b){b||(b=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),a.resizing=!0,a.last.tmp={x:b.screenX,y:b.screenY,gx:b.screenX,gy:b.screenY,col:parseInt($(this).attr("name"))},b.stopPropagation?b.stopPropagation():b.cancelBubble=!0,b.preventDefault&&b.preventDefault();for(var c in a.columns)"undefined"==typeof a.columns[c].sizeOriginal&&(a.columns[c].sizeOriginal=a.columns[c].size),a.columns[c].size=a.columns[c].sizeCalculated;var d={phase:"before",type:"columnResize",target:a.name,column:a.last.tmp.col,field:a.columns[a.last.tmp.col].field};d=a.trigger($.extend(d,{resizeBy:0,originalEvent:b}));var e=function(b){if(1==a.resizing){if(b||(b=window.event),d=a.trigger($.extend(d,{resizeBy:b.screenX-a.last.tmp.gx,originalEvent:b})),d.isCancelled===!0)return void(d.isCancelled=!1);a.last.tmp.x=b.screenX-a.last.tmp.x,a.last.tmp.y=b.screenY-a.last.tmp.y,a.columns[a.last.tmp.col].size=parseInt(a.columns[a.last.tmp.col].size)+a.last.tmp.x+"px",a.resizeRecords(),a.last.tmp.x=b.screenX,a.last.tmp.y=b.screenY}},f=function(b){delete a.resizing,$(document).off("mousemove","body"),$(document).off("mouseup","body"),a.resizeRecords(),a.trigger($.extend(d,{phase:"after",originalEvent:b}))};$(document).on("mousemove","body",e),$(document).on("mouseup","body",f)}).each(function(a,b){var c=$(b).parent();$(b).css({height:"25px","margin-left":c.width()-3+"px"})})},resizeBoxes:function(){{var a=($(this.box).find("> div"),$("#grid_"+this.name+"_header")),b=$("#grid_"+this.name+"_toolbar"),c=$("#grid_"+this.name+"_summary"),d=$("#grid_"+this.name+"_footer"),e=$("#grid_"+this.name+"_body");$("#grid_"+this.name+"_columns"),$("#grid_"+this.name+"_records")}this.show.header&&a.css({top:"0px",left:"0px",right:"0px"}),this.show.toolbar&&b.css({top:0+(this.show.header?w2utils.getSize(a,"height"):0)+"px",left:"0px",right:"0px"}),this.show.footer&&d.css({bottom:"0px",left:"0px",right:"0px"}),this.summary.length>0&&c.css({bottom:0+(this.show.footer?w2utils.getSize(d,"height"):0)+"px",left:"0px",right:"0px"}),e.css({top:0+(this.show.header?w2utils.getSize(a,"height"):0)+(this.show.toolbar?w2utils.getSize(b,"height"):0)+"px",bottom:0+(this.show.footer?w2utils.getSize(d,"height"):0)+(this.summary.length>0?w2utils.getSize(c,"height"):0)+"px",left:"0px",right:"0px"})},resizeRecords:function(){var a=this;$(this.box).find(".w2ui-empty-record").remove();var b=$(this.box),c=$(this.box).find("> div"),d=$("#grid_"+this.name+"_header"),e=$("#grid_"+this.name+"_toolbar"),f=$("#grid_"+this.name+"_summary"),g=$("#grid_"+this.name+"_footer"),h=$("#grid_"+this.name+"_body"),i=$("#grid_"+this.name+"_columns"),j=$("#grid_"+this.name+"_records");if(this.fixedBody){var k=c.height()-(this.show.header?w2utils.getSize(d,"height"):0)-(this.show.toolbar?w2utils.getSize(e,"height"):0)-("none"!=f.css("display")?w2utils.getSize(f,"height"):0)-(this.show.footer?w2utils.getSize(g,"height"):0);h.css("height",k)}else{var k=w2utils.getSize(i,"height")+w2utils.getSize($("#grid_"+a.name+"_records table"),"height");a.height=k+w2utils.getSize(c,"+height")+(a.show.header?w2utils.getSize(d,"height"):0)+(a.show.toolbar?w2utils.getSize(e,"height"):0)+("none"!=f.css("display")?w2utils.getSize(f,"height"):0)+(a.show.footer?w2utils.getSize(g,"height"):0),c.css("height",a.height),h.css("height",k),b.css("height",w2utils.getSize(c,"height")+w2utils.getSize(b,"+height"))}var l=!1,m=!1;if(h.width()<$(j).find(">table").width()&&(l=!0),h.height()-i.height()<$(j).find(">table").height()+(l?w2utils.scrollBarSize():0)&&(m=!0),this.fixedBody||(m=!1,l=!1),l||m?(i.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show(),j.css({top:(this.columnGroups.length>0&&this.show.columns?1:0)+w2utils.getSize(i,"height")+"px","-webkit-overflow-scrolling":"touch","overflow-x":l?"auto":"hidden","overflow-y":m?"auto":"hidden"})):(i.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").hide(),j.css({top:(this.columnGroups.length>0&&this.show.columns?1:0)+w2utils.getSize(i,"height")+"px",overflow:"hidden"}),j.length>0&&(this.last.scrollTop=0,this.last.scrollLeft=0)),this.show.emptyRecords&&!m){var n=Math.floor(j.height()/this.recordHeight)+1;if(this.fixedBody)for(var o=this.buffered;n>=o;o++){var p="";p+='',this.show.lineNumbers&&(p+=''),this.show.selectColumn&&(p+=''),this.show.expandColumn&&(p+='');for(var q=0;this.columns.length>0;){var r=this.columns[q];if(r.hidden){if(q++,"undefined"==typeof this.columns[q])break}else if(p+='',q++,"undefined"==typeof this.columns[q])break}p+='',p+="",$("#grid_"+this.name+"_records > table").append(p)}}if(h.length>0){for(var s=parseInt(h.width())-(m?w2utils.scrollBarSize():0)-(this.show.lineNumbers?34:0)-(this.show.selectColumn?26:0)-(this.show.expandColumn?26:0),t=s,u=0,v=!1,w=0;wt&&r.hidden!==!0&&(r.hidden=!0,v=!0),r.gridMinWidth0)for(var w=0;wparseInt(r.max)&&(r.sizeCalculated=r.max+"px"),x+=parseInt(r.sizeCalculated))}var y=parseInt(t)-parseInt(x);if(y>0&&u>0)for(var w=0;;){var r=this.columns[w];if("undefined"!=typeof r)if(r.hidden||"px"==r.sizeType)w++;else{if(r.sizeCalculated=parseInt(r.sizeCalculated)+1+"px",y--,0==y)break;w++}else w=0}else y>0&&i.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show();i.find("> table > tbody > tr:nth-child(1) td").each(function(b,c){var d=$(c).attr("col");"undefined"!=typeof d&&a.columns[d]&&$(c).css("width",a.columns[d].sizeCalculated),$(c).hasClass("w2ui-head-last")&&$(c).css("width",w2utils.scrollBarSize()+(y>0&&0==u?y:0)+"px")}),3==i.find("> table > tbody > tr").length&&i.find("> table > tbody > tr:nth-child(1) td").html("").css({height:"0px",border:"0px",padding:"0px",margin:"0px"}),j.find("> table > tbody > tr:nth-child(1) td").each(function(b,c){var d=$(c).attr("col");"undefined"!=typeof d&&a.columns[d]&&$(c).css("width",a.columns[d].sizeCalculated),$(c).hasClass("w2ui-grid-data-last")&&$(c).css("width",(y>0&&0==u?y:0)+"px")}),f.find("> table > tbody > tr:nth-child(1) td").each(function(b,c){var d=$(c).attr("col");"undefined"!=typeof d&&a.columns[d]&&$(c).css("width",a.columns[d].sizeCalculated),$(c).hasClass("w2ui-grid-data-last")&&$(c).css("width",w2utils.scrollBarSize()+(y>0&&0==u?y:0)+"px")}),this.initResize(),this.refreshRanges(),""!=this.last.scrollTop&&j.length>0&&(i.prop("scrollLeft",this.last.scrollLeft),j.prop("scrollTop",this.last.scrollTop),j.prop("scrollLeft",this.last.scrollLeft))},getSearchesHTML:function(){for(var a='',b=!1,c=0;cX ";if(-1!=["int","float","money","currency","percent","date","time"].indexOf(d.type))var f='";if(-1!=["select","list","hex"].indexOf(d.type))var f='";if(-1!=["enum"].indexOf(d.type))var f='";switch(a+='"}}return a+='
      '+e+' '+d.caption+' '+f+'
      ',d.type){case"text":case"alphanumeric":case"hex":case"list":case"combo":case"enum":a+='";break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":a+='";break;case"select":a+='"}a+=d.outTag+"
      "},initOperator:function(a,b){var c=this,d=c.searches[b],e=$("#grid_"+c.name+"_range_"+b),f=$("#grid_"+c.name+"_field_"+b),g=f.parent().find("span input");f.w2field("in"==$(a).val()?"clear":d.type),"between"==$(a).val()?(e.show(),g.w2field(d.type)):e.hide()},initSearches:function(){var a=this;for(var b in this.searches){var c=this.searches[b],d=this.getSearchData(c.field);switch(c.type=String(c.type).toLowerCase(),"object"!=typeof c.options&&(c.options={}),c.type){case"text":case"alphanumeric":$("#grid_"+this.name+"_operator_"+b).val("begins"),-1!=["alphanumeric","hex"].indexOf(c.type)&&$("#grid_"+this.name+"_field_"+b).w2field(c.type,c.options);break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":if(d&&"int"==d.type&&"in"==d.operator)break;$("#grid_"+this.name+"_field_"+b).w2field(c.type,c.options),$("#grid_"+this.name+"_field2_"+b).w2field(c.type,c.options),setTimeout(function(){$("#grid_"+a.name+"_field_"+b).keydown(),$("#grid_"+a.name+"_field2_"+b).keydown()},1);break;case"hex":break;case"list":case"combo":case"enum":var e=c.options;"list"==c.type&&(e.selected={}),"enum"==c.type&&(e.selected=[]),d&&(e.selected=d.value),$("#grid_"+this.name+"_field_"+b).w2field(c.type,e),"combo"==c.type&&$("#grid_"+this.name+"_operator_"+b).val("begins");break;case"select":var e='';for(var f in c.options.items){var g=c.options.items[f];if($.isPlainObject(c.options.items[f])){var h=g.id,i=g.text;"undefined"==typeof h&&"undefined"!=typeof g.value&&(h=g.value),"undefined"==typeof i&&"undefined"!=typeof g.caption&&(i=g.caption),null==h&&(h=""),e+='"}else e+='"}$("#grid_"+this.name+"_field_"+b).html(e)}null!=d&&("int"==d.type&&"in"==d.operator&&$("#grid_"+this.name+"_field_"+b).w2field("clear").val(d.value),$("#grid_"+this.name+"_operator_"+b).val(d.operator).trigger("change"),$.isArray(d.value)?"in"==d.operator?$("#grid_"+this.name+"_field_"+b).val(d.value).trigger("change"):($("#grid_"+this.name+"_field_"+b).val(d.value[0]).trigger("change"),$("#grid_"+this.name+"_field2_"+b).val(d.value[1]).trigger("change")):"udefined"!=typeof d.value&&$("#grid_"+this.name+"_field_"+b).val(d.value).trigger("change"))}$("#w2ui-overlay-searches-"+this.name+" .w2ui-grid-searches *[rel=search]").on("keypress",function(b){13==b.keyCode&&(b.ctrlKey||b.metaKey)&&(a.search(),$().w2overlay())})},getColumnsHTML:function(){function a(){var a="";""!=c.columnGroups[c.columnGroups.length-1].caption&&c.columnGroups.push({caption:""}),c.show.lineNumbers&&(a+='
       
      '),c.show.selectColumn&&(a+='
       
      '),c.show.expandColumn&&(a+='
       
      ');for(var b=0,d=0;d
      '),a+='"+i+'
      '+(f.caption?f.caption:" ")+"
      "}else a+='
      '+(e.caption?e.caption:" ")+"
      ";b+=e.span}return a+=""}function b(a){var b="",d=!c.reorderColumns||c.columnGroups&&c.columnGroups.length?"":" w2ui-reorder-cols-head ";c.show.lineNumbers&&(b+='
      #
      "),c.show.selectColumn&&(b+='
      "),c.show.expandColumn&&(b+='
       
      ');for(var e=0,f=0,g=0;g
      '),b+='"+l+'
      '+(h.caption?h.caption:" ")+"
      "}}}return b+='
       
      ',b+=""}var c=this,d="";return this.show.columnHeaders&&(d=this.columnGroups.length>0?b(!0)+a()+b(!1):b(!0)),d},getRecordsHTML:function(){this.show_extra=this.buffered>300?30:300;var a=$("#grid_"+this.name+"_records"),b=Math.floor(a.height()/this.recordHeight)+this.show_extra+1;this.fixedBody||(b=this.buffered);var c=""+this.getRecordHTML(-1,0);c+='';for(var d=0;b>d;d++)c+=this.getRecordHTML(d,d+1);return c+='
      ',this.last.range_start=0,this.last.range_end=b,c},getSummaryHTML:function(){if(0!=this.summary.length){for(var a="",b=0;b0&&$(b.box).find(".w2ui-grid-data > div").w2marker(a)},50))}var b=((new Date).getTime(),this),c=$("#grid_"+this.name+"_records");if(0!=this.records.length&&0!=c.length&&0!=c.height()){if(this.show_extra=this.buffered>300?30:300,c.height()0&&this.refresh());var d=Math.round(c[0].scrollTop/this.recordHeight+1),e=d+(Math.round(c.height()/this.recordHeight)-1);d>this.buffered&&(d=this.buffered),e>this.buffered&&(e=this.buffered);var f="object"!=typeof this.url?this.url:this.url.get;if($("#grid_"+this.name+"_footer .w2ui-footer-right").html(w2utils.formatNumber(this.offset+d)+"-"+w2utils.formatNumber(this.offset+e)+" "+w2utils.lang("of")+" "+w2utils.formatNumber(this.total)+(f?" ("+w2utils.lang("buffered")+" "+w2utils.formatNumber(this.buffered)+(this.offset>0?", skip "+w2utils.formatNumber(this.offset):"")+")":"")),f||this.fixedBody&&!(this.total<=300)){var g=Math.floor(c[0].scrollTop/this.recordHeight)-this.show_extra,h=g+Math.floor(c.height()/this.recordHeight)+2*this.show_extra+1;1>g&&(g=1),h>this.total&&(h=this.total);var i=c.find("#grid_"+this.name+"_rec_top"),j=c.find("#grid_"+this.name+"_rec_bottom");-1!=String(i.next().prop("id")).indexOf("_expanded_row")&&i.next().remove(),this.total>h&&-1!=String(j.prev().prop("id")).indexOf("_expanded_row")&&j.prev().remove();var k=parseInt(i.next().attr("line")),l=parseInt(j.prev().attr("line"));if(g>k||1==k||this.last.pull_refresh){if(h<=l+this.show_extra-2&&h!=this.total)return;for(this.last.pull_refresh=!1;;){var m=c.find("#grid_"+this.name+"_rec_top").next();if("bottom"==m.attr("line"))break;if(!(parseInt(m.attr("line"))=o;o++)this.records[o-1]&&(this.records[o-1].expanded===!0&&(this.records[o-1].expanded=!1),j.before(this.getRecordHTML(o-1,o)));a(),setTimeout(function(){b.refreshRanges()},0)}else{if(g>=k-this.show_extra+2&&g>1)return;for(;;){var m=c.find("#grid_"+this.name+"_rec_bottom").prev();if("top"==m.attr("line"))break;if(!(parseInt(m.attr("line"))>h))break;m.remove()}var m=c.find("#grid_"+this.name+"_rec_top").next(),n=m.attr("line");"bottom"==n&&(n=h);for(var o=parseInt(n)-1;o>=g;o--)this.records[o-1]&&(this.records[o-1].expanded===!0&&(this.records[o-1].expanded=!1),i.after(this.getRecordHTML(o-1,o)));a(),setTimeout(function(){b.refreshRanges()},0)}var p=(g-1)*b.recordHeight,q=(this.buffered-h)*b.recordHeight;0>q&&(q=0),i.css("height",p+"px"),j.css("height",q+"px"),b.last.range_start=g,b.last.range_end=h;var r=Math.floor(c[0].scrollTop/this.recordHeight),s=r+Math.floor(c.height()/this.recordHeight);if(s+10>this.buffered&&this.last.pull_more!==!0&&this.buffered
      ')}),-1==t.find("td").text().indexOf("Load")&&t.find("td").html("
      "+w2utils.lang("Load")+" "+b.limit+" "+w2utils.lang("More")+"...
      ")}this.buffered>=this.total-this.offset&&$("#grid_"+this.name+"_rec_more").hide()}}},getRecordHTML:function(a,b,c){var d,e="",f=this.last.selection;if(-1==a){e+='
      ',this.show.lineNumbers&&(e+=''),this.show.selectColumn&&(e+=''),this.show.expandColumn&&(e+='');for(var g in this.columns)this.columns[g].hidden||(e+='');return e+='',e+=""}var h="object"!=typeof this.url?this.url:this.url.get;if(c!==!0)if(this.searchData.length>0&&!h){if(a>=this.last.searchIds.length)return"";a=this.last.searchIds[a],d=this.records[a]}else{if(a>=this.records.length)return"";d=this.records[a]}else{if(a>=this.summary.length)return"";d=this.summary[a]}if(!d)return"";var i=(w2utils.escapeId(d.recid),!1);if(-1!=f.indexes.indexOf(a)&&(i=!0),e+='",this.show.lineNumbers&&(e+='"),this.show.selectColumn&&(e+='"),this.show.expandColumn){var j="";j=d.expanded===!0?"-":"+","none"==d.expanded&&(j=""),"spinner"==d.expanded&&(j='
      '),e+='"}for(var k=0;;){var l=this.columns[k];if(l.hidden){if(k++,"undefined"==typeof this.columns[k])break}else{var m=!c&&d.changes&&"undefined"!=typeof d.changes[l.field],n=this.getCellHTML(a,k,c),o="";if("string"==typeof l.render){var p=l.render.toLowerCase().split(":");-1!=["number","int","float","money","currency","percent"].indexOf(p[0])&&(o+="text-align: right;")}"object"==typeof d.style&&"string"==typeof d.style[k]&&(o+=d.style[k]+";");var q=!1;if(i&&-1!=$.inArray(k,f.columns[a])&&(q=!0),e+='",k++,"undefined"==typeof this.columns[k])break}}return e+='',e+=""},getCellHTML:function(a,b,c){var d=this.columns[b],e=c!==!0?this.records[a]:this.summary[a],f=this.getCellValue(a,b,c),g=d.editable;if("undefined"!=typeof d.render){if("function"==typeof d.render&&(f=$.trim(d.render.call(this,e,a,b)),(f.length<4||""+f+"")),"object"==typeof d.render&&(f="
      "+d.render[f]+"
      "),"string"==typeof d.render){var h=d.render.toLowerCase().split(":"),i="",j="";-1!=["number","int","float","money","currency","percent"].indexOf(h[0])&&("undefined"!=typeof h[1]&&w2utils.isInt(h[1])||(h[1]=0),h[1]>20&&(h[1]=20),h[1]<0&&(h[1]=0),-1!=["money","currency"].indexOf(h[0])&&(h[1]=w2utils.settings.currencyPrecision,i=w2utils.settings.currencyPrefix,j=w2utils.settings.currencySuffix),"percent"==h[0]&&(j="%","0"!==h[1]&&(h[1]=1)),"int"==h[0]&&(h[1]=0),f="
      "+(""!==f?i+w2utils.formatNumber(Number(f).toFixed(h[1]))+j:"")+"
      "),"time"==h[0]&&(("undefined"==typeof h[1]||""==h[1])&&(h[1]=w2utils.settings.time_format),f="
      "+i+w2utils.formatTime(f,"h12"==h[1]?"hh:mi pm":"h24:min")+j+"
      "),"date"==h[0]&&(("undefined"==typeof h[1]||""==h[1])&&(h[1]=w2utils.settings.date_display),f="
      "+i+w2utils.formatDate(f,h[1])+j+"
      "),"age"==h[0]&&(f="
      "+i+w2utils.age(f)+j+"
      ")}}else{var k="";if(g&&-1!=["checkbox","check"].indexOf(g.type)){var l=c?-(a+1):a;k="text-align: center",f=''}if(this.show.recordTitles){var m=String(f).replace(/"/g,"''");"undefined"!=typeof d.title&&("function"==typeof d.title&&(m=d.title.call(this,e,a,b)),"string"==typeof d.title&&(m=d.title));var f='
      '+f+"
      "}else var f='
      '+f+"
      "}return(null==f||"undefined"==typeof f)&&(f=""),f},getCellValue:function(a,b,c){var d=this.columns[b],e=c!==!0?this.records[a]:this.summary[a],f=this.parseField(e,d.field);return e.changes&&"undefined"!=typeof e.changes[d.field]&&(f=e.changes[d.field]),(null==f||"undefined"==typeof f)&&(f=""),f},getFooterHTML:function(){return'
      '},status:function(a){if("undefined"!=typeof a)$("#grid_"+this.name+"_footer").find(".w2ui-footer-left").html(a);else{var b="",c=this.getSelection();if(c.length>0){b=String(c.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")+" "+w2utils.lang("selected");var d=c[0];"object"==typeof d&&(d=d.recid+", "+w2utils.lang("Column")+": "+d.column),1==c.length&&(b=w2utils.lang("Record ID")+": "+d+" ")}$("#grid_"+this.name+"_footer .w2ui-footer-left").html(b),1==c.length?this.toolbar.enable("w2ui-edit"):this.toolbar.disable("w2ui-edit"),c.length>=1?this.toolbar.enable("w2ui-delete"):this.toolbar.disable("w2ui-delete")}},lock:function(){var a=$(this.box).find("> div:first-child"),b=Array.prototype.slice.call(arguments,0);b.unshift(a),setTimeout(function(){w2utils.lock.apply(window,b)},10)},unlock:function(){var a=this.box;setTimeout(function(){w2utils.unlock(a)},25)},parseField:function(a,b){var c="";try{c=a;var d=String(b).split(".");for(var e in d)c=c[d[e]]}catch(f){c=""}return c},prepareData:function(){for(var a in this.records){var b=this.records[a];for(var c in this.columns){var d=this.columns[c];if(null!=b[d.field]&&"string"==typeof d.render){if(-1!=["number","int","float","money","currency","percent"].indexOf(d.render.split(":")[0])&&"number"!=typeof b[d.field]&&(b[d.field]=parseFloat(b[d.field])),-1!=["date","age"].indexOf(d.render)&&!b[d.field+"_"]){var e=b[d.field];w2utils.isInt(e)&&(e=parseInt(e)),b[d.field+"_"]=new Date(e)}if(-1!=["time"].indexOf(d.render))if(w2utils.isTime(b[d.field])){var f=w2utils.isTime(b[d.field],!0),e=new Date;e.setHours(f.hours,f.minutes,f.seconds?f.seconds:0,0),b[d.field+"_"]||(b[d.field+"_"]=e)}else{var f=b[d.field];w2utils.isInt(f)&&(f=parseInt(f));var f=null!=f?new Date(f):new Date,e=new Date;e.setHours(f.getHours(),f.getMinutes(),f.getSeconds(),0),b[d.field+"_"]||(b[d.field+"_"]=e)}}}}},nextCell:function(a,b){var c=a+1;if(this.columns.length==c)return!1;if(b===!0){var d=this.columns[c].editable;if(this.columns[c].hidden||"undefined"==typeof d||d&&-1!=["checkbox","check"].indexOf(d.type))return this.nextCell(c,b)}return c},prevCell:function(a,b){var c=a-1;if(0>c)return!1;if(b===!0){var d=this.columns[c].editable;if(this.columns[c].hidden||"undefined"==typeof d||d&&-1!=["checkbox","check"].indexOf(d.type))return this.prevCell(c,b)}return c},nextRow:function(a){if(a+10&&a0)for(;;){if(-1!=$.inArray(a,this.last.searchIds)||a>this.records.length)break;a++}return a}return null},prevRow:function(a){if(a>0&&0==this.last.searchIds.length||this.last.searchIds.length>0&&a>this.last.searchIds[0]){if(a--,this.last.searchIds.length>0)for(;;){if(-1!=$.inArray(a,this.last.searchIds)||0>a)break;a--}return a}return null}},$.extend(w2grid.prototype,w2utils.event),w2obj.grid=w2grid}(),function(){var a=function(a){this.box=null,this.name=null,this.panels=[],this.tmp={},this.padding=1,this.resizer=4,this.style="",this.onShow=null,this.onHide=null,this.onResizing=null,this.onResizerClick=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(!0,this,w2obj.layout,a)},b=["top","left","main","preview","right","bottom"];$.fn.w2layout=function(c){function d(a,b,c){var d=a.get(b);return null!==d&&"undefined"==typeof c&&(c=d.tabs),null===d||null===c?!1:($.isArray(c)&&(c={tabs:c}),$().w2destroy(a.name+"_"+b+"_tabs"),d.tabs=$().w2tabs($.extend({},c,{owner:a,name:a.name+"_"+b+"_tabs"})),d.show.tabs=!0,!0)}function e(a,b,c){var d=a.get(b);return null!==d&&"undefined"==typeof c&&(c=d.toolbar),null===d||null===c?!1:($.isArray(c)&&(c={items:c}),$().w2destroy(a.name+"_"+b+"_toolbar"),d.toolbar=$().w2toolbar($.extend({},c,{owner:a,name:a.name+"_"+b+"_toolbar"})),d.show.toolbar=!0,!0)}if("object"==typeof c||!c){if(!w2utils.checkName(c,"w2layout"))return;var f=c.panels||[],g=new a(c);$.extend(g,{handlers:[],panels:[]});for(var h=0,i=f.length;i>h;h++)g.panels[h]=$.extend(!0,{},a.prototype.panel,f[h]),($.isPlainObject(g.panels[h].tabs)||$.isArray(g.panels[h].tabs))&&d(g,f[h].type),($.isPlainObject(g.panels[h].toolbar)||$.isArray(g.panels[h].toolbar))&&e(g,f[h].type);for(var j in b)j=b[j],null===g.get(j)&&g.panels.push($.extend(!0,{},a.prototype.panel,{type:j,hidden:"main"!==j,size:50}));return $(this).length>0&&g.render($(this)[0]),w2ui[g.name]=g,g}if(w2ui[$(this).attr("name")]){var k=w2ui[$(this).attr("name")];return k[c].apply(k,Array.prototype.slice.call(arguments,1)),this}console.log("ERROR: Method "+c+" does not exist on jQuery.w2layout")},a.prototype={panel:{title:"",type:null,size:100,minSize:20,maxSize:!1,hidden:!1,resizable:!1,overflow:"auto",style:"",content:"",tabs:null,toolbar:null,width:null,height:null,show:{toolbar:!1,tabs:!1},onRefresh:null,onShow:null,onHide:null},html:function(a,b,c){return this.content(a,b,c)},content:function(a,b,c){var d=this,e=this.get(a);if("css"==a)return $("#layout_"+d.name+"_panel_css").html(""),!0;if(null===e)return!1;if("undefined"==typeof b||null===b)return e.content;if(b instanceof jQuery)return console.log("ERROR: You can not pass jQuery object to w2layout.content() method"),!1;var f="#layout_"+this.name+"_panel_"+e.type,g=$(f+"> .w2ui-panel-content"),h=0;if(g.length>0&&($(f).scrollTop(0),h=$(g).position().top),""===e.content)e.content=b,this.refresh(a);else{if(e.content=b,!e.hidden&&null!==c&&""!==c&&"undefined"!=typeof c){var i=$(f+"> .w2ui-panel-content");i.after('
      ');var j=$(f+"> .w2ui-panel-content.new-panel");i.css("top",h),j.css("top",h),"object"==typeof b?(b.box=j[0],b.render()):j.html(b),w2utils.transition(i[0],j[0],c,function(){i.remove(),j.removeClass("new-panel"),j.css("overflow",e.overflow),d.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){d.resize()},100)})}this.refresh(a)}return d.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){d.resize()},100),!0},load:function(a,b,c,d){var e=this;return"css"==a?($.get(b,function(b,c,f){e.content(a,f.responseText),d&&d()}),!0):null!==this.get(a)?($.get(b,function(b,f,g){e.content(a,g.responseText,c),d&&d(),e.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){e.resize()},100)}),!0):!1},sizeTo:function(a,b){var c=this,d=c.get(a);return null===d?!1:($(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),setTimeout(function(){c.set(a,{size:b})},1),setTimeout(function(){$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),c.resize()},500),!0)},show:function(a,b){var c=this,d=this.trigger({phase:"before",type:"show",target:a,object:this.get(a),immediate:b});if(d.isCancelled!==!0){var e=c.get(a);return null===e?!1:(e.hidden=!1,b===!0?($("#layout_"+c.name+"_panel_"+a).css({opacity:"1"}),e.resizable&&$("#layout_"+c.name+"_resizer_"+a).show(),c.trigger($.extend(d,{phase:"after"})),c.resize()):(e.resizable&&$("#layout_"+c.name+"_resizer_"+a).show(),$("#layout_"+c.name+"_panel_"+a).css({opacity:"0"}),$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),setTimeout(function(){c.resize()},1),setTimeout(function(){$("#layout_"+c.name+"_panel_"+a).css({opacity:"1"})},250),setTimeout(function(){$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),c.trigger($.extend(d,{phase:"after"})),c.resize()},500)),!0)}},hide:function(a,b){var c=this,d=this.trigger({phase:"before",type:"hide",target:a,object:this.get(a),immediate:b});if(d.isCancelled!==!0){var e=c.get(a);return null===e?!1:(e.hidden=!0,b===!0?($("#layout_"+c.name+"_panel_"+a).css({opacity:"0"}),$("#layout_"+c.name+"_resizer_"+a).hide(),c.trigger($.extend(d,{phase:"after"})),c.resize()):($("#layout_"+c.name+"_resizer_"+a).hide(),$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),$("#layout_"+c.name+"_panel_"+a).css({opacity:"0"}),setTimeout(function(){c.resize()},1),setTimeout(function(){$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),c.trigger($.extend(d,{phase:"after"})),c.resize()},500)),!0)}},toggle:function(a,b){var c=this.get(a);return null===c?!1:c.hidden?this.show(a,b):this.hide(a,b)},set:function(a,b){var c=this.get(a,!0);return null===c?!1:($.extend(this.panels[c],b),"undefined"!=typeof b.content&&this.refresh(a),this.resize(),!0)},get:function(a,b){for(var c in this.panels)if(this.panels[c].type==a)return b===!0?c:this.panels[c];return null},el:function(a){var b=$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-content");return 1!=b.length?null:b[0]},hideToolbar:function(a){var b=this.get(a);b&&(b.show.toolbar=!1,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-toolbar").hide(),this.resize())},showToolbar:function(a){var b=this.get(a);b&&(b.show.toolbar=!0,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-toolbar").show(),this.resize())},toggleToolbar:function(a){var b=this.get(a);b&&(b.show.toolbar?this.hideToolbar(a):this.showToolbar(a))},hideTabs:function(a){var b=this.get(a);b&&(b.show.tabs=!1,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-tabs").hide(),this.resize())},showTabs:function(a){var b=this.get(a);b&&(b.show.tabs=!0,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-tabs").show(),this.resize())},toggleTabs:function(a){var b=this.get(a);b&&(b.show.tabs?this.hideTabs(a):this.showTabs(a))},render:function(a){function c(){g.tmp.events={resize:function(){w2ui[g.name].resize()},resizeStart:d,mouseMove:f,mouseUp:e},$(window).on("resize",g.tmp.events.resize)}function d(a,c){if(g.box){c||(c=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),$(document).off("mousemove",g.tmp.events.mouseMove).on("mousemove",g.tmp.events.mouseMove),$(document).off("mouseup",g.tmp.events.mouseUp).on("mouseup",g.tmp.events.mouseUp),g.tmp.resize={type:a,x:c.screenX,y:c.screenY,diff_x:0,diff_y:0,value:0};for(var d in b)d=b[d],g.lock(d,{opacity:0});("left"==a||"right"==a)&&(g.tmp.resize.value=parseInt($("#layout_"+g.name+"_resizer_"+a)[0].style.left)),("top"==a||"preview"==a||"bottom"==a)&&(g.tmp.resize.value=parseInt($("#layout_"+g.name+"_resizer_"+a)[0].style.top))}}function e(a){if(g.box&&(a||(a=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),$(document).off("mousemove",g.tmp.events.mouseMove),$(document).off("mouseup",g.tmp.events.mouseUp),"undefined"!=typeof g.tmp.resize)){for(var c in b)g.unlock(b[c]);if(0!==g.tmp.diff_x||0!==g.tmp.resize.diff_y){var d,e,f=g.get("top"),h=g.get("bottom"),i=g.get(g.tmp.resize.type),j=parseInt($(g.box).height()),k=parseInt($(g.box).width()),l=String(i.size);switch(g.tmp.resize.type){case"top":d=parseInt(i.sizeCalculated)+g.tmp.resize.diff_y,e=0;break;case"bottom":d=parseInt(i.sizeCalculated)-g.tmp.resize.diff_y,e=0;break;case"preview":d=parseInt(i.sizeCalculated)-g.tmp.resize.diff_y,e=(f&&!f.hidden?f.sizeCalculated:0)+(h&&!h.hidden?h.sizeCalculated:0);break;case"left":d=parseInt(i.sizeCalculated)+g.tmp.resize.diff_x,e=0;break;case"right":d=parseInt(i.sizeCalculated)-g.tmp.resize.diff_x,e=0}i.size="%"==l.substr(l.length-1)?Math.floor(100*d/("left"==i.type||"right"==i.type?k:j-e)*100)/100+"%":d,g.resize()}$("#layout_"+g.name+"_resizer_"+g.tmp.resize.type).removeClass("active"),delete g.tmp.resize}}function f(a){if(g.box&&(a||(a=window.event),"undefined"!=typeof g.tmp.resize)){var b=g.get(g.tmp.resize.type),c=g.tmp.resize,d=g.trigger({phase:"before",type:"resizing",target:g.name,object:b,originalEvent:a,panel:c?c.type:"all",diff_x:c?c.diff_x:0,diff_y:c?c.diff_y:0});if(d.isCancelled!==!0){var e=$("#layout_"+g.name+"_resizer_"+c.type),f=a.screenX-c.x,h=a.screenY-c.y,i=g.get("main");switch(e.hasClass("active")||e.addClass("active"),c.type){case"left":b.minSize-f>b.width&&(f=b.minSize-b.width),b.maxSize&&b.width+f>b.maxSize&&(f=b.maxSize-b.width),i.minSize+f>i.width&&(f=i.width-i.minSize);break;case"right":b.minSize+f>b.width&&(f=b.width-b.minSize),b.maxSize&&b.width-f>b.maxSize&&(f=b.width-b.maxSize),i.minSize-f>i.width&&(f=i.minSize-i.width);break;case"top":b.minSize-h>b.height&&(h=b.minSize-b.height),b.maxSize&&b.height+h>b.maxSize&&(h=b.maxSize-b.height),i.minSize+h>i.height&&(h=i.height-i.minSize);break;case"preview":case"bottom":b.minSize+h>b.height&&(h=b.height-b.minSize),b.maxSize&&b.height-h>b.maxSize&&(h=b.height-b.maxSize),i.minSize-h>i.height&&(h=i.minSize-i.height)}switch(c.diff_x=f,c.diff_y=h,c.type){case"top":case"preview":case"bottom":c.diff_x=0,e.length>0&&(e[0].style.top=c.value+c.diff_y+"px");break;case"left":case"right":c.diff_y=0,e.length>0&&(e[0].style.left=c.value+c.diff_x+"px")}g.trigger($.extend(d,{phase:"after"}))}}}var g=this,h=(new Date).getTime(),i=g.trigger({phase:"before",type:"render",target:g.name,box:a});if(i.isCancelled!==!0){if("undefined"!=typeof a&&null!==a&&($(g.box).find("#layout_"+g.name+"_panel_main").length>0&&$(g.box).removeAttr("name").removeClass("w2ui-layout").html(""),g.box=a),!g.box)return!1;$(g.box).attr("name",g.name).addClass("w2ui-layout").html("
      "),$(g.box).length>0&&($(g.box)[0].style.cssText+=g.style);for(var j in b){j=b[j];var k=(g.get(j),'
      ');$(g.box).find(" > div").append(k)}return $(g.box).find(" > div").append('
      .w2ui-panel-content")[0],setTimeout(function(){$(f+"> .w2ui-panel-content").length>0&&($(f+"> .w2ui-panel-content").removeClass().addClass("w2ui-panel-content").css("overflow",e.overflow)[0].style.cssText+=";"+e.style),e.content.render()},1)):$(f+"> .w2ui-panel-content").length>0&&($(f+"> .w2ui-panel-content").removeClass().addClass("w2ui-panel-content").html(e.content).css("overflow",e.overflow)[0].style.cssText+=";"+e.style);var h=$(b.box).find(f+"> .w2ui-panel-tabs");e.show.tabs?0===h.find("[name="+e.tabs.name+"]").length&&null!==e.tabs?h.w2render(e.tabs):e.tabs.refresh():h.html("").removeClass("w2ui-tabs").hide(),h=$(b.box).find(f+"> .w2ui-panel-toolbar"),e.show.toolbar?0===h.find("[name="+e.toolbar.name+"]").length&&null!==e.toolbar?h.w2render(e.toolbar):e.toolbar.refresh():h.html("").removeClass("w2ui-toolbar").hide(),h=$(b.box).find(f+"> .w2ui-panel-title"),e.title?h.html(e.title).show():h.html("").hide()}else{if(0==$("#layout_"+b.name+"_panel_main").length)return void b.render();b.resize();for(var i in this.panels)b.refresh(this.panels[i].type)}return b.trigger($.extend(d,{phase:"after"})),(new Date).getTime()-c}},resize:function(){if(!this.box)return!1;var a=(new Date).getTime(),c=this.tmp.resize,d=this.trigger({phase:"before",type:"resize",target:this.name,panel:c?c.type:"all",diff_x:c?c.diff_x:0,diff_y:c?c.diff_y:0});if(d.isCancelled!==!0){this.padding<0&&(this.padding=0);var e=parseInt($(this.box).width()),f=parseInt($(this.box).height());$(this.box).find(" > div").css({width:e+"px",height:f+"px"});var g,h,i,j,k,l=this,m=this.get("main"),n=this.get("preview"),o=this.get("left"),p=this.get("right"),q=this.get("top"),r=this.get("bottom"),s=null!==n&&n.hidden!==!0?!0:!1,t=null!==o&&o.hidden!==!0?!0:!1,u=null!==p&&p.hidden!==!0?!0:!1,v=null!==q&&q.hidden!==!0?!0:!1,w=null!==r&&r.hidden!==!0?!0:!1;for(var x in b)if(x=b[x],"main"!==x){var c=this.get(x);if(c){var y=String(c.size||0);if("%"==y.substr(y.length-1)){var z=f;"preview"==c.type&&(z=z-(q&&!q.hidden?q.sizeCalculated:0)-(r&&!r.hidden?r.sizeCalculated:0)),c.sizeCalculated=parseInt(("left"==c.type||"right"==c.type?e:z)*parseFloat(c.size)/100)}else c.sizeCalculated=parseInt(c.size);c.sizeCalculated=Math.max(c.sizeCalculated,parseInt(c.minSize))}}null!==q&&q.hidden!==!0?(g=0,h=0,i=e,j=q.sizeCalculated,$("#layout_"+this.name+"_panel_top").css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px"}).show(),q.width=i,q.height=j,q.resizable&&(h=q.sizeCalculated-(0===this.padding?this.resizer:0),j=this.resizer>this.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_top").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"top",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("top",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_top").hide(),null!==o&&o.hidden!==!0?(g=0,h=0+(v?q.sizeCalculated+this.padding:0),i=o.sizeCalculated,j=f-(v?q.sizeCalculated+this.padding:0)-(w?r.sizeCalculated+this.padding:0),k=$("#layout_"+this.name+"_panel_left"),-1!=window.navigator.userAgent.indexOf("MSIE")&&k.length>0&&k[0].clientHeightthis.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_left").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"left",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("left",a),l.trigger($.extend(b,{phase:"after"})),!1}))):($("#layout_"+this.name+"_panel_left").hide(),$("#layout_"+this.name+"_resizer_left").hide()),null!==p&&p.hidden!==!0?(g=e-p.sizeCalculated,h=0+(v?q.sizeCalculated+this.padding:0),i=p.sizeCalculated,j=f-(v?q.sizeCalculated+this.padding:0)-(w?r.sizeCalculated+this.padding:0),$("#layout_"+this.name+"_panel_right").css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px"}).show(),p.width=i,p.height=j,p.resizable&&(g-=this.padding,i=this.resizer>this.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_right").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"right",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("right",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_right").hide(),null!==r&&r.hidden!==!0?(g=0,h=f-r.sizeCalculated,i=e,j=r.sizeCalculated,$("#layout_"+this.name+"_panel_bottom").css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px"}).show(),r.width=i,r.height=j,r.resizable&&(h-=0===this.padding?0:this.padding,j=this.resizer>this.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_bottom").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"bottom",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("bottom",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_bottom").hide(),g=0+(t?o.sizeCalculated+this.padding:0),h=0+(v?q.sizeCalculated+this.padding:0),i=e-(t?o.sizeCalculated+this.padding:0)-(u?p.sizeCalculated+this.padding:0),j=f-(v?q.sizeCalculated+this.padding:0)-(w?r.sizeCalculated+this.padding:0)-(s?n.sizeCalculated+this.padding:0),k=$("#layout_"+this.name+"_panel_main"),-1!=window.navigator.userAgent.indexOf("MSIE")&&k.length>0&&k[0].clientHeight0&&k[0].clientHeightthis.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_preview").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"preview",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("preview",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_preview").hide();for(var A in b){A=b[A];var B=this.get(A),C="#layout_"+this.name+"_panel_"+A+" > .w2ui-panel-",D=0;B&&(B.title&&(D+=w2utils.getSize($(C+"title").css({top:D+"px",display:"block"}),"height")),B.show.tabs&&(null!==B.tabs&&w2ui[this.name+"_"+A+"_tabs"]&&w2ui[this.name+"_"+A+"_tabs"].resize(),D+=w2utils.getSize($(C+"tabs").css({top:D+"px",display:"block"}),"height")),B.show.toolbar&&(null!==B.toolbar&&w2ui[this.name+"_"+A+"_toolbar"]&&w2ui[this.name+"_"+A+"_toolbar"].resize(),D+=w2utils.getSize($(C+"toolbar").css({top:D+"px",display:"block"}),"height"))),$(C+"content").css({display:"block"}).css({top:D+"px"})}return clearTimeout(this._resize_timer),this._resize_timer=setTimeout(function(){for(var a in w2ui)if("function"==typeof w2ui[a].resize){"undefined"==w2ui[a].panels&&w2ui[a].resize(); -var b=$(w2ui[a].box).parents(".w2ui-layout");b.length>0&&b.attr("name")==l.name&&w2ui[a].resize()}},100),this.trigger($.extend(d,{phase:"after"})),(new Date).getTime()-a}},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});if(a.isCancelled!==!0)return"undefined"==typeof w2ui[this.name]?!1:($(this.box).find("#layout_"+this.name+"_panel_main").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-layout").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})),this.tmp.events&&this.tmp.events.resize&&$(window).off("resize",this.tmp.events.resize),!0)},lock:function(a){if(-1==b.indexOf(a))return void console.log("ERROR: First parameter needs to be the a valid panel name.");var c=Array.prototype.slice.call(arguments,0);c[0]="#layout_"+this.name+"_panel_"+a,w2utils.lock.apply(window,c)},unlock:function(a){if(-1==b.indexOf(a))return void console.log("ERROR: First parameter needs to be the a valid panel name.");var c="#layout_"+this.name+"_panel_"+a;w2utils.unlock(c)}},$.extend(a.prototype,w2utils.event),w2obj.layout=a}();var w2popup={};!function(){$.fn.w2popup=function(a,b){"undefined"==typeof a&&(b={},a="open"),$.isPlainObject(a)&&(b=a,a="open"),a=a.toLowerCase(),"load"===a&&"string"==typeof b&&(b=$.extend({url:b},arguments.length>2?arguments[2]:{})),"open"===a&&null!=b.url&&(a="load"),b=b||{};var c={};return $(this).length>0&&($(this).find("div[rel=title], div[rel=body], div[rel=buttons]").length>0?($(this).find("div[rel=title]").length>0&&(c.title=$(this).find("div[rel=title]").html()),$(this).find("div[rel=body]").length>0&&(c.body=$(this).find("div[rel=body]").html(),c.style=$(this).find("div[rel=body]")[0].style.cssText),$(this).find("div[rel=buttons]").length>0&&(c.buttons=$(this).find("div[rel=buttons]").html())):(c.title=" ",c.body=$(this).html()),0!=parseInt($(this).css("width"))&&(c.width=parseInt($(this).css("width"))),0!=parseInt($(this).css("height"))&&(c.height=parseInt($(this).css("height")))),w2popup[a]($.extend({},c,b))},w2popup={defaults:{title:"",body:"",buttons:"",style:"",color:"#000",opacity:.4,speed:.3,modal:!1,maximized:!1,keyboard:!0,width:500,height:300,showClose:!0,showMax:!1,transition:null},status:"closed",handlers:[],onOpen:null,onClose:null,onMax:null,onMin:null,onToggle:null,onKeydown:null,open:function(a){function b(a){return a||(a=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),w2popup.status="moving",p.resizing=!0,p.x=a.screenX,p.y=a.screenY,p.pos_x=$("#w2ui-popup").position().left,p.pos_y=$("#w2ui-popup").position().top,w2popup.lock({opacity:0}),$(document).on("mousemove",p.mvMove),$(document).on("mouseup",p.mvStop),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,a.preventDefault?void a.preventDefault():!1}function c(a){1==p.resizing&&(a||(a=window.event),p.div_x=a.screenX-p.x,p.div_y=a.screenY-p.y,$("#w2ui-popup").css({"-webkit-transition":"none","-webkit-transform":"translate3d("+p.div_x+"px, "+p.div_y+"px, 0px)","-moz-transition":"none","-moz-transform":"translate("+p.div_x+"px, "+p.div_y+"px)","-ms-transition":"none","-ms-transform":"translate("+p.div_x+"px, "+p.div_y+"px)","-o-transition":"none","-o-transform":"translate("+p.div_x+"px, "+p.div_y+"px)"}))}function d(a){1==p.resizing&&(a||(a=window.event),w2popup.status="open",p.div_x=a.screenX-p.x,p.div_y=a.screenY-p.y,$("#w2ui-popup").css({left:p.pos_x+p.div_x+"px",top:p.pos_y+p.div_y+"px","-webkit-transition":"none","-webkit-transform":"translate3d(0px, 0px, 0px)","-moz-transition":"none","-moz-transform":"translate(0px, 0px)","-ms-transition":"none","-ms-transform":"translate(0px, 0px)","-o-transition":"none","-o-transform":"translate(0px, 0px)"}),p.resizing=!1,$(document).off("mousemove",p.mvMove),$(document).off("mouseup",p.mvStop),w2popup.unlock())}var e=this;if("closing"==w2popup.status)return void setTimeout(function(){e.open.call(e,a)},100);var f=$("#w2ui-popup").data("options"),a=$.extend({},this.defaults,{body:""},f,a,{maximized:!1});if(setTimeout(function(){$("#w2ui-popup").data("options",a)},100),0==$("#w2ui-popup").length&&(w2popup.handlers=[],w2popup.onMax=null,w2popup.onMin=null,w2popup.onToggle=null,w2popup.onOpen=null,w2popup.onClose=null,w2popup.onKeydown=null),a.onOpen&&(w2popup.onOpen=a.onOpen),a.onClose&&(w2popup.onClose=a.onClose),a.onMax&&(w2popup.onMax=a.onMax),a.onMin&&(w2popup.onMin=a.onMin),a.onToggle&&(w2popup.onToggle=a.onToggle),a.onKeydown&&(w2popup.onKeydown=a.onKeydown),void 0==window.innerHeight){var g=document.documentElement.offsetWidth,h=document.documentElement.offsetHeight;"IE7"===w2utils.engine&&(g+=21,h+=4)}else var g=window.innerWidth,h=window.innerHeight;parseInt(g)-10';""!=a.title&&(l+='
      '+(a.showClose?'
      Close
      ':"")+(a.showMax?'
      Max
      ':"")+a.title+"
      "),l+='
      ',l+='
      '+a.body+"
      ",l+="
      ",l+='
      ',l+='
      ',l+="
      ",""!=a.buttons&&(l+='
      '+a.buttons+"
      "),l+="
      ",$("body").append(l),setTimeout(function(){$("#w2ui-popup .w2ui-box2").hide(),$("#w2ui-popup").css({"-webkit-transition":a.speed+"s opacity, "+a.speed+"s -webkit-transform","-webkit-transform":"scale(1)","-moz-transition":a.speed+"s opacity, "+a.speed+"s -moz-transform","-moz-transform":"scale(1)","-ms-transition":a.speed+"s opacity, "+a.speed+"s -ms-transform","-ms-transform":"scale(1)","-o-transition":a.speed+"s opacity, "+a.speed+"s -o-transform","-o-transform":"scale(1)",opacity:"1"})},1),setTimeout(function(){$("#w2ui-popup").css({"-webkit-transform":"","-moz-transform":"","-ms-transform":"","-o-transform":""}),w2popup.status="open",setTimeout(function(){e.trigger($.extend(k,{phase:"after"}))},100)},1e3*a.speed)}else{var k=this.trigger({phase:"before",type:"open",target:"popup",options:a,present:!0});if(k.isCancelled===!0)return;w2popup.status="opening",("undefined"==typeof f||f.width!=a.width||f.height!=a.height)&&w2popup.resize(a.width,a.height),"undefined"!=typeof f&&(a.prevSize=a.width+":"+a.height,a.maximized=f.maximized);var m=$("#w2ui-popup .w2ui-box2 > .w2ui-msg-body").html(a.body);m.length>0&&(m[0].style.cssText=a.style),$("#w2ui-popup .w2ui-msg-buttons").html(a.buttons),$("#w2ui-popup .w2ui-msg-title").html((a.showClose?'
      Close
      ':"")+(a.showMax?'
      Max
      ':"")+a.title);var n=$("#w2ui-popup .w2ui-box1")[0],o=$("#w2ui-popup .w2ui-box2")[0];w2utils.transition(n,o,a.transition),o.className="w2ui-box1",n.className="w2ui-box2",$(o).addClass("w2ui-current-box"),$("#w2ui-popup").data("prev-size",null),setTimeout(function(){w2popup.status="open",e.trigger($.extend(k,{phase:"after"}))},100)}a._last_w2ui_name=w2utils.keyboard.active(),w2utils.keyboard.active(null),a.keyboard&&$(document).on("keydown",this.keydown);var p={resizing:!1,mvMove:c,mvStop:d};return $("#w2ui-popup .w2ui-msg-title").on("mousedown",function(a){b(a)}),this},keydown:function(a){var b=$("#w2ui-popup").data("options");if(b.keyboard){var c=w2popup.trigger({phase:"before",type:"keydown",target:"popup",options:b,originalEvent:a});if(c.isCancelled!==!0){switch(a.keyCode){case 27:a.preventDefault(),$("#w2ui-popup .w2ui-popup-message").length>0?w2popup.message():w2popup.close()}w2popup.trigger($.extend(c,{phase:"after"}))}}},close:function(a){var b=this,a=$.extend({},$("#w2ui-popup").data("options"),a);if(0!=$("#w2ui-popup").length){var c=this.trigger({phase:"before",type:"close",target:"popup",options:a});c.isCancelled!==!0&&(w2popup.status="closing",$("#w2ui-popup").css({"-webkit-transition":a.speed+"s opacity, "+a.speed+"s -webkit-transform","-webkit-transform":"scale(0.9)","-moz-transition":a.speed+"s opacity, "+a.speed+"s -moz-transform","-moz-transform":"scale(0.9)","-ms-transition":a.speed+"s opacity, "+a.speed+"s -ms-transform","-ms-transform":"scale(0.9)","-o-transition":a.speed+"s opacity, "+a.speed+"s -o-transform","-o-transform":"scale(0.9)",opacity:"0"}),w2popup.unlockScreen(a),setTimeout(function(){$("#w2ui-popup").remove(),w2popup.status="closed",b.trigger($.extend(c,{phase:"after"}))},1e3*a.speed),w2utils.keyboard.active(a._last_w2ui_name),a.keyboard&&$(document).off("keydown",this.keydown))}},toggle:function(){var a=this,b=$("#w2ui-popup").data("options"),c=this.trigger({phase:"before",type:"toggle",target:"popup",options:b});c.isCancelled!==!0&&(b.maximized===!0?w2popup.min():w2popup.max(),setTimeout(function(){a.trigger($.extend(c,{phase:"after"}))},250))},max:function(){var a=this,b=$("#w2ui-popup").data("options");if(b.maximized!==!0){var c=this.trigger({phase:"before",type:"max",target:"popup",options:b});c.isCancelled!==!0&&(w2popup.status="resizing",b.prevSize=$("#w2ui-popup").css("width")+":"+$("#w2ui-popup").css("height"),w2popup.resize(1e4,1e4,function(){w2popup.status="open",b.maximized=!0,a.trigger($.extend(c,{phase:"after"}))}))}},min:function(){var a=this,b=$("#w2ui-popup").data("options");if(b.maximized===!0){var c=b.prevSize.split(":"),d=this.trigger({phase:"before",type:"min",target:"popup",options:b});d.isCancelled!==!0&&(w2popup.status="resizing",w2popup.resize(c[0],c[1],function(){w2popup.status="open",b.maximized=!1,b.prevSize=null,a.trigger($.extend(d,{phase:"after"}))}))}},get:function(){return $("#w2ui-popup").data("options")},set:function(a){w2popup.open(a)},clear:function(){$("#w2ui-popup .w2ui-msg-title").html(""),$("#w2ui-popup .w2ui-msg-body").html(""),$("#w2ui-popup .w2ui-msg-buttons").html("")},reset:function(){w2popup.open(w2popup.defaults)},load:function(a){function b(b,c){if(delete a.url,$("body").append('"),"undefined"!=typeof c&&$("#w2ui-tmp #"+c).length>0?$("#w2ui-tmp #"+c).w2popup(a):$("#w2ui-tmp > div").w2popup(a),$("#w2ui-tmp > style").length>0){var d=$("
      ").append($("#w2ui-tmp > style").clone()).html();0==$("#w2ui-popup #div-style").length&&$("#w2ui-popup").append('
      '),$("#w2ui-popup #div-style").html(d)}$("#w2ui-tmp").remove()}if(w2popup.status="loading","undefined"==String(a.url))return void console.log("ERROR: The url parameter is empty.");var c=String(a.url).split("#"),d=c[0],e=c[1];"undefined"==String(a)&&(a={});var f=$("#w2ui-popup").data(d);"undefined"!=typeof f&&null!=f?b(f,e):$.get(d,function(a,c,f){b(f.responseText,e),$("#w2ui-popup").data(d,f.responseText)})},message:function(a){$().w2tag(),a||(a={width:200,height:100}),parseInt(a.width)<10&&(a.width=10),parseInt(a.height)<10&&(a.height=10),"undefined"==typeof a.hideOnClick&&(a.hideOnClick=!1);var b=$("#w2ui-popup").data("options");("undefined"==typeof a.width||a.width>b.width-10)&&(a.width=b.width-10),("undefined"==typeof a.height||a.height>b.height-40)&&(a.height=b.height-40);var c=$("#w2ui-popup .w2ui-msg-title"),d=parseInt($("#w2ui-popup").width()),e=$("#w2ui-popup .w2ui-popup-message").length;if(""==$.trim(a.html)){$("#w2ui-popup #w2ui-message"+(e-1)).css("z-Index",250);var a=$("#w2ui-popup #w2ui-message"+(e-1)).data("options")||{};$("#w2ui-popup #w2ui-message"+(e-1)).remove(),"function"==typeof a.onClose&&a.onClose(),1==e?w2popup.unlock():$("#w2ui-popup #w2ui-message"+(e-2)).show()}else{$("#w2ui-popup .w2ui-popup-message").hide(),$("#w2ui-popup .w2ui-box1").before('"),$("#w2ui-popup #w2ui-message"+e).data("options",a);var f=$("#w2ui-popup #w2ui-message"+e).css("display");$("#w2ui-popup #w2ui-message"+e).css({"-webkit-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)","-moz-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)","-ms-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)","-o-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)"}),"none"==f&&($("#w2ui-popup #w2ui-message"+e).show().html(a.html),setTimeout(function(){$("#w2ui-popup #w2ui-message"+e).css({"-webkit-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)","-moz-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)","-ms-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)","-o-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)"})},1),setTimeout(function(){$("#w2ui-popup #w2ui-message"+e).css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s","z-Index":1500}),0==e&&w2popup.lock(),"function"==typeof a.onOpen&&a.onOpen()},300))}},lock:function(){var a=Array.prototype.slice.call(arguments,0);a.unshift($("#w2ui-popup")),w2utils.lock.apply(window,a)},unlock:function(){w2utils.unlock($("#w2ui-popup"))},lockScreen:function(a){return $("#w2ui-lock").length>0?!1:("undefined"==typeof a&&(a=$("#w2ui-popup").data("options")),"undefined"==typeof a&&(a={}),a=$.extend({},w2popup.defaults,a),$("body").append('
      '),setTimeout(function(){$("#w2ui-lock").css({"-webkit-transition":a.speed+"s opacity","-moz-transition":a.speed+"s opacity","-ms-transition":a.speed+"s opacity","-o-transition":a.speed+"s opacity",opacity:a.opacity})},1),1==a.modal?($("#w2ui-lock").on("mousedown",function(){$("#w2ui-lock").css({"-webkit-transition":".1s","-moz-transition":".1s","-ms-transition":".1s","-o-transition":".1s",opacity:"0.6"})}),$("#w2ui-lock").on("mouseup",function(){setTimeout(function(){$("#w2ui-lock").css({"-webkit-transition":".1s","-moz-transition":".1s","-ms-transition":".1s","-o-transition":".1s",opacity:a.opacity})},100)})):$("#w2ui-lock").on("mouseup",function(){w2popup.close()}),!0)},unlockScreen:function(a){return 0==$("#w2ui-lock").length?!1:("undefined"==typeof a&&(a=$("#w2ui-popup").data("options")),"undefined"==typeof a&&(a={}),a=$.extend({},w2popup.defaults,a),$("#w2ui-lock").css({"-webkit-transition":a.speed+"s opacity","-moz-transition":a.speed+"s opacity","-ms-transition":a.speed+"s opacity","-o-transition":a.speed+"s opacity",opacity:0}),setTimeout(function(){$("#w2ui-lock").remove()},1e3*a.speed),!0)},resize:function(a,b,c){var d=$("#w2ui-popup").data("options");parseInt($(window).width())-100&&"closing"!=w2popup.status?w2popup.message({width:400,height:150,html:'
      '+a+'
      ",onClose:function(){"function"==typeof c&&c()}}):w2popup.open({width:450,height:200,showMax:!1,title:b,body:'
      '+a+"
      ",buttons:'",onClose:function(){"function"==typeof c&&c()}})},w2confirm=function(a,b){var c=400,d=150,e="Yes",f="",g="",h="No",i="",j="",k=w2utils.lang("Confirmation");if(1==arguments.length&&"object"==typeof a){var l=w2utils.lang(a.msg),b=a.callBack,m=a.btn_yes,n=a.btn_no;a.title&&(k=w2utils.lang(a.title)),w2utils.isInt(a.width)&&(c=a.width),w2utils.isInt(a.height)&&(d=a.height),m&&(m.text&&(e=w2utils.lang(m.text)),m.class&&(f=m.class),m.style&&(g=m.style)),n&&(n.text&&(h=w2utils.lang(n.text)),n.class&&(i=n.class),n.style&&(j=n.style))}else var l=a;$("#w2ui-popup").length>0&&"closing"!=w2popup.status?(c>w2popup.get().width&&(c=w2popup.get().width),d>w2popup.get().height-50&&(d=w2popup.get().height-50),w2popup.message({width:c,height:d,html:'
      '+l+'
      ",onOpen:function(){$("#w2ui-popup .w2ui-popup-message .btn").on("click",function(a){w2popup.message(),"function"==typeof b&&b(a.target.id)})},onKeydown:function(a){switch(a.originalEvent.keyCode){case 13:"function"==typeof b&&b("Yes"),w2popup.message();break;case 27:"function"==typeof b&&b("No"),w2popup.message()}}})):(w2utils.isInt(a.height)||(d+=50),w2popup.open({width:c,height:d,title:k,modal:!0,showClose:!1,body:'
      '+l+"
      ",buttons:'",onOpen:function(a){a.onComplete=function(){$("#w2ui-popup .w2ui-popup-btn").on("click",function(a){w2popup.close(),"function"==typeof b&&b(a.target.id)})}},onKeydown:function(a){switch(a.originalEvent.keyCode){case 13:"function"==typeof b&&b("Yes"),w2popup.close();break;case 27:"function"==typeof b&&b("No"),w2popup.close()}}}))};!function(){var a=function(a){this.box=null,this.name=null,this.active=null,this.tabs=[],this.right="",this.style="",this.onClick=null,this.onClose=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(this,{handlers:[]}),$.extend(!0,this,w2obj.tabs,a)};$.fn.w2tabs=function(b){if("object"!=typeof b&&b){if(w2ui[$(this).attr("name")]){var c=w2ui[$(this).attr("name")];return c[b].apply(c,Array.prototype.slice.call(arguments,1)),this}return void console.log("ERROR: Method "+b+" does not exist on jQuery.w2tabs")}if(w2utils.checkName(b,"w2tabs")){for(var d=b.tabs||[],e=new a(b),f=0;f
      ":"")+'
      "+e.text+"
      ";if(0===f.length){var h="";e.hidden&&(h+="display: none;"),e.disabled&&(h+="opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);");var i='
      ";this.get(a,!0)!==this.tabs.length-1&&$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))+1].id)).length>0?$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))+1].id)).before(i):$(this.box).find("#tabs_"+this.name+"_right").before(i)}else f.html(g),e.hidden?f.css("display","none"):f.css("display",""),f.css(e.disabled?{opacity:"0.2","-moz-opacity":"0.2","-webkit-opacity":"0.2","-o-opacity":"0.2",filter:"alpha(opacity=20)"}:{opacity:"1","-moz-opacity":"1","-webkit-opacity":"1","-o-opacity":"1",filter:"alpha(opacity=100)"})}return $("#tabs_"+this.name+"_right").html(this.right),this.trigger($.extend(c,{phase:"after"})),(new Date).getTime()-b}},render:function(a){var b=(new Date).getTime(),c=this.trigger({phase:"before",type:"render",target:this.name,box:a});if(c.isCancelled!==!0){if("undefined"!=typeof a&&null!==a&&($(this.box).find("> table #tabs_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),this.box=a),!this.box)return!1;var d='
      '+(c!==!0?"
      "+b+"
      ":"")+"
      '+(c!==!0?'
      ":"")+"
      '+(c!==!0?'
      "+j+"
      ":"")+"
      "+n+"
      '+g+"
      '+this.right+"
      ";return $(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-tabs").html(d),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),this.trigger($.extend(c,{phase:"after"})),this.refresh(),(new Date).getTime()-b}},resize:function(){var a=(new Date).getTime(),b=this.trigger({phase:"before",type:"resize",target:this.name});return b.isCancelled!==!0?(this.trigger($.extend(b,{phase:"after"})),(new Date).getTime()-a):void 0},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});a.isCancelled!==!0&&($(this.box).find("> table #tabs_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})))},click:function(a,b){var c=this.get(a);if(null===c||c.disabled)return!1;var d=this.trigger({phase:"before",type:"click",target:a,tab:c,object:c,originalEvent:b});d.isCancelled!==!0&&($(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.active)+" .w2ui-tab").removeClass("active"),this.active=c.id,this.trigger($.extend(d,{phase:"after"})),this.refresh(a))},animateClose:function(a,b){var c=this.get(a);if(null===c||c.disabled)return!1;var d=this.trigger({phase:"before",type:"close",target:a,object:this.get(a),originalEvent:b});if(d.isCancelled!==!0){var e=this;$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(c.id)).css({"-webkit-transition":".2s","-moz-transition":"2s","-ms-transition":".2s","-o-transition":".2s",opacity:"0"}),setTimeout(function(){var a=$(e.box).find("#tabs_"+e.name+"_tab_"+w2utils.escapeId(c.id)).width();$(e.box).find("#tabs_"+e.name+"_tab_"+w2utils.escapeId(c.id)).html('
      '),setTimeout(function(){$(e.box).find("#tabs_"+e.name+"_tab_"+w2utils.escapeId(c.id)).find(":first-child").css({width:"0px"})},50)},200),setTimeout(function(){e.remove(a)},450),this.trigger($.extend(d,{phase:"after"})),this.refresh()}},animateInsert:function(a,b){if(null!==this.get(a)&&$.isPlainObject(b)&&w2utils.checkUniqueId(b.id,this.tabs,"tabs",this.name)){var c=$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(b.id));if(0===c.length){"undefined"!=typeof b.caption&&(b.text=b.caption);var d='
      '+(b.closable?'
      ':"")+'
      '+b.text+"
      ";$("body").append(d);var e='
       
      ',f="";b.hidden&&(f+="display: none;"),b.disabled&&(f+="opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);");var g=''+e+"";this.get(a,!0)!==this.tabs.length&&$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))].id)).length>0?$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))].id)).before(g):$(this.box).find("#tabs_"+this.name+"_right").before(g);var h=this;setTimeout(function(){var a=$("#_tmp_simple_tab").width();$("#_tmp_tabs").remove(),$("#tabs_"+h.name+"_tab_"+w2utils.escapeId(b.id)+" > div").css("width",a+"px")},1),setTimeout(function(){h.insert(a,b)},200)}}}},$.extend(a.prototype,w2utils.event),w2obj.tabs=a}(),function(){var a=function(a){this.box=null,this.name=null,this.items=[],this.right="",this.onClick=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(!0,this,w2obj.toolbar,a)};$.fn.w2toolbar=function(b){if("object"==typeof b||!b){if(!w2utils.checkName(b,"w2toolbar"))return;var c=b.items||[],d=new a(b);$.extend(d,{items:[],handlers:[]});for(var e=0;e table #tb_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),this.box=a),this.box)){for(var d='',e=0;e':'")}return d+='",d+="
      '+this.getItemHTML(f)+"'+this.right+"
      ",$(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-toolbar").html(d),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),this.trigger($.extend(c,{phase:"after"})),(new Date).getTime()-b}},refresh:function(a){var b=(new Date).getTime(),c=this.trigger({phase:"before",type:"refresh",target:"undefined"!=typeof a?a:this.name,item:this.get(a)});if(c.isCancelled!==!0){if(null==a)for(var d=0;d':''+h+"",this.get(a,!0)===this.items.length-1?$(this.box).find("#tb_"+this.name+"_right").before(h):$(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(this.items[parseInt(this.get(a,!0))+1].id)).before(h)):(g.html(h),f.hidden?g.css("display","none"):g.css("display",""),f.disabled?g.addClass("disabled"):g.removeClass("disabled")),this.trigger($.extend(c,{phase:"after"})),(new Date).getTime()-b}},resize:function(){var a=(new Date).getTime(),b=this.trigger({phase:"before",type:"resize",target:this.name});return b.isCancelled!==!0?(this.trigger($.extend(b,{phase:"after"})),(new Date).getTime()-a):void 0},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});a.isCancelled!==!0&&($(this.box).find("> table #tb_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),$(this.box).html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})))},getItemHTML:function(a){var b="";switch("undefined"!=typeof a.caption&&(a.text=a.caption),"undefined"==typeof a.hint&&(a.hint=""),"undefined"==typeof a.text&&(a.text=""),a.type){case"menu":case"button":case"check":case"radio":case"drop":var c=" ";a.img&&(c='
      '),a.icon&&(c='
      '),b+='
      '+c+(""!==a.text?'":"")+("drop"!==a.type&&"menu"!==a.type||a.arrow===!1?"":'')+"
      '+a.text+"
      ";break;case"break":b+='
       
      ';break;case"html":b+='
      '+a.html+"
      "}var d="";return"function"==typeof a.onRender&&(d=a.onRender.call(this,a.id,b)),"function"==typeof this.onRender&&(d=this.onRender(a.id,b)),""!==d&&null!=d&&(b=d),b},menuClick:function(a){if(a.item&&!a.item.disabled){var b=this.trigger({phase:"before",type:"click",target:a.item.id+":"+a.subItem.id,item:a.item,subItem:a.subItem,originalEvent:a.originalEvent});if(b.isCancelled===!0)return;this.trigger($.extend(b,{phase:"after"}))}},click:function(a,b){var c=this,d=this.get(a);if(d&&!d.disabled){var e=this.trigger({phase:"before",type:"click",target:"undefined"!=typeof a?a:this.name,item:d,object:d,originalEvent:b});if(e.isCancelled===!0)return;var f=$("#tb_"+this.name+"_item_"+w2utils.escapeId(d.id)+" table.w2ui-button");if(f.removeClass("down"),"radio"===d.type){for(var g=0;g19&&(e=19),"drop"===d.type&&b.w2overlay(d.html,$.extend({left:e,top:3},d.overlay)),"menu"===d.type&&b.w2menu(d.items,$.extend({left:e,top:3},d.overlay,{select:function(b){c.menuClick({item:d,subItem:b.item,originalEvent:b.originalEvent}),a()}})),$(document).on("click",a)},1)),("check"===d.type||"drop"===d.type||"menu"===d.type)&&(d.checked=!d.checked,d.checked?f.addClass("checked"):f.removeClass("checked")),this.trigger($.extend(e,{phase:"after"}))}}},$.extend(a.prototype,w2utils.event),w2obj.toolbar=a}(),function(){var a=function(a){this.name=null,this.box=null,this.sidebar=null,this.parent=null,this.nodes=[],this.menu=[],this.selected=null,this.img=null,this.icon=null,this.style="",this.topHTML="",this.bottomHTML="",this.keyboard=!0,this.onClick=null,this.onDblClick=null,this.onContextMenu=null,this.onMenuClick=null,this.onExpand=null,this.onCollapse=null,this.onKeydown=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(!0,this,w2obj.sidebar,a)};$.fn.w2sidebar=function(b){if("object"==typeof b||!b){if(!w2utils.checkName(b,"w2sidebar"))return;var c=b.nodes,d=new a(b);return $.extend(d,{handlers:[],nodes:[]}),"undefined"!=typeof c&&d.add(d,c),0!==$(this).length&&d.render($(this)[0]),d.sidebar=d,w2ui[d.name]=d,d}if(w2ui[$(this).attr("name")]){var e=w2ui[$(this).attr("name")];return e[b].apply(e,Array.prototype.slice.call(arguments,1)),this}console.log("ERROR: Method "+b+" does not exist on jQuery.w2sidebar")},a.prototype={node:{id:null,text:"",count:null,img:null,icon:null,nodes:[],style:"",selected:!1,expanded:!1,hidden:!1,disabled:!1,group:!1,groupShowHide:!0,plus:!1,onClick:null,onDblClick:null,onContextMenu:null,onExpand:null,onCollapse:null,parent:null,sidebar:null},add:function(a,b){return 1==arguments.length&&(b=arguments[0],a=this),"string"==typeof a&&(a=this.get(a)),this.insert(a,null,b)},insert:function(b,c,d){var e,f,g,h,i;if(2==arguments.length){if(d=arguments[1],c=arguments[0],f=this.get(c),null===f)return $.isArray(d)||(d=[d]),e=null!=d[0].caption?d[0].caption:d[0].text,console.log('ERROR: Cannot insert node "'+e+'" because cannot find node "'+c+'" to insert before.'),null;b=this.get(c).parent}"string"==typeof b&&(b=this.get(b)),$.isArray(d)||(d=[d]);for(var j in d)if(h=d[j],null!=typeof h.id)if(null===this.get(this,h.id)){if(g=$.extend({},a.prototype.node,h),g.sidebar=this,g.parent=b,i=g.nodes||[],g.nodes=[],null===c)b.nodes.push(g);else{if(f=this.get(b,c,!0),null===f)return e=null!=h.caption?h.caption:h.text,console.log('ERROR: Cannot insert node "'+e+'" because cannot find node "'+c+'" to insert before.'),null;b.nodes.splice(f,0,g)}i.length>0&&this.insert(g,null,i)}else e=null!=h.caption?h.caption:h.text,console.log("ERROR: Cannot insert node with id="+h.id+" (text: "+e+") because another node with the same id already exists.");else e=null!=h.caption?h.caption:h.text,console.log('ERROR: Cannot insert node "'+e+'" because it has no id.');return this.refresh(b.id),g},remove:function(){for(var a,b=0,c=0;c0&&1==arguments.length?this.refresh(a.parent.id):this.refresh(),b},set:function(a,b,c){if(2==arguments.length&&(c=b,b=a,a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return null;for(var d=0;d0&&(c=this.find(a.nodes[d],b,c))}return c},hide:function(){for(var a=0,b=0;b+
      '),c.expanded=!1,this.trigger($.extend(d,{phase:"after"})),setTimeout(function(){b.refresh(a)},200),!0):void 0},collapseAll:function(a){if("undefined"==typeof a&&(a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return!1;for(var b=0;b0&&this.collapseAll(a.nodes[b]);return this.refresh(a.id),!0},expand:function(a){var b=this,c=this.get(a),d=this.trigger({phase:"before",type:"expand",target:a,object:c});return d.isCancelled!==!0?($(this.box).find("#node_"+w2utils.escapeId(a)+"_sub").slideDown(200),$(this.box).find("#node_"+w2utils.escapeId(a)+" .w2ui-node-dots:first-child").html('
      -
      '),c.expanded=!0,this.trigger($.extend(d,{phase:"after"})),setTimeout(function(){b.refresh(a)},200),!0):void 0},expandAll:function(a){if("undefined"==typeof a&&(a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return!1;for(var b=0;b0&&this.collapseAll(a.nodes[b]);this.refresh(a.id)},expandParents:function(a){var b=this.get(a);return null===b?!1:(b.parent&&(b.parent.expanded=!0,this.expandParents(b.parent.id)),this.refresh(a),!0)},click:function(a,b){var c=this,d=this.get(a);if(null!==d&&!d.disabled&&!d.group){$(c.box).find(".w2ui-node.w2ui-selected").each(function(a,b){var d=$(b).attr("id").replace("node_",""),e=c.get(d);null!=e&&(e.selected=!1),$(b).removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected")});var e=$(c.box).find("#node_"+w2utils.escapeId(a)),f=$(c.box).find("#node_"+w2utils.escapeId(c.selected));e.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected"),setTimeout(function(){var g=c.trigger({phase:"before",type:"click",target:a,originalEvent:b,node:d,object:d});return g.isCancelled===!0?(e.removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected"),void f.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected")):(null!==f&&(f.selected=!1),c.get(a).selected=!0,c.selected=a,void c.trigger($.extend(g,{phase:"after"})))},1)}},keydown:function(a){function b(a,b){null===a||a.hidden||a.disabled||a.group||(g.click(a.id,b),setTimeout(function(){g.scrollIntoView()},50))}function c(a,b){for(a=b(a);null!==a&&(a.hidden||a.disabled)&&!a.group;)a=b(a);return a}function d(a,b){if(null===a)return null;var c=a.parent,e=g.get(a.id,!0),f=null;if(a.expanded&&a.nodes.length>0&&b!==!0){var h=a.nodes[0];f=h.hidden||h.disabled||h.group?d(h):h}else f=c&&e+10?f(b.nodes[c-1]):b;return null!==d&&(d.hidden||d.disabled||d.group)&&(d=e(d)),d}function f(a){if(a.expanded&&a.nodes.length>0){var b=a.nodes[a.nodes.length-1];return b.hidden||b.disabled||b.group?e(b):f(b)}return a}var g=this,h=g.get(g.selected);if(h&&g.keyboard===!0){var i=g.trigger({phase:"before",type:"keydown",target:g.name,originalEvent:a});i.isCancelled!==!0&&((13==a.keyCode||32==a.keyCode)&&h.nodes.length>0&&g.toggle(g.selected),37==a.keyCode&&(h.nodes.length>0&&h.expanded?g.collapse(g.selected):(b(h.parent),h.parent.group||g.collapse(h.parent.id))),39==a.keyCode&&(h.nodes.length>0||h.plus)&&!h.expanded&&g.expand(g.selected),38==a.keyCode&&b(c(h,e)),40==a.keyCode&&b(c(h,d)),-1!=$.inArray(a.keyCode,[13,32,37,38,39,40])&&(a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation()),g.trigger($.extend(i,{phase:"after"})))}},scrollIntoView:function(a){"undefined"==typeof a&&(a=this.selected);var b=this.get(a);if(null!==b){var c=$(this.box).find(".w2ui-sidebar-div"),d=$(this.box).find("#node_"+w2utils.escapeId(a)),e=d.offset().top-c.offset().top;e+d.height()>c.height()&&c.animate({scrollTop:c.scrollTop()+c.height()/1.3},250,"linear"),0>=e&&c.animate({scrollTop:c.scrollTop()-c.height()/1.3},250,"linear")}},dblClick:function(a,b){var c=this.get(a),d=this.trigger({phase:"before",type:"dblClick",target:a,originalEvent:b,object:c});d.isCancelled!==!0&&(this.toggle(a),this.trigger($.extend(d,{phase:"after"})))},contextMenu:function(a,b){var c=this,d=c.get(a);a!=c.selected&&c.click(a),setTimeout(function(){var e=c.trigger({phase:"before",type:"contextMenu",target:a,originalEvent:b,object:d});e.isCancelled!==!0&&(d.group||d.disabled||(c.menu.length>0&&$(c.box).find("#node_"+w2utils.escapeId(a)).w2menu(c.menu,{left:(b?b.offsetX||b.pageX:50)-25,onSelect:function(b){c.menuClick(a,parseInt(b.index),b.originalEvent)}}),c.trigger($.extend(e,{phase:"after"}))))},150)},menuClick:function(a,b,c){var d=this,e=d.trigger({phase:"before",type:"menuClick",target:a,originalEvent:c,menuIndex:b,menuItem:d.menu[b]});e.isCancelled!==!0&&d.trigger($.extend(e,{phase:"after"}))},render:function(a){var b=(new Date).getTime(),c=this.trigger({phase:"before",type:"render",target:this.name,box:a});return c.isCancelled!==!0&&("undefined"!=typeof a&&null!==a&&($(this.box).find("> div > div.w2ui-sidebar-div").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),this.box=a),this.box)?($(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-sidebar").html('
      '),$(this.box).find("> div").css({width:$(this.box).width()+"px",height:$(this.box).height()+"px"}),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),""!==this.topHTML&&($(this.box).find(".w2ui-sidebar-top").html(this.topHTML),$(this.box).find(".w2ui-sidebar-div").css("top",$(this.box).find(".w2ui-sidebar-top").height()+"px")),""!==this.bottomHTML&&($(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),$(this.box).find(".w2ui-sidebar-div").css("bottom",$(this.box).find(".w2ui-sidebar-bottom").height()+"px")),this.trigger($.extend(c,{phase:"after"})),this.refresh(),(new Date).getTime()-b):void 0},refresh:function(a){function b(a){var b="",c=a.img;null===c&&(c=this.img);var d=a.icon;null===d&&(d=this.icon);for(var e=a.parent,f=0;e&&null!==e.parent;)e.group&&f--,e=e.parent,f++;return"undefined"!=typeof a.caption&&(a.text=a.caption),a.group?b='
      "+(a.groupShowHide?""+w2utils.lang(!a.hidden&&a.expanded?"Hide":"Show")+"":"")+" "+a.text+'
      ':(a.selected&&!a.disabled&&(h.selected=a.id),e="",c&&(e='
      '),d&&(e='
      '),b='
      '+(a.nodes.length>0?a.expanded?"-":"+":a.plus?"+":"")+'
      '+e+(a.count||0===a.count?'
      '+a.count+"
      ":"")+'
      '+a.text+'
      '),b}var c=(new Date).getTime(),d=this.trigger({phase:"before",type:"refresh",target:"undefined"!=typeof a?a:this.name});if(d.isCancelled!==!0){""!==this.topHTML&&($(this.box).find(".w2ui-sidebar-top").html(this.topHTML),$(this.box).find(".w2ui-sidebar-div").css("top",$(this.box).find(".w2ui-sidebar-top").height()+"px")),""!==this.bottomHTML&&($(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),$(this.box).find(".w2ui-sidebar-div").css("bottom",$(this.box).find(".w2ui-sidebar-bottom").height()+"px")),$(this.box).find("> div").css({width:$(this.box).width()+"px",height:$(this.box).height()+"px"});var e,f,g,h=this;if("undefined"==typeof a)e=this,g=".w2ui-sidebar-div";else{if(e=this.get(a),null===e)return;g="#node_"+w2utils.escapeId(e.id)+"_sub"}var i;if(e!==this){var j="#node_"+w2utils.escapeId(e.id);i=b(e),$(this.box).find(j).before(''),$(this.box).find(j).remove(),$(this.box).find(g).remove(),$("#sidebar_"+this.name+"_tmp").before(i),$("#sidebar_"+this.name+"_tmp").remove()}$(this.box).find(g).html("");for(var k=0;k div").css({width:$(this.box).width()+"px",height:$(this.box).height()+"px"}),this.trigger($.extend(b,{phase:"after"})),(new Date).getTime()-a):void 0},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});a.isCancelled!==!0&&($(this.box).find("> div > div.w2ui-sidebar-div").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})))},lock:function(){var a=$(this.box).find("> div:first-child"),b=Array.prototype.slice.call(arguments,0);b.unshift(a),w2utils.lock.apply(window,b)},unlock:function(){w2utils.unlock(this.box)}},$.extend(a.prototype,w2utils.event),w2obj.sidebar=a}(),function(a){var b=function(b){this.el=null,this.helpers={},this.type=b.type||"text",this.options=a.extend(!0,{},b),this.onSearch=b.onSearch||null,this.onRequest=b.onRequest||null,this.onLoad=b.onLoad||null,this.onError=b.onError||null,this.onClick=b.onClick||null,this.onAdd=b.onAdd||null,this.onNew=b.onNew||null,this.onRemove=b.onRemove||null,this.onMouseOver=b.onMouseOver||null,this.onMouseOut=b.onMouseOut||null,this.onIconClick=b.onIconClick||null,this.tmp={},delete this.options.type,delete this.options.onSearch,delete this.options.onRequest,delete this.options.onLoad,delete this.options.onError,delete this.options.onClick,delete this.options.onMouseOver,delete this.options.onMouseOut,delete this.options.onIconClick,a.extend(!0,this,w2obj.field)};a.fn.w2field=function(c,d){if(0!=this.length)return"string"==typeof c&&"object"==typeof d&&(c=a.extend(!0,{},d,{type:c})),"string"==typeof c&&"undefined"==typeof d&&(c={type:c}),c.type=String(c.type).toLowerCase(),this.each(function(d,e){var f=a(e).data("w2field");if("undefined"==typeof f){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}if(f.clear(),"clear"!=c.type){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}});var e=b.prototype;return e[c]?e[c].apply(e,Array.prototype.slice.call(arguments,1)):void 0},b.prototype={custom:{},pallete:[["000000","444444","666666","999999","CCCCCC","EEEEEE","F3F3F3","FFFFFF"],["FF011B","FF9838","FFFD59","01FD55","00FFFE","0424F3","9B24F4","FF21F5"],["F4CCCC","FCE5CD","FFF2CC","D9EAD3","D0E0E3","CFE2F3","D9D1E9","EAD1DC"],["EA9899","F9CB9C","FEE599","B6D7A8","A2C4C9","9FC5E8","B4A7D6","D5A6BD"],["E06666","F6B26B","FED966","93C47D","76A5AF","6FA8DC","8E7CC3","C27BA0"],["CC0814","E69138","F1C232","6AA84F","45818E","3D85C6","674EA7","A54D79"],["99050C","B45F17","BF901F","37761D","124F5C","0A5394","351C75","741B47"],["660205","783F0B","7F6011","274E12","0C343D","063762","20124D","4C1030"]],addType:function(a,b){return a=String(a).toLowerCase(),this.custom[a]=b,!0},removeType:function(a){return a=String(a).toLowerCase(),this.custom[a]?(delete this.custom[a],!0):!1},init:function(){var b,c=this,d=this.options;if("function"==typeof this.custom[this.type])return void this.custom[this.type].call(this,d);if(-1==["INPUT","TEXTAREA"].indexOf(this.el.tagName))return void console.log("ERROR: w2field could only be applied to INPUT or TEXTAREA.",this.el);switch(this.type){case"text":case"int":case"float":case"money":case"currency":case"percent":case"alphanumeric":case"hex":b={min:null,max:null,step:1,placeholder:"",autoFormat:!0,currencyPrefix:w2utils.settings.currencyPrefix,currencySuffix:w2utils.settings.currencySuffix,currencyPrecision:w2utils.settings.currencyPrecision,groupSymbol:w2utils.settings.groupSymbol,arrows:!1,keyboard:!0,precision:null,silent:!0,prefix:"",suffix:""},this.options=a.extend(!0,{},b,d),d=this.options,d.numberRE=new RegExp("["+d.groupSymbol+"]","g"),d.moneyRE=new RegExp("["+d.currencyPrefix+d.currencySuffix+d.groupSymbol+"]","g"),d.percentRE=new RegExp("["+d.groupSymbol+"%]","g"),-1!=["text","alphanumeric","hex"].indexOf(this.type)&&(d.arrows=!1,d.keyboard=!1),this.addPrefix(),this.addSuffix(),a(this.el).attr("placeholder",d.placeholder);break;case"color":b={prefix:"#",suffix:'
       
      ',placeholder:"",arrows:!1,keyboard:!1},a.extend(d,b),this.addPrefix(),this.addSuffix(),a(this.el).attr("maxlength",6),""!=a(this.el).val()&&setTimeout(function(){a(c.el).change()},1),a(this.el).attr("placeholder",d.placeholder);break;case"date":b={format:w2utils.settings.date_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:"",blocked:{},colored:{}},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:d.format);break;case"time":b={format:w2utils.settings.time_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:""},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:"h12"==d.format?"hh:mi pm":"hh:mi");break;case"datetime":break;case"list":case"combo":if(b={items:[],selected:{},placeholder:"",url:null,postData:{},minLength:1,cacheMax:250,maxDropHeight:350,match:"begins",silent:!0,icon:null,iconStyle:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onIconClick:null,renderDrop:null,prefix:"",suffix:"",openOnFocus:!1,markSearch:!1},"list"==this.type&&(b.openOnFocus=!0,b.suffix='
      ',a(this.el).addClass("w2ui-select"),!a.isPlainObject(d.selected)))for(var e in d.items){var f=d.items[e];if(f&&f.id==d.selected){d.selected=a.extend(!0,{},f);break}}d=a.extend({},b,d,{align:"both",altRows:!0}),d.items=this.normMenu(d.items),this.options=d,a.isPlainObject(d.selected)||(d.selected={}),a(this.el).data("selected",d.selected),d.url&&this.request(0),d.icon&&(d.prefix=''),"list"==this.type&&this.addFocus(),this.addPrefix(),this.addSuffix(),setTimeout(function(){c.refresh()},10),a(this.el).attr("placeholder",d.placeholder).attr("autocomplete","off"),"undefined"!=typeof d.selected.text&&a(this.el).val(d.selected.text);break;case"enum":b={items:[],selected:[],placeholder:"",max:0,url:null,postData:{},minLength:1,cacheMax:250,maxWidth:250,maxHeight:350,maxDropHeight:350,match:"contains",silent:!0,openOnFocus:!1,markSearch:!0,renderDrop:null,renderItem:null,style:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onClick:null,onAdd:null,onNew:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",suffix:"",altRows:!0}),d.items=this.normMenu(d.items),d.selected=this.normMenu(d.selected),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),d.url&&this.request(0),this.addSuffix(),this.addMulti();break;case"file":b={selected:[],placeholder:w2utils.lang("Attach files by dragging and dropping or Click to Select"),max:0,maxSize:0,maxFileSize:0,maxWidth:250,maxHeight:350,maxDropHeight:350,silent:!0,renderItem:null,style:"",onClick:null,onAdd:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",altRows:!0}),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),this.addMulti()}this.tmp={onChange:function(a){c.change.call(c,a)},onClick:function(a){c.click.call(c,a)},onFocus:function(a){c.focus.call(c,a)},onBlur:function(a){c.blur.call(c,a)},onKeydown:function(a){c.keyDown.call(c,a)},onKeyup:function(a){c.keyUp.call(c,a)},onKeypress:function(a){c.keyPress.call(c,a)}},a(this.el).addClass("w2field").data("w2field",this).on("change",this.tmp.onChange).on("click",this.tmp.onClick).on("focus",this.tmp.onFocus).on("blur",this.tmp.onBlur).on("keydown",this.tmp.onKeydown).on("keyup",this.tmp.onKeyup).on("keypress",this.tmp.onKeypress).css({"box-sizing":"border-box","-webkit-box-sizing":"border-box","-moz-box-sizing":"border-box","-ms-box-sizing":"border-box","-o-box-sizing":"border-box"}),this.change(a.Event("change"))},clear:function(){var b=this.options;-1!=["money","currency"].indexOf(this.type)&&a(this.el).val(a(this.el).val().replace(b.moneyRE,"")),"percent"==this.type&&a(this.el).val(a(this.el).val().replace(/%/g,"")),"color"==this.type&&a(this.el).removeAttr("maxlength"),"list"==this.type&&a(this.el).removeClass("w2ui-select"),this.type="clear";var c=a(this.el).data("tmp");if(this.tmp){"undefined"!=typeof c&&(c&&c["old-padding-left"]&&a(this.el).css("padding-left",c["old-padding-left"]),c&&c["old-padding-right"]&&a(this.el).css("padding-right",c["old-padding-right"])),a(this.el).val(this.clean(a(this.el).val())).removeClass("w2field").removeData().off("change",this.tmp.onChange).off("click",this.tmp.onClick).off("focus",this.tmp.onFocus).off("blur",this.tmp.onBlur).off("keydown",this.tmp.onKeydown).off("keyup",this.tmp.onKeyup).off("keypress",this.tmp.onKeypress);for(var d in this.helpers)a(this.helpers[d]).remove();this.helpers={}}},refresh:function(){var b=this,c=this.options,d=a(this.el).data("selected"),e=(new Date).getTime();if(-1!=["list"].indexOf(this.type)&&(a(b.el).parent().css("white-space","nowrap"),b.helpers.prefix&&b.helpers.prefix.hide(),setTimeout(function(){var c=b.helpers.focus.find("input");""==a(c).val()?(a(c).css("opacity",0).prev().css("opacity",0),a(b.el).val(d&&null!=d.text?d.text:""),a(b.el).attr("placeholder",a(b.el).attr("_placeholder")),a.isEmptyObject(d)?b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide():b.helpers&&b.helpers.prefix&&b.helpers.prefix.show()):(a(c).css("opacity",1).prev().css("opacity",1),b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide(),a(b.el).val(""),a(b.el).attr("_placeholder",a(b.el).attr("placeholder")).removeAttr("placeholder"))},1)),-1!=["enum","file"].indexOf(this.type)){var f="";for(var g in d){var h=d[g],i="";i="function"==typeof c.renderItem?c.renderItem(h,g,'
        
      '):'
        
      '+("enum"==b.type?h.text:h.name+' - '+w2utils.size(h.size)+""),f+='
    • '+i+"
    • " -}var j=b.helpers.multi,k=j.find("ul");if(j.attr("style",j.attr("style")+";"+c.style),a(b.el).attr("readonly")?j.addClass("w2ui-readonly"):j.removeClass("w2ui-readonly"),j.find(".w2ui-enum-placeholder").remove(),k.find("li").not("li.nomouse").remove(),""!=f)k.prepend(f);else if("undefined"!=typeof c.placeholder){var l="padding-top: "+a(this.el).css("padding-top")+";padding-left: "+a(this.el).css("padding-left")+"; box-sizing: "+a(this.el).css("box-sizing")+"; line-height: "+a(this.el).css("line-height")+"; font-size: "+a(this.el).css("font-size")+"; font-family: "+a(this.el).css("font-family")+"; ";j.prepend('
      '+c.placeholder+"
      ")}j.find("li").data("mouse","out").on("click",function(c){var e=d[a(c.target).attr("index")];if(!a(c.target).hasClass("nomouse")){c.stopPropagation();var f=b.trigger({phase:"before",type:"click",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled!==!0){if(a(c.target).hasClass("w2ui-list-remove")){if(a(b.el).attr("readonly"))return;var f=b.trigger({phase:"before",type:"remove",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled===!0)return;a().w2overlay(),d.splice(a(c.target).attr("index"),1),a(b.el).trigger("change"),a(c.target).parent().fadeOut("fast"),setTimeout(function(){b.refresh(),b.trigger(a.extend(f,{phase:"after"}))},300)}if("file"==b.type&&!a(c.target).hasClass("w2ui-list-remove")){var g="";/image/i.test(e.type)&&(g='
      ');var h='style="padding: 3px; text-align: right; color: #777;"',i='style="padding: 3px"';g+='
      Name:"+e.name+"
      Size:"+w2utils.size(e.size)+"
      Type: '+e.type+"
      Modified:"+w2utils.date(e.modified)+"
      ",a(c.target).w2overlay(g)}b.trigger(a.extend(f,{phase:"after"}))}}}).on("mouseover",function(c){var e=c.target;if("LI"!=e.tagName&&(e=e.parentNode),!a(e).hasClass("nomouse")){if("out"==a(e).data("mouse")){var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"mouseOver",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}a(e).data("mouse","over")}}).on("mouseout",function(c){var e=c.target;"LI"!=e.tagName&&(e=e.parentNode),a(e).hasClass("nomouse")||(a(e).data("mouse","leaving"),setTimeout(function(){if("leaving"==a(e).data("mouse")){a(e).data("mouse","out");var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"f",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}},0))}),a(this.el).height("auto");var m=a(j).find("> div").height()+2*w2utils.getSize(j,"+height");26>m&&(m=26),m>c.maxHeight&&(m=c.maxHeight),j.length>0&&(j[0].scrollTop=1e3);var n=w2utils.getSize(a(this.el),"height")-2;n>m&&(m=n),a(j).css({height:m+"px",overflow:m==c.maxHeight?"auto":"hidden"}),mc.max&&(b=c.max,a(this.el).val(c.max))),b=""!==b&&w2utils.isFloat(b)?Number(b):""),b},format:function(a){var b=this.options;if(b.autoFormat&&""!=a)switch(this.type){case"money":case"currency":a=w2utils.formatNumber(Number(a).toFixed(b.currencyPrecision),b.groupSymbol),""!=a&&(a=b.currencyPrefix+a+b.currencySuffix);break;case"percent":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol),""!=a&&(a+="%");break;case"float":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol);break;case"int":a=w2utils.formatNumber(a,b.groupSymbol)}return a},change:function(b){{var c=this;c.options}if(-1!=["int","float","money","currency","percent"].indexOf(this.type)){var d=a(this.el).val(),e=this.format(this.clean(a(this.el).val()));if(""!=d&&d!=e)return a(this.el).val(e).change(),b.stopPropagation(),b.preventDefault(),!1}if("color"==this.type){var f="#"+a(this.el).val();6!=a(this.el).val().length&&3!=a(this.el).val().length&&(f=""),a(this.el).next().find("div").css("background-color",f),a(c.el).is(":focus")&&this.updateOverlay()}},click:function(b){b.stopPropagation(),-1!=["list","combo","enum"].indexOf(this.type)&&(a(this.el).is(":focus")||this.focus(b)),-1!=["date","time","color"].indexOf(this.type)&&this.updateOverlay()},focus:function(){{var b=this;this.options}if(-1!==["color","date","time"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){b.updateOverlay()},150)}if(-1!=["list","combo","enum"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){return"list"==b.type&&a(b.el).is(":focus")?void a(b.helpers.focus).find("input").focus():(b.search(),void setTimeout(function(){b.updateOverlay()},1))},1)}"file"==b.type&&a(b.helpers.multi).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"})},blur:function(){var b=this,c=b.options,d=a(b.el).val().trim();-1!=["color","date","time","list","combo","enum"].indexOf(b.type)&&a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),-1!=["int","float","money","currency","percent"].indexOf(b.type)&&(""===d||b.checkType(d)||(a(b.el).val("").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid number"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),-1!=["date","time"].indexOf(b.type)&&(w2utils.isInt(b.el.value)&&a(b.el).val(w2utils.formatDate(new Date(parseInt(b.el.value)),c.format)).change(),""===d||b.inRange(b.el.value)?("date"!=b.type||""===d||w2utils.isDate(b.el.value,c.format)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid date"),setTimeout(function(){a(b.el).w2tag("")},3e3))),"time"!=b.type||""===d||w2utils.isTime(b.el.value)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid time"),setTimeout(function(){a(b.el).w2tag("")},3e3)))):(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not in range"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),"enum"==b.type&&a(b.helpers.multi).find("input").val("").width(20),"file"==b.type&&a(b.helpers.multi).css({outline:"none"})},keyPress:function(a){{var b=this;b.options}if(-1!=["int","float","money","currency","percent","hex","color","alphanumeric"].indexOf(b.type)){if(a.metaKey||a.ctrlKey||a.altKey||a.charCode!=a.keyCode&&a.keyCode>0)return;var c=String.fromCharCode(a.charCode);if(!b.checkType(c,!0)&&13!=a.keyCode)return a.preventDefault(),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,!1}-1!=["date","time"].indexOf(b.type)&&setTimeout(function(){b.updateOverlay()},1)},keyDown:function(b,c){var d=this,e=d.options,f=b.keyCode||c&&c.keyCode;if(-1!=["int","float","money","currency","percent"].indexOf(d.type)){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,h=parseFloat(a(d.el).val().replace(e.moneyRE,""))||0,i=e.step;switch((b.ctrlKey||b.metaKey)&&(i=10),f){case 38:if(b.shiftKey)break;a(d.el).val(h+i<=e.max||null===e.max?Number((h+i).toFixed(12)):e.max).change(),g=!0;break;case 40:if(b.shiftKey)break;a(d.el).val(h-i>=e.min||null===e.min?Number((h-i).toFixed(12)):e.min).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("date"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,j=864e5,i=1;(b.ctrlKey||b.metaKey)&&(i=10),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatDate(new Date(parseInt(d.el.value)),e.format)).change();var k=w2utils.isDate(a(d.el).val(),e.format,!0);switch(k||(k=new Date,j=0),f){case 38:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()+j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()+1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0;break;case 40:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()-j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()-1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length),d.updateOverlay()},0))}if("time"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,i=1;(b.ctrlKey||b.metaKey)&&(i=60),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatTime(new Date(parseInt(d.el.value)),e.format)).change();var h=a(d.el).val(),m=d.toMin(h)||d.toMin((new Date).getHours()+":"+((new Date).getMinutes()-1));switch(f){case 38:if(b.shiftKey)break;m+=i,g=!0;break;case 40:if(b.shiftKey)break;m-=i,g=!0}g&&(a(d.el).val(d.fromMin(m)).change(),b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("color"==d.type){if(a(d.el).attr("readonly"))return;if(86==b.keyCode&&(b.ctrlKey||b.metaKey)&&(a(d.el).prop("maxlength",7),setTimeout(function(){var b=a(d).val();"#"==b.substr(0,1)&&(b=b.substr(1)),w2utils.isHex(b)||(b=""),a(d).val(b).prop("maxlength",6).change()},20)),(b.ctrlKey||b.metaKey)&&!b.shiftKey){if("undefined"==typeof d.tmp.cind1)d.tmp.cind1=-1,d.tmp.cind2=-1;else{switch(f){case 38:d.tmp.cind1--;break;case 40:d.tmp.cind1++;break;case 39:d.tmp.cind2++;break;case 37:d.tmp.cind2--}d.tmp.cind1<0&&(d.tmp.cind1=0),d.tmp.cind1>this.pallete.length-1&&(d.tmp.cind1=this.pallete.length-1),d.tmp.cind2<0&&(d.tmp.cind2=0),d.tmp.cind2>this.pallete[0].length-1&&(d.tmp.cind2=this.pallete[0].length-1)}-1!=[37,38,39,40].indexOf(f)&&(a(d.el).val(this.pallete[d.tmp.cind1][d.tmp.cind2]).change(),b.preventDefault())}}if(-1!=["list","combo","enum"].indexOf(d.type)){if(a(d.el).attr("readonly"))return;var g=!1,n=a(d.el).data("selected"),o=a(d.helpers.focus).find("input");switch("list"==d.type&&-1==[37,38,39,40].indexOf(f)&&d.refresh(),f){case 27:"list"==d.type&&(""==a(o).val()?a(d.el).data("selected",{}):a(o).val(""),d.refresh(),b.stopPropagation());break;case 37:case 39:break;case 13:if(0==a("#w2ui-overlay").length)break;var p=e.items[e.index],q=a(d.helpers.multi).find("input");if("enum"==d.type)if(null!=p){var r=d.trigger({phase:"before",type:"add",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,n.length>=e.max&&e.max>0&&n.pop(),delete p.hidden,delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}else{p={id:q.val(),text:q.val()};var r=d.trigger({phase:"before",type:"new",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,"function"==typeof d.onNew&&(n.length>=e.max&&e.max>0&&n.pop(),delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh()),d.trigger(a.extend(r,{phase:"after"}))}else p&&a(d.el).data("selected",p).val(p.text).change(),""==a(d.el).val()&&a(d.el).data("selected")&&a(d.el).removeData("selected").val("").change(),"list"==d.type&&(o.val(""),d.refresh()),d.tmp.force_hide=!0;break;case 8:if(-1!=["enum"].indexOf(d.type)&&""==a(d.helpers.multi).find("input").val()&&n.length>0){var p=n[n.length-1],r=d.trigger({phase:"before",type:"remove",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;n.pop(),a(d.el).trigger("change"),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}break;case 38:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):0,e.index--;e.index>0&&e.items[e.index].hidden;)e.index--;if(0==e.index&&e.items[e.index].hidden)for(;e.items[e.index]&&e.items[e.index].hidden;)e.index++;g=!0;break;case 40:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):-1,e.index++;e.index=e.items.length&&(e.index=e.items.length-1),d.updateOverlay(),b.preventDefault(),void setTimeout(function(){if("enum"==d.type){var a=d.helpers.multi.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else if("list"==d.type){var a=d.helpers.focus.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0);if("enum"==d.type){var s=d.helpers.multi.find("input"),t=s.val();s.width(8*(t.length+2)+"px")}-1==[16,17,18,20,37,39,91].indexOf(f)&&setTimeout(function(){d.tmp.force_hide||d.request(),d.search()},1)}},keyUp:function(b){"color"==this.type&&86==b.keyCode&&(b.ctrlKey||b.metaKey)&&a(this).prop("maxlength",6)},clearCache:function(){var a=this.options;a.items=[],this.tmp.xhr_loading=!1,this.tmp.xhr_search="",this.tmp.xhr_total=-1,this.search()},request:function(b){var c=this,d=this.options,e=a(c.el).val()||"";if(d.url){if("enum"==c.type){var f=a(c.helpers.multi).find("input");e=0==f.length?"":f.val()}if("list"==c.type){var f=a(c.helpers.focus).find("input");e=0==f.length?"":f.val()}if(0!=d.minLength&&e.lengthc.tmp.xhr_search.length||e.length>=c.tmp.xhr_search.length&&e.substr(0,c.tmp.xhr_search.length)!=c.tmp.xhr_search||e.lengthd.cacheMax&&b.items.splice(d.cacheMax,1e5),c.tmp.xhr_loading=!1,c.tmp.xhr_search=e,c.tmp.xhr_total=b.items.length,d.items=b.items,c.tmp.emptySet=""==e&&0==b.items.length?!0:!1,c.search(),c.trigger(a.extend(i,{phase:"after"}))}}).error(function(b,d,f){var g={status:d,exceptionThrown:f,rawResponseText:b.responseText},h=c.trigger({phase:"before",type:"error",target:c.el,search:e,error:g,xhr:b});h.isCancelled!==!0&&(console.log("ERROR: server communication failed. The server should return",{status:"success",items:[{id:1,text:"item"}]},", instead the AJAX request produced this: ",g),c.clearCache(),c.trigger(a.extend(h,{phase:"after"})))}),c.trigger(a.extend(g,{phase:"after"})))},b))}},search:function(){var b=this,c=this.options,d=a(b.el).val(),e=b.el,f=[],g=a(b.el).data("selected");if("enum"==b.type){e=a(b.helpers.multi).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}if("list"==b.type){e=a(b.helpers.focus).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}var i=b.trigger({phase:"before",type:"search",target:e,search:d});if(i.isCancelled!==!0){if(b.tmp.xhr_loading!==!0){var j=0;for(var k in c.items){var l=c.items[k],m="",n="";-1!=["is","begins"].indexOf(c.match)&&(m="^"),-1!=["is","ends"].indexOf(c.match)&&(n="$");try{var o=new RegExp(m+d+n,"i");l.hidden=o.test(l.text)||"..."==l.text?!1:!0}catch(p){}"enum"==b.type&&-1!=a.inArray(l.id,f)&&(l.hidden=!0),l.hidden!==!0&&j++}if("combo"!=b.type)for(c.index=0;c.items[c.index]&&c.items[c.index].hidden;)c.index++;else c.index=-1;0>=j&&(c.index=-1),c.spinner=!1,b.updateOverlay(),setTimeout(function(){var b=a("#w2ui-overlay").html()||"";c.markSearch&&-1!=b.indexOf("$.fn.w2menuHandler")&&a("#w2ui-overlay").w2marker(d)},1)}else c.items.splice(0,c.cacheMax),c.spinner=!0,b.updateOverlay();b.trigger(a.extend(i,{phase:"after"}))}},updateOverlay:function(){var b=this,c=this.options;if("color"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length?a(b.el).w2overlay(b.getColorHTML()):a("#w2ui-overlay").html(b.getColorHTML()),a("#w2ui-overlay .color").on("mousedown",function(c){var d=a(c.originalEvent.target).attr("name"),e=a(c.originalEvent.target).attr("index").split(":");b.tmp.cind1=e[0],b.tmp.cind2=e[1],a(b.el).val(d).change(),a(this).html("•")}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}if("date"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
      ',{css:{"background-color":"#f5f5f5"}});var d,e,f=w2utils.isDate(a(b.el).val(),b.options.format,!0);f&&(d=f.getMonth()+1,e=f.getFullYear()),function k(c,d){a("#w2ui-overlay > div > div").html(b.getMonthHTML(c,d)),a("#w2ui-overlay .w2ui-calendar-title").on("mousedown",function(){if(a(this).next().hasClass("w2ui-calendar-jump"))a(this).next().remove();else{var c,d;a(this).after('
      '),a(this).next().hide().html(b.getYearHTML()).fadeIn(200),setTimeout(function(){a("#w2ui-overlay .w2ui-calendar-jump").find(".w2ui-jump-month, .w2ui-jump-year").on("click",function(){a(this).hasClass("w2ui-jump-month")&&(a(this).parent().find(".w2ui-jump-month").removeClass("selected"),a(this).addClass("selected"),d=a(this).attr("name")),a(this).hasClass("w2ui-jump-year")&&(a(this).parent().find(".w2ui-jump-year").removeClass("selected"),a(this).addClass("selected"),c=a(this).attr("name")),null!=c&&null!=d&&(a("#w2ui-overlay .w2ui-calendar-jump").fadeOut(100),setTimeout(function(){k(parseInt(d)+1,c)},100))}),a("#w2ui-overlay .w2ui-calendar-jump >:last-child").prop("scrollTop",2e3)},1)}}),a("#w2ui-overlay .w2ui-date").on("mousedown",function(){var c=a(this).attr("date");a(b.el).val(c).change(),a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"})}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)}),a("#w2ui-overlay .previous").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])-1,k(a[0],a[1])}),a("#w2ui-overlay .next").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])+1,k(a[0],a[1])})}(d,e)}if("time"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
      ',{css:{"background-color":"#fff"}});var g="h24"==this.options.format?!0:!1;a("#w2ui-overlay > div").html(b.getHourHTML()),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var c=a(this).attr("hour");a(b.el).val((c>12&&!g?c-12:c)+":00"+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){var c=a(this).attr("hour");a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),a(b.el).w2overlay('
      ',{css:{"background-color":"#fff"}}),a("#w2ui-overlay > div").html(b.getMinHTML(c)),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var d=a(this).attr("min");a(b.el).val((c>12&&!g?c-12:c)+":"+(10>d?0:"")+d+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})})}if(-1!=["list","combo","enum"].indexOf(this.type)){var h=this.el,i=this.el;if("enum"==this.type&&(h=a(this.helpers.multi),i=a(h).find("input")),"list"==this.type&&(i=a(this.helpers.focus).find("input")),a(i).is(":focus")){if(c.openOnFocus===!1&&""==a(i).val()&&b.tmp.force_open!==!0)return void a().w2overlay();if(b.tmp.force_hide)return a().w2overlay(),void setTimeout(function(){delete b.tmp.force_hide},1);""!=a(i).val()&&delete b.tmp.force_open,0==a("#w2ui-overlay").length&&(c.index=0);var j=w2utils.lang("No matches");null!=c.url&&a(i).val().length=c.max&&c.max>0&&e.pop(),delete d.item.hidden,e.push(d.item),a(b.el).data("selected",e).change(),a(b.helpers.multi).find("input").val("").width(20),b.refresh(),a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),b.trigger(a.extend(f,{phase:"after"}))}}else a(b.el).data("selected",d.item).val(d.item.text).change(),b.helpers.focus&&(b.helpers.focus.find("input").val(""),b.refresh())}}))}}},inRange:function(b){var c=!1;if("date"==this.type){var d=w2utils.isDate(b,this.options.format,!0);if(d){if(this.options.start||this.options.end){var e="string"==typeof this.options.start?this.options.start:a(this.options.start).val(),f="string"==typeof this.options.end?this.options.end:a(this.options.end).val(),g=w2utils.isDate(e,this.options.format,!0),h=w2utils.isDate(f,this.options.format,!0),i=new Date(d);g||(g=i),h||(h=i),i>=g&&h>=i&&(c=!0)}else c=!0;this.options.blocked&&-1!=a.inArray(b,this.options.blocked)&&(c=!1)}}if("time"==this.type)if(this.options.start||this.options.end){var j=this.toMin(b),k=this.toMin(this.options.start),l=this.toMin(this.options.end);k||(k=j),l||(l=j),j>=k&&l>=j&&(c=!0)}else c=!0;return c},checkType:function(a,b){var c=this;switch(c.type){case"int":return b&&-1!=["-"].indexOf(a)?!0:w2utils.isInt(a.replace(c.options.numberRE,""));case"percent":a=a.replace(/%/g,"");case"float":return b&&-1!=["-","."].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.numberRE,""));case"money":case"currency":return b&&-1!=["-",".",c.options.groupSymbol,c.options.currencyPrefix,c.options.currencySuffix].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.moneyRE,""));case"hex":case"color":return w2utils.isHex(a);case"alphanumeric":return w2utils.isAlphaNumeric(a)}return!0},addPrefix:function(){var b=this;setTimeout(function(){if("clear"!==b.type){var c,d=a(b.el).data("tmp")||{};d["old-padding-left"]&&a(b.el).css("padding-left",d["old-padding-left"]),d["old-padding-left"]=a(b.el).css("padding-left"),a(b.el).data("tmp",d),""!==b.options.prefix&&(b.helpers.prefix&&a(b.helpers.prefix).remove(),a(b.el).before('
      '+b.options.prefix+"
      "),c=a(b.el).prev(),c.css({color:a(b.el).css("color"),"font-family":a(b.el).css("font-family"),"font-size":a(b.el).css("font-size"),"padding-top":a(b.el).css("padding-top"),"padding-bottom":a(b.el).css("padding-bottom"),"padding-left":a(b.el).css("padding-left"),"padding-right":0,"margin-top":parseInt(a(b.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(b.el).css("margin-bottom"),10)+1+"px","margin-left":a(b.el).css("margin-left"),"margin-right":0}).on("click",function(){if(b.options.icon&&"function"==typeof b.onIconClick){var c=b.trigger({phase:"before",type:"iconClick",target:b.el,el:a(this).find("span.w2ui-icon")[0]});if(c.isCancelled===!0)return;b.trigger(a.extend(c,{phase:"after"}))}else"list"==b.type?a(b.helpers.focus).find("input").focus():a(b.el).focus()}),a(b.el).css("padding-left",c.width()+parseInt(a(b.el).css("padding-left"),10)+"px"),b.helpers.prefix=c)}},1)},addSuffix:function(){var b,c,d=this;setTimeout(function(){if("clear"!==d.type){var e=a(d.el).data("tmp")||{};if(e["old-padding-right"]&&a(d.el).css("padding-right",e["old-padding-right"]),e["old-padding-right"]=a(d.el).css("padding-right"),a(d.el).data("tmp",e),c=parseInt(a(d.el).css("padding-right"),10),d.options.arrows){d.helpers.arrows&&a(d.helpers.arrows).remove(),a(d.el).after('
       
      ');{w2utils.getSize(d.el,"height")}b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),height:a(d.el).height()+parseInt(a(d.el).css("padding-top"),10)+parseInt(a(d.el).css("padding-bottom"),10)+"px",padding:0,"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":0,"border-left":"1px solid silver"}).css("margin-left","-"+(b.width()+parseInt(a(d.el).css("margin-right"),10)+12)+"px").on("mousedown",function(b){function c(){clearTimeout(a("body").data("_field_update_timer")),a("body").off("mouseup",c)}function e(c){a(d.el).focus(),d.keyDown(a.Event("keydown"),{keyCode:"up"==a(b.target).attr("type")?38:40}),c!==!1&&a("body").data("_field_update_timer",setTimeout(e,60))}a("body").on("mouseup",c),a("body").data("_field_update_timer",setTimeout(e,700)),e(!1)}),c+=b.width()+12,a(d.el).css("padding-right",c+"px"),d.helpers.arrows=b}""!==d.options.suffix&&(d.helpers.suffix&&a(d.helpers.suffix).remove(),a(d.el).after('
      '+d.options.suffix+"
      "),b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),"padding-top":a(d.el).css("padding-top"),"padding-bottom":a(d.el).css("padding-bottom"),"padding-left":"3px","padding-right":a(d.el).css("padding-right"),"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(d.el).css("margin-bottom"),10)+1+"px"}).on("click",function(){"list"==d.type?a(d.helpers.focus).find("input").focus():a(d.el).focus()}),b.css("margin-left","-"+(w2utils.getSize(b,"width")+parseInt(a(d.el).css("margin-right"),10)+2)+"px"),c+=b.width()+3,a(d.el).css("padding-right",c+"px"),d.helpers.suffix=b)}},1)},addFocus:function(){var b=this,c=this.options,d=0;c.icon&&(d=11),a(b.helpers.focus).remove();var e='
      ';a(b.el).attr("tabindex",-1).before(e);var f=a(b.el).prev();b.helpers.focus=f,f.css({width:a(b.el).width(),"margin-top":a(b.el).css("margin-top"),"margin-left":parseInt(a(b.el).css("margin-left"))+parseInt(a(b.el).css("padding-left"))+"px","margin-bottom":a(b.el).css("margin-bottom"),"margin-right":a(b.el).css("margin-right")}).find("input").css({cursor:"default",width:"100%",outline:"none",opacity:1,margin:0,border:"1px solid transparent",padding:a(b.el).css("padding-top"),"padding-left":0,"margin-left":d+(d>0?6:0),"background-color":"transparent"}),f.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),c.stopPropagation()}).on("focus",function(c){a(b.el).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(this).val(""),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(b.el).css("outline","none"),a(this).val(""),b.refresh(),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){b.keyPress(a)}),f.on("click",function(){a(this).find("input").focus()}),b.refresh()},addMulti:function(){{var b=this;this.options}a(b.helpers.multi).remove();var c="",d="margin-top : 0px; margin-bottom : 0px; margin-left : "+a(b.el).css("margin-left")+"; margin-right : "+a(b.el).css("margin-right")+"; width : "+(w2utils.getSize(b.el,"width")-parseInt(a(b.el).css("margin-left"),10)-parseInt(a(b.el).css("margin-right"),10))+"px;";"enum"==b.type&&(c='
      • "),"file"==b.type&&(c='
        '),a(b.el).before(c).css({"background-color":"transparent","border-color":"transparent"});var e=a(b.el).prev();b.helpers.multi=e,"enum"==b.type&&(a(b.el).attr("tabindex",-1),e.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),a(b.el).triggerHandler("click")}).on("focus",function(c){a(e).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(e).css("outline","none"),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){e.find(".w2ui-enum-placeholder").remove(),b.keyPress(a)}),e.on("click",function(){a(this).find("input").focus()})),"file"==b.type&&(a(b.el).css("outline","none"),e.on("click",function(c){a(b.el).focus(),a(b.el).attr("readonly")||(b.blur(c),e.find("input").click())}).on("dragenter",function(){a(b.el).attr("readonly")||a(e).addClass("w2ui-file-dragover")}).on("dragleave",function(c){if(!a(b.el).attr("readonly")){var d=a(c.target).parents(".w2ui-field-helper");0==d.length&&a(e).removeClass("w2ui-file-dragover")}}).on("drop",function(c){if(!a(b.el).attr("readonly")){a(e).removeClass("w2ui-file-dragover");for(var d=c.originalEvent.dataTransfer.files,f=0,g=d.length;g>f;f++)b.addFile.call(b,d[f]);c.preventDefault(),c.stopPropagation()}}).on("dragover",function(a){a.preventDefault(),a.stopPropagation()}),e.find("input").on("click",function(a){a.stopPropagation()}).on("change",function(){if("undefined"!=typeof this.files)for(var a=0,c=this.files.length;c>a;a++)b.addFile.call(b,this.files[a])})),b.refresh()},addFile:function(b){var c,d=this,e=this.options,f=a(d.el).data("selected"),g={name:b.name,type:b.type,modified:b.lastModifiedDate,size:b.size,content:null},h=0,i=0;for(var j in f)h+=f[j].size,i++;var k=d.trigger({phase:"before",type:"add",target:d.el,file:g,total:i,totalSize:h});if(k.isCancelled!==!0){if(0!==e.maxFileSize&&g.size>e.maxFileSize)return c="Maximum file size is "+w2utils.size(e.maxFileSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.maxSize&&h+g.size>e.maxSize)return c="Maximum total size is "+w2utils.size(e.maxSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c); -if(0!==e.max&&i>=e.max)return c="Maximum number of files is "+e.max,e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(f.push(g),"undefined"!=typeof FileReader){var l=new FileReader;l.onload=function(){return function(b){var c=b.target.result,e=c.indexOf(",");g.content=c.substr(e+1),d.refresh(),a(d.el).trigger("change"),d.trigger(a.extend(k,{phase:"after"}))}}(),l.readAsDataURL(b)}else d.refresh(),a(d.el).trigger("change")}},normMenu:function(b){if(a.isArray(b)){for(var c=0;cc;c++){b+="";for(var d=0;8>d;d++)b+='
        '+(a(this.el).val()==this.pallete[c][d]?"•":" ")+"
        ";b+="",2>c&&(b+='')}return b+="
        "},getMonthHTML:function(a,b){var c=new Date,d=w2utils.settings.fullmonths,e=(w2utils.settings.fulldays,["31","28","31","30","31","30","31","31","30","31","30","31"]),f=c.getFullYear()+"/"+(Number(c.getMonth())+1)+"/"+c.getDate();b=w2utils.isInt(b)?parseInt(b):c.getFullYear(),a=w2utils.isInt(a)?parseInt(a):c.getMonth()+1,a>12&&(a-=12,b++),(1>a||0===a)&&(a+=12,b--),e[1]=b/4==Math.floor(b/4)?"29":"28",this.options.current=a+"/"+b,c=new Date(b,a-1,1);for(var g=c.getDay(),h=w2utils.settings.shortdays,i="",j=0,k=h.length;k>j;j++)i+=""+h[j]+"";for(var l='
        '+d[a-1]+", "+b+'
        '+i+"",m=1,n=1;43>n;n++){if(0===g&&1==n){for(var o=0;6>o;o++)l+='';n+=6}else if(g>n||m>e[a-1]){l+='',n%7===0&&(l+="");continue}var p=b+"/"+a+"/"+m,q="";n%7==6&&(q=" w2ui-saturday"),n%7===0&&(q=" w2ui-sunday"),p==f&&(q+=" w2ui-today");var r=m,s="",t="",u=w2utils.formatDate(p,this.options.format);this.options.colored&&void 0!==this.options.colored[u]&&(tmp=this.options.colored[u].split(":"),t="background-color: "+tmp[0]+";",s="color: "+tmp[1]+";"),l+='",(n%7===0||0===g&&1==n)&&(l+=""),m++}return l+="
          
        '+r+"
        "},getYearHTML:function(){var a=w2utils.settings.shortmonths,b="",c="";for(var d in a)b+='
        '+a[d]+"
        ";for(var e=1950;2020>=e;e++)c+='
        '+e+"
        ";return"
        "+b+"
        "+c+"
        "},getHourHTML:function(){for(var a=[],b="h24"==this.options.format?!0:!1,c=0;24>c;c++){var d=(c>=12&&!b?c-12:c)+":00"+(b?"":12>c?" am":" pm");12!=c||b||(d="12:00 pm"),a[Math.floor(c/8)]||(a[Math.floor(c/8)]="");var e=this.fromMin(this.toMin(d)),f=this.fromMin(this.toMin(d)+59);a[Math.floor(c/8)]+='
        '+d+"
        "}var g='
        '+a[0]+" "+a[1]+" "+a[2]+"
        ";return g},getMinHTML:function(a){"undefined"==typeof a&&(a=0);for(var b="h24"==this.options.format?!0:!1,c=[],d=0;60>d;d+=5){var e=(a>12&&!b?a-12:a)+":"+(10>d?0:"")+d+" "+(b?"":12>a?"am":"pm"),f=20>d?0:40>d?1:2;c[f]||(c[f]=""),c[f]+='
        '+e+"
        "}var g='
        '+c[0]+" "+c[1]+" "+c[2]+"
        ";return g},toMin:function(a){if("string"!=typeof a)return null;var b=a.split(":");return 2!=b.length?null:(b[0]=parseInt(b[0]),b[1]=parseInt(b[1]),-1!=a.indexOf("pm")&&12!=b[0]&&(b[0]+=12),60*b[0]+b[1])},fromMin:function(a){var b="";a>=1440&&(a%=1440),0>a&&(a=1440+a);var c=Math.floor(a/60),d=(10>a%60?"0":"")+a%60;return b=-1!=this.options.format.indexOf("h24")?c+":"+d:(12>=c?c:c-12)+":"+d+" "+(c>=12?"pm":"am")}},a.extend(b.prototype,w2utils.event),w2obj.field=b}(jQuery),function(){var w2form=function(a){this.name=null,this.header="",this.box=null,this.url="",this.formURL="",this.formHTML="",this.page=0,this.recid=0,this.fields=[],this.actions={},this.record={},this.original={},this.postData={},this.toolbar={},this.tabs={},this.style="",this.focus=0,this.msgNotJSON=w2utils.lang("Return data is not in JSON format."),this.msgAJAXerror=w2utils.lang("AJAX error. See console for more details."),this.msgRefresh=w2utils.lang("Refreshing..."),this.msgSaving=w2utils.lang("Saving..."),this.onRequest=null,this.onLoad=null,this.onValidate=null,this.onSubmit=null,this.onSave=null,this.onChange=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,this.onAction=null,this.onToolbar=null,this.onError=null,this.isGenerated=!1,this.last={xhr:null},$.extend(!0,this,w2obj.form,a)};$.fn.w2form=function(a){if("object"==typeof a||!a){var b=this;if(!w2utils.checkName(a,"w2form"))return;var c=a.record,d=a.original,e=a.fields,f=a.toolbar,g=a.tabs,h=new w2form(a);if($.extend(h,{record:{},original:{},fields:[],tabs:{},toolbar:{},handlers:[]}),$.isArray(g)){$.extend(!0,h.tabs,{tabs:[]});for(var i in g){var j=g[i];h.tabs.tabs.push("object"==typeof j?j:{id:j,caption:j})}}else $.extend(!0,h.tabs,g);$.extend(!0,h.toolbar,f);for(var k in e)h.fields[k]=$.extend(!0,{},e[k]);for(var k in c)h.record[k]=$.isPlainObject(c[k])?$.extend(!0,{},c[k]):c[k];for(var k in d)h.original[k]=$.isPlainObject(d[k])?$.extend(!0,{},d[k]):d[k];return b.length>0&&(h.box=b[0]),""!=h.formURL?$.get(h.formURL,function(a){h.formHTML=a,h.isGenerated=!0,(0!=$(h.box).length||0!=a.length)&&($(h.box).html(a),h.render(h.box))}):""!=h.formHTML||(h.formHTML=0!=$(this).length&&""!=$.trim($(this).html())?$(this).html():h.generateHTML()),w2ui[h.name]=h,""==h.formURL&&(-1==String(h.formHTML).indexOf("w2ui-page")&&(h.formHTML='
        '+h.formHTML+"
        "),$(h.box).html(h.formHTML),h.isGenerated=!0,h.render(h.box)),h}if(w2ui[$(this).attr("name")]){var b=w2ui[$(this).attr("name")];return b[a].apply(b,Array.prototype.slice.call(arguments,1)),this}console.log("ERROR: Method "+a+" does not exist on jQuery.w2form")},w2form.prototype={get:function(a,b){if(0===arguments.length){var c=[];for(var d in this.fields)null!=this.fields[d].name&&c.push(this.fields[d].name);return c}for(var e in this.fields)if(this.fields[e].name==a)return b===!0?e:this.fields[e];return null},set:function(a,b){for(var c in this.fields)if(this.fields[c].name==a)return $.extend(this.fields[c],b),this.refresh(),!0;return!1},reload:function(a){var b="object"!=typeof this.url?this.url:this.url.get;b&&0!=this.recid?this.request(a):(this.refresh(),"function"==typeof a&&a())},clear:function(){this.recid=0,this.record={},$().w2tag(),this.refresh()},error:function(a){var b=this.trigger({target:this.name,type:"error",message:a,xhr:this.last.xhr});return b.isCancelled===!0?void("function"==typeof callBack&&callBack()):(setTimeout(function(){w2alert(a,"Error")},1),void this.trigger($.extend(b,{phase:"after"})))},validate:function(a){"undefined"==typeof a&&(a=!0),$().w2tag();var b=[];for(var c in this.fields){var d=this.fields[c];switch(null==this.record[d.name]&&(this.record[d.name]=""),d.type){case"int":this.record[d.name]&&!w2utils.isInt(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not an integer")});break;case"float":this.record[d.name]&&!w2utils.isFloat(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not a float")});break;case"money":this.record[d.name]&&!w2utils.isMoney(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not in money format")});break;case"color":case"hex":this.record[d.name]&&!w2utils.isHex(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not a hex number")});break;case"email":this.record[d.name]&&!w2utils.isEmail(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not a valid email")});break;case"checkbox":this.record[d.name]=1==this.record[d.name]?1:0;break;case"date":this.record[d.name]&&!w2utils.isDate(this.record[d.name],d.options.format)&&b.push({field:d,error:w2utils.lang("Not a valid date")+": "+d.options.format});break;case"list":case"combo":break;case"enum":}var e=this.record[d.name];d.required&&(""===e||$.isArray(e)&&0==e.length)&&b.push({field:d,error:w2utils.lang("Required field")}),d.equalto&&this.record[d.name]!=this.record[d.equalto]&&b.push({field:d,error:w2utils.lang("Field should be equal to ")+d.equalto})}var f=this.trigger({phase:"before",target:this.name,type:"validate",errors:b});if(f.isCancelled!==!0){if(a)for(var g in f.errors){var h=f.errors[g];"radio"==h.field.type?$($(h.field.el).parents("div")[0]).w2tag(h.error,{"class":"w2ui-error"}):-1!=["enum","file"].indexOf(h.field.type)?!function(a){setTimeout(function(){var b=$(a.field.el).data("w2field").helpers.multi;$(a.field.el).w2tag(a.error),$(b).addClass("w2ui-error")},1)}(h):$(h.field.el).w2tag(h.error,{"class":"w2ui-error"})}return this.trigger($.extend(f,{phase:"after"})),b}},getChanges:function(){var a=function(b,c,d){for(var e in b)"object"==typeof b[e]?(d[e]=a(b[e],c[e]||{},{}),(!d[e]||$.isEmptyObject(d[e]))&&delete d[e]):b[e]!=c[e]&&(d[e]=b[e]);return d};return a(this.record,this.original,{})},request:function(postData,callBack){var obj=this;if("function"==typeof postData&&(callBack=postData,postData=null),("undefined"==typeof postData||null==postData)&&(postData={}),this.url&&("object"!=typeof this.url||this.url.get)){(null==this.recid||"undefined"==typeof this.recid)&&(this.recid=0);var params={};params.cmd="get-record",params.name=this.name,params.recid=this.recid,$.extend(params,this.postData),$.extend(params,postData);var eventData=this.trigger({phase:"before",type:"request",target:this.name,url:this.url,postData:params});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Request aborted."}));this.record={},this.original={},this.lock(this.msgRefresh);var url=eventData.url;if("object"==typeof eventData.url&&eventData.url.get&&(url=eventData.url.get),this.last.xhr)try{this.last.xhr.abort()}catch(e){}this.last.xhr=$.ajax({type:"GET",url:url,data:String($.param(eventData.postData,!1)).replace(/%5B/g,"[").replace(/%5D/g,"]"),dataType:"text",complete:function(xhr,status){obj.unlock();var eventData=obj.trigger({phase:"before",target:obj.name,type:"load",xhr:xhr,status:status});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Request aborted."}));var data,responseText=obj.last.xhr.responseText;if("error"!=status){if("undefined"!=typeof responseText&&""!=responseText){if("object"==typeof responseText)data=responseText;else try{eval("data = "+responseText)}catch(e){}"undefined"==typeof data&&(data={status:"error",message:obj.msgNotJSON,responseText:responseText}),"error"==data.status?obj.error(data.message):(obj.record=$.extend({},data.record),obj.original=$.extend({},data.record))}}else obj.error("AJAX Error "+xhr.status+": "+xhr.statusText),data={status:"error",message:obj.msgAJAXerror,responseText:responseText};obj.trigger($.extend(eventData,{phase:"after"})),obj.refresh(),"function"==typeof callBack&&callBack(data)}}),this.trigger($.extend(eventData,{phase:"after"}))}},submit:function(a,b){return this.save(a,b)},save:function(postData,callBack){var obj=this;$(this.box).find(":focus").change(),"function"==typeof postData&&(callBack=postData,postData=null);var errors=obj.validate(!0);return 0!==errors.length?void obj.goto(errors[0].field.page):(("undefined"==typeof postData||null==postData)&&(postData={}),!obj.url||"object"==typeof obj.url&&!obj.url.save?void console.log("ERROR: Form cannot be saved because no url is defined."):(obj.lock(obj.msgSaving+' '),void setTimeout(function(){var params={};params.cmd="save-record",params.name=obj.name,params.recid=obj.recid,$.extend(params,obj.postData),$.extend(params,postData),params.record=$.extend(!0,{},obj.record);var eventData=obj.trigger({phase:"before",type:"submit",target:obj.name,url:obj.url,postData:params});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Saving aborted."}));var url=eventData.url;if("object"==typeof eventData.url&&eventData.url.save&&(url=eventData.url.save),obj.last.xhr)try{obj.last.xhr.abort()}catch(e){}obj.last.xhr=$.ajax({type:w2utils.settings.RESTfull?0==obj.recid?"POST":"PUT":"POST",url:url,data:String($.param(eventData.postData,!1)).replace(/%5B/g,"[").replace(/%5D/g,"]"),dataType:"text",xhr:function(){var a=new window.XMLHttpRequest;return a.upload.addEventListener("progress",function(a){if(a.lengthComputable){var b=Math.round(a.loaded/a.total*100);$("#"+obj.name+"_progress").text(""+b+"%")}},!1),a},complete:function(xhr,status){obj.unlock();var eventData=obj.trigger({phase:"before",target:obj.name,type:"save",xhr:xhr,status:status});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Saving aborted."}));var data,responseText=xhr.responseText;if("error"!=status){if("undefined"!=typeof responseText&&""!=responseText){if("object"==typeof responseText)data=responseText;else try{eval("data = "+responseText)}catch(e){}"undefined"==typeof data&&(data={status:"error",message:obj.msgNotJSON,responseText:responseText}),"error"==data.status?obj.error(data.message):obj.original=$.extend({},obj.record)}}else obj.error("AJAX Error "+xhr.status+": "+xhr.statusText),data={status:"error",message:obj.msgAJAXerror,responseText:responseText};obj.trigger($.extend(eventData,{phase:"after"})),obj.refresh(),"function"==typeof callBack&&callBack(data)}}),obj.trigger($.extend(eventData,{phase:"after"}))},50)))},lock:function(){var a=$(this.box).find("> div:first-child"),b=Array.prototype.slice.call(arguments,0);b.unshift(a),w2utils.lock.apply(window,b)},unlock:function(){var a=this;setTimeout(function(){w2utils.unlock(a.box)},25)},"goto":function(a){"undefined"!=typeof a&&(this.page=a),$(this.box).data("auto-size")===!0&&$(this.box).height(0),this.refresh()},generateHTML:function(){var a=[];for(var b in this.fields){var c="",d=this.fields[b];"undefined"==typeof d.html&&(d.html={}),d.html=$.extend(!0,{caption:"",span:6,attr:"",text:"",page:0},d.html),""==d.html.caption&&(d.html.caption=d.name);var e='";("pass"===d.type||"password"===d.type)&&(e='"),"checkbox"==d.type&&(e='"),"textarea"==d.type&&(e='"),c+='\n
        '+d.html.caption+':
        \n
        '+e+d.html.text+"
        ","undefined"==typeof a[d.html.page]&&(a[d.html.page]='
        '),a[d.html.page]+=c}for(var f in a)a[f]+="\n
        ";var g="";if(!$.isEmptyObject(this.actions)){g+='\n
        ';for(var h in this.actions)g+='\n ";g+="\n
        "}return a.join("")+g},action:function(a,b){var c=this.trigger({phase:"before",target:a,type:"action",originalEvent:b});c.isCancelled!==!0&&("function"==typeof this.actions[a]&&this.actions[a].call(this,b),this.trigger($.extend(c,{phase:"after"})))},resize:function(){function a(){d.width($(b.box).width()).height($(b.box).height()),f.css("top",""!=b.header?w2utils.getSize(e,"height"):0),g.css("top",(""!=b.header?w2utils.getSize(e,"height"):0)+("object"==typeof b.toolbar&&$.isArray(b.toolbar.items)&&b.toolbar.items.length>0?w2utils.getSize(f,"height"):0)),h.css("top",(""!=b.header?w2utils.getSize(e,"height"):0)+("object"==typeof b.toolbar&&$.isArray(b.toolbar.items)&&b.toolbar.items.length>0?w2utils.getSize(f,"height")+5:0)+("object"==typeof b.tabs&&$.isArray(b.tabs.tabs)&&b.tabs.tabs.length>0?w2utils.getSize(g,"height")+5:0)),h.css("bottom",k.length>0?w2utils.getSize(k,"height"):0)}var b=this,c=this.trigger({phase:"before",target:this.name,type:"resize"});if(c.isCancelled!==!0){var d=$(this.box).find("> div"),e=$(this.box).find("> div .w2ui-form-header"),f=$(this.box).find("> div .w2ui-form-toolbar"),g=$(this.box).find("> div .w2ui-form-tabs"),h=$(this.box).find("> div .w2ui-page"),i=$(this.box).find("> div .w2ui-page.page-"+this.page),j=$(this.box).find("> div .w2ui-page.page-"+this.page+" > div"),k=$(this.box).find("> div .w2ui-buttons");a(),(0==parseInt($(this.box).height())||$(this.box).data("auto-size")===!0)&&($(this.box).height((e.length>0?w2utils.getSize(e,"height"):0)+("object"==typeof this.tabs&&$.isArray(this.tabs.tabs)&&this.tabs.tabs.length>0?w2utils.getSize(g,"height"):0)+("object"==typeof this.toolbar&&$.isArray(this.toolbar.items)&&this.toolbar.items.length>0?w2utils.getSize(f,"height"):0)+(h.length>0?w2utils.getSize(j,"height")+w2utils.getSize(i,"+height")+12:0)+(k.length>0?w2utils.getSize(k,"height"):0)),$(this.box).data("auto-size",!0)),a(),b.trigger($.extend(c,{phase:"after"}))}},refresh:function(){var a=(new Date).getTime(),b=this;if(this.box&&this.isGenerated&&"undefined"!=typeof $(this.box).html()){$(this.box).find("input, textarea, select").each(function(a,c){var d=$(c).attr("undefined"!=typeof $(c).attr("name")?"name":"id"),e=b.get(d);if(e){var f=$(c).parents(".w2ui-page");if(f.length>0)for(var g=0;100>g;g++)if(f.hasClass("page-"+g)){e.page=g;break}}});var c=this.trigger({phase:"before",target:this.name,type:"refresh",page:this.page});if(c.isCancelled!==!0){$(this.box).find(".w2ui-page").hide(),$(this.box).find(".w2ui-page.page-"+this.page).show(),$(this.box).find(".w2ui-form-header").html(this.header),"object"==typeof this.tabs&&$.isArray(this.tabs.tabs)&&this.tabs.tabs.length>0?($("#form_"+this.name+"_tabs").show(),this.tabs.active=this.tabs.tabs[this.page].id,this.tabs.refresh()):$("#form_"+this.name+"_tabs").hide(),"object"==typeof this.toolbar&&$.isArray(this.toolbar.items)&&this.toolbar.items.length>0?($("#form_"+this.name+"_toolbar").show(),this.toolbar.refresh()):$("#form_"+this.name+"_toolbar").hide();for(var d in this.fields){var e=this.fields[d];e.$el=$(this.box).find('[name="'+String(e.name).replace(/\\/g,"\\\\")+'"]'),e.el=e.$el[0],"undefined"==typeof e.el&&console.log('ERROR: Cannot associate field "'+e.name+'" with html control. Make sure html control exists with the same name.'),e.el&&(e.el.id=e.name);var f=$(e).data("w2field");f&&f.clear(),$(e.$el).off("change").on("change",function(){var a=this.value,c=b.record[this.name]?b.record[this.name]:"",d=b.get(this.name);if(-1!=["list","enum","file"].indexOf(d.type)&&$(this).data("selected")){var e=$(this).data("selected"),f=b.record[this.name];if($.isArray(e)){a=[];for(var g in e)a[g]=$.extend(!0,{},e[g])}if($.isPlainObject(e)&&(a=$.extend(!0,{},e)),$.isArray(f)){c=[];for(var g in f)c[g]=$.extend(!0,{},f[g])}$.isPlainObject(f)&&(c=$.extend(!0,{},f))}if(-1!=["int","float","percent","money","currency"].indexOf(d.type)&&(a=$(this).data("w2field").clean(a)),a!==c){var h=b.trigger({phase:"before",target:this.name,type:"change",value_new:a,value_previous:c});if(h.isCancelled===!0)return void $(this).val(b.record[this.name]);var i=this.value;if("select"==this.type&&(i=this.value),"checkbox"==this.type&&(i=this.checked?!0:!1),"radio"==this.type&&d.$el.each(function(a,b){b.checked&&(i=b.value)}),-1!=["int","float","percent","money","currency","list","combo","enum","file"].indexOf(d.type)&&(i=a),-1!=["enum","file"].indexOf(d.type)&&i.length>0){var j=$(d.el).data("w2field").helpers.multi;$(j).removeClass("w2ui-error")}b.record[this.name]=i,b.trigger($.extend(h,{phase:"after"}))}}),e.required?$(e.el).parent().addClass("w2ui-required"):$(e.el).parent().removeClass("w2ui-required")}$(this.box).find("button, input[type=button]").each(function(a,c){$(c).off("click").on("click",function(a){var c=this.value;this.name&&(c=this.name),this.id&&(c=this.id),b.action(c,a)})});for(var d in this.fields){var e=this.fields[d],g="undefined"!=typeof this.record[e.name]?this.record[e.name]:"";if(e.el)switch(e.type=String(e.type).toLowerCase(),e.options||(e.options={}),e.type){case"text":case"textarea":case"email":case"password":e.el.value=g;break;case"int":case"float":case"money":case"currency":case"percent":case"hex":case"alphanumeric":case"color":case"date":case"time":e.el.value=g,$(e.el).w2field($.extend({},e.options,{type:e.type}));break;case"list":case"combo":if("list"!=e.type||$.isPlainObject(g))e.el.value="combo"!=e.type||$.isPlainObject(g)?$.isPlainObject(g)&&"undefined"!=typeof g.text?g.text:"":g;else for(var h in e.options.items){var i=e.options.items[h];if(i&&i.id==g){g=$.extend(!0,{},i),b.record[e.name]=g;break}}$.isPlainObject(g)||(g={}),$(e.el).w2field($.extend({},e.options,{type:e.type,selected:g}));break;case"enum":case"file":$.isArray(g)||(g=[]),$(e.el).w2field($.extend({},e.options,{type:e.type,selected:g}));break;case"select":var j=e.options.items;if("undefined"!=typeof j&&j.length>0){j=w2obj.field.prototype.normMenu(j),$(e.el).html("");for(var k in j)$(e.el).append('
        '),i.markerLeft=$('
        ')),i.lastInt&&i.lastInt===a||(i.lastInt=a,i.marker.remove(),i.markerLeft.remove(),$(".w2ui-head").removeClass("w2ui-col-intersection"),a>=i.columns.length?($(i.columns[i.columns.length-1]).children("div:last").append(i.marker.addClass("right").removeClass("left")),$(i.columns[i.columns.length-1]).addClass("w2ui-col-intersection")):a<=i.numberPreColumnsPresent?($('.w2ui-head[col="0"]').prepend(i.marker.addClass("left").removeClass("right")).css({position:"relative"}),$('.w2ui-head[col="0"]').prev().addClass("w2ui-col-intersection")):($(i.columns[a]).children("div:last").prepend(i.marker.addClass("left").removeClass("right")),$(i.columns[a]).prev().children("div:last").append(i.markerLeft.addClass("right").removeClass("left")).css({position:"relative"}),$(i.columns[a-1]).addClass("w2ui-col-intersection")))}function f(a,b,c){if(a<=b[0])return 0;if(a>=b[b.length-1]+c)return b.length;for(var d=0,e=b.length;e>d;d++){var f=b[d],g=b[d+1]||b[d]+c,h=(g-b[d])/2+b[d];if(a>f&&h>=a)return d;if(a>h&&g>=a)return d+1}return intersection}function g(a,b){$(i.ghost).css({left:a-10,top:b-10})}if(this.columnGroups&&this.columnGroups.length)throw"Draggable columns are not currently supported with column groups.";var h=this,i={};return i.lastInt=null,i.pressed=!1,i.timeout=null,i.columnHead=null,$(h.box).on("mousedown",b),$(h.box).on("mouseup",a),{remove:function(){$(h.box).off("mousedown",b),$(h.box).off("mouseup",a),$(h.box).find(".w2ui-head").removeAttr("draggable"),h.last.columnDrag=!1}}},columnOnOff:function(a,b,c,d){var e=this.trigger({phase:"before",target:this.name,type:"columnOnOff",checkbox:a,field:c,originalEvent:b});if(e.isCancelled!==!0){var f=this;for(var g in this.records)this.records[g].expanded===!0&&(this.records[g].expanded=!1);var h=!0;if("line-numbers"==c)this.show.lineNumbers=!this.show.lineNumbers,this.refresh();else if("skip"==c)w2utils.isInt(d)||(d=0),f.skip(d);else if("resize"==c){for(var i in this.columns)"undefined"!=typeof this.columns[i].sizeOriginal&&(this.columns[i].size=this.columns[i].sizeOriginal);this.initResize(),this.resize()}else{var j=this.getColumn(c);j.hidden?($(a).prop("checked",!0),this.showColumn(j.field)):($(a).prop("checked",!1),this.hideColumn(j.field)),h=!1}this.initColumnOnOff(),h&&setTimeout(function(){$().w2overlay("",{name:"searches-"+this.name}),f.toolbar.uncheck("column-on-off")},100),this.trigger($.extend(e,{phase:"after"}))}},initToolbar:function(){if("undefined"==typeof this.toolbar.render){var a=this.toolbar.items;if(this.toolbar.items=[],this.toolbar=$().w2toolbar($.extend(!0,{},this.toolbar,{name:this.name+"_toolbar",owner:this})),this.show.toolbarReload&&this.toolbar.items.push($.extend(!0,{},this.buttons.reload)),this.show.toolbarColumns&&(this.toolbar.items.push($.extend(!0,{},this.buttons.columns)),this.initColumnOnOff()),(this.show.toolbarReload||this.show.toolbarColumn)&&this.toolbar.items.push({type:"break",id:"w2ui-break0"}),this.show.toolbarSearch){var b='";this.toolbar.items.push({type:"html",id:"w2ui-search",html:b}),this.multiSearch&&this.searches.length>0&&this.toolbar.items.push($.extend(!0,{},this.buttons["search-go"]))}this.show.toolbarSearch&&(this.show.toolbarAdd||this.show.toolbarEdit||this.show.toolbarDelete||this.show.toolbarSave)&&this.toolbar.items.push({type:"break",id:"w2ui-break1"}),this.show.toolbarAdd&&this.toolbar.items.push($.extend(!0,{},this.buttons.add)),this.show.toolbarEdit&&this.toolbar.items.push($.extend(!0,{},this.buttons.edit)),this.show.toolbarDelete&&this.toolbar.items.push($.extend(!0,{},this.buttons["delete"])),this.show.toolbarSave&&((this.show.toolbarAdd||this.show.toolbarDelete||this.show.toolbarEdit)&&this.toolbar.items.push({type:"break",id:"w2ui-break2"}),this.toolbar.items.push($.extend(!0,{},this.buttons.save)));for(var c in a)this.toolbar.items.push(a[c]);var d=this;this.toolbar.on("click",function(a){function b(){$("#w2ui-overlay-searches-"+d.name).data("keepOpen")!==!0&&(h.uncheck(e),$(document).off("click","body",b))}var c=d.trigger({phase:"before",type:"toolbar",target:a.target,originalEvent:a});if(c.isCancelled!==!0){var e=a.target;switch(e){case"w2ui-reload":var f=d.trigger({phase:"before",type:"reload",target:d.name});if(f.isCancelled===!0)return!1;d.reload(),d.trigger($.extend(f,{phase:"after"}));break;case"w2ui-column-on-off":for(var g in d.columns)d.columns[g].hidden?$("#grid_"+d.name+"_column_"+g+"_check").prop("checked",!1):$("#grid_"+d.name+"_column_"+g+"_check").prop("checked",!0);d.initResize(),d.resize();break;case"w2ui-search-advanced":var h=this,i=this.get(e);i.checked?(d.searchClose(),setTimeout(function(){h.uncheck(e)},1)):(d.searchOpen(),a.originalEvent.stopPropagation(),$(document).on("click","body",b));break;case"w2ui-add":var c=d.trigger({phase:"before",target:d.name,type:"add",recid:null});d.trigger($.extend(c,{phase:"after"}));break;case"w2ui-edit":var j=d.getSelection(),k=null;1==j.length&&(k=j[0]);var c=d.trigger({phase:"before",target:d.name,type:"edit",recid:k});d.trigger($.extend(c,{phase:"after"}));break;case"w2ui-delete":d.delete();break;case"w2ui-save":d.save()}d.trigger($.extend(c,{phase:"after"}))}})}},initResize:function(){var a=this;$(this.box).find(".w2ui-resizer").off("click").on("click",function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,a.preventDefault&&a.preventDefault()}).off("mousedown").on("mousedown",function(b){b||(b=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),a.resizing=!0,a.last.tmp={x:b.screenX,y:b.screenY,gx:b.screenX,gy:b.screenY,col:parseInt($(this).attr("name"))},b.stopPropagation?b.stopPropagation():b.cancelBubble=!0,b.preventDefault&&b.preventDefault();for(var c in a.columns)"undefined"==typeof a.columns[c].sizeOriginal&&(a.columns[c].sizeOriginal=a.columns[c].size),a.columns[c].size=a.columns[c].sizeCalculated;var d={phase:"before",type:"columnResize",target:a.name,column:a.last.tmp.col,field:a.columns[a.last.tmp.col].field};d=a.trigger($.extend(d,{resizeBy:0,originalEvent:b}));var e=function(b){if(1==a.resizing){if(b||(b=window.event),d=a.trigger($.extend(d,{resizeBy:b.screenX-a.last.tmp.gx,originalEvent:b})),d.isCancelled===!0)return void(d.isCancelled=!1);a.last.tmp.x=b.screenX-a.last.tmp.x,a.last.tmp.y=b.screenY-a.last.tmp.y,a.columns[a.last.tmp.col].size=parseInt(a.columns[a.last.tmp.col].size)+a.last.tmp.x+"px",a.resizeRecords(),a.last.tmp.x=b.screenX,a.last.tmp.y=b.screenY}},f=function(b){delete a.resizing,$(document).off("mousemove","body"),$(document).off("mouseup","body"),a.resizeRecords(),a.trigger($.extend(d,{phase:"after",originalEvent:b}))};$(document).on("mousemove","body",e),$(document).on("mouseup","body",f)}).each(function(a,b){var c=$(b).parent();$(b).css({height:"25px","margin-left":c.width()-3+"px"})})},resizeBoxes:function(){{var a=($(this.box).find("> div"),$("#grid_"+this.name+"_header")),b=$("#grid_"+this.name+"_toolbar"),c=$("#grid_"+this.name+"_summary"),d=$("#grid_"+this.name+"_footer"),e=$("#grid_"+this.name+"_body");$("#grid_"+this.name+"_columns"),$("#grid_"+this.name+"_records")}this.show.header&&a.css({top:"0px",left:"0px",right:"0px"}),this.show.toolbar&&b.css({top:0+(this.show.header?w2utils.getSize(a,"height"):0)+"px",left:"0px",right:"0px"}),this.show.footer&&d.css({bottom:"0px",left:"0px",right:"0px"}),this.summary.length>0&&c.css({bottom:0+(this.show.footer?w2utils.getSize(d,"height"):0)+"px",left:"0px",right:"0px"}),e.css({top:0+(this.show.header?w2utils.getSize(a,"height"):0)+(this.show.toolbar?w2utils.getSize(b,"height"):0)+"px",bottom:0+(this.show.footer?w2utils.getSize(d,"height"):0)+(this.summary.length>0?w2utils.getSize(c,"height"):0)+"px",left:"0px",right:"0px"})},resizeRecords:function(){var a=this;$(this.box).find(".w2ui-empty-record").remove();var b=$(this.box),c=$(this.box).find("> div"),d=$("#grid_"+this.name+"_header"),e=$("#grid_"+this.name+"_toolbar"),f=$("#grid_"+this.name+"_summary"),g=$("#grid_"+this.name+"_footer"),h=$("#grid_"+this.name+"_body"),i=$("#grid_"+this.name+"_columns"),j=$("#grid_"+this.name+"_records");if(this.fixedBody){var k=c.height()-(this.show.header?w2utils.getSize(d,"height"):0)-(this.show.toolbar?w2utils.getSize(e,"height"):0)-("none"!=f.css("display")?w2utils.getSize(f,"height"):0)-(this.show.footer?w2utils.getSize(g,"height"):0);h.css("height",k)}else{var k=w2utils.getSize(i,"height")+w2utils.getSize($("#grid_"+a.name+"_records table"),"height");a.height=k+w2utils.getSize(c,"+height")+(a.show.header?w2utils.getSize(d,"height"):0)+(a.show.toolbar?w2utils.getSize(e,"height"):0)+("none"!=f.css("display")?w2utils.getSize(f,"height"):0)+(a.show.footer?w2utils.getSize(g,"height"):0),c.css("height",a.height),h.css("height",k),b.css("height",w2utils.getSize(c,"height")+w2utils.getSize(b,"+height"))}var l=!1,m=!1;if(h.width()<$(j).find(">table").width()&&(l=!0),h.height()-i.height()<$(j).find(">table").height()+(l?w2utils.scrollBarSize():0)&&(m=!0),this.fixedBody||(m=!1,l=!1),l||m?(i.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show(),j.css({top:(this.columnGroups.length>0&&this.show.columns?1:0)+w2utils.getSize(i,"height")+"px","-webkit-overflow-scrolling":"touch","overflow-x":l?"auto":"hidden","overflow-y":m?"auto":"hidden"})):(i.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").hide(),j.css({top:(this.columnGroups.length>0&&this.show.columns?1:0)+w2utils.getSize(i,"height")+"px",overflow:"hidden"}),j.length>0&&(this.last.scrollTop=0,this.last.scrollLeft=0)),this.show.emptyRecords&&!m){var n=Math.floor(j.height()/this.recordHeight)+1;if(this.fixedBody)for(var o=this.buffered;n>=o;o++){var p="";p+='',this.show.lineNumbers&&(p+=''),this.show.selectColumn&&(p+=''),this.show.expandColumn&&(p+='');for(var q=0;this.columns.length>0;){var r=this.columns[q];if(r.hidden){if(q++,"undefined"==typeof this.columns[q])break}else if(p+='',q++,"undefined"==typeof this.columns[q])break}p+='',p+="",$("#grid_"+this.name+"_records > table").append(p)}}if(h.length>0){for(var s=parseInt(h.width())-(m?w2utils.scrollBarSize():0)-(this.show.lineNumbers?34:0)-(this.show.selectColumn?26:0)-(this.show.expandColumn?26:0),t=s,u=0,v=!1,w=0;wt&&r.hidden!==!0&&(r.hidden=!0,v=!0),r.gridMinWidth0)for(var w=0;wparseInt(r.max)&&(r.sizeCalculated=r.max+"px"),x+=parseInt(r.sizeCalculated))}var y=parseInt(t)-parseInt(x);if(y>0&&u>0)for(var w=0;;){var r=this.columns[w];if("undefined"!=typeof r)if(r.hidden||"px"==r.sizeType)w++;else{if(r.sizeCalculated=parseInt(r.sizeCalculated)+1+"px",y--,0==y)break;w++}else w=0}else y>0&&i.find("> table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()).show();i.find("> table > tbody > tr:nth-child(1) td").each(function(b,c){var d=$(c).attr("col");"undefined"!=typeof d&&a.columns[d]&&$(c).css("width",a.columns[d].sizeCalculated),$(c).hasClass("w2ui-head-last")&&$(c).css("width",w2utils.scrollBarSize()+(y>0&&0==u?y:0)+"px")}),3==i.find("> table > tbody > tr").length&&i.find("> table > tbody > tr:nth-child(1) td").html("").css({height:"0px",border:"0px",padding:"0px",margin:"0px"}),j.find("> table > tbody > tr:nth-child(1) td").each(function(b,c){var d=$(c).attr("col");"undefined"!=typeof d&&a.columns[d]&&$(c).css("width",a.columns[d].sizeCalculated),$(c).hasClass("w2ui-grid-data-last")&&$(c).css("width",(y>0&&0==u?y:0)+"px")}),f.find("> table > tbody > tr:nth-child(1) td").each(function(b,c){var d=$(c).attr("col");"undefined"!=typeof d&&a.columns[d]&&$(c).css("width",a.columns[d].sizeCalculated),$(c).hasClass("w2ui-grid-data-last")&&$(c).css("width",w2utils.scrollBarSize()+(y>0&&0==u?y:0)+"px")}),this.initResize(),this.refreshRanges(),""!=this.last.scrollTop&&j.length>0&&(i.prop("scrollLeft",this.last.scrollLeft),j.prop("scrollTop",this.last.scrollTop),j.prop("scrollLeft",this.last.scrollLeft))},getSearchesHTML:function(){for(var a='',b=!1,c=0;cX ";if(-1!=["int","float","money","currency","percent","date","time"].indexOf(d.type))var f='";if(-1!=["select","list","hex"].indexOf(d.type))var f='";if(-1!=["enum"].indexOf(d.type))var f='";switch(a+='"}}return a+='
        '+e+' '+d.caption+' '+f+'
        ',d.type){case"text":case"alphanumeric":case"hex":case"list":case"combo":case"enum":a+='";break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":a+='";break;case"select":a+='"}a+=d.outTag+"
        "},initOperator:function(a,b){var c=this,d=c.searches[b],e=$("#grid_"+c.name+"_range_"+b),f=$("#grid_"+c.name+"_field_"+b),g=f.parent().find("span input");f.w2field("in"==$(a).val()?"clear":d.type),"between"==$(a).val()?(e.show(),g.w2field(d.type)):e.hide()},initSearches:function(){var a=this;for(var b in this.searches){var c=this.searches[b],d=this.getSearchData(c.field);switch(c.type=String(c.type).toLowerCase(),"object"!=typeof c.options&&(c.options={}),c.type){case"text":case"alphanumeric":$("#grid_"+this.name+"_operator_"+b).val("begins"),-1!=["alphanumeric","hex"].indexOf(c.type)&&$("#grid_"+this.name+"_field_"+b).w2field(c.type,c.options);break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":if(d&&"int"==d.type&&"in"==d.operator)break;$("#grid_"+this.name+"_field_"+b).w2field(c.type,c.options),$("#grid_"+this.name+"_field2_"+b).w2field(c.type,c.options),setTimeout(function(){$("#grid_"+a.name+"_field_"+b).keydown(),$("#grid_"+a.name+"_field2_"+b).keydown()},1);break;case"hex":break;case"list":case"combo":case"enum":var e=c.options;"list"==c.type&&(e.selected={}),"enum"==c.type&&(e.selected=[]),d&&(e.selected=d.value),$("#grid_"+this.name+"_field_"+b).w2field(c.type,e),"combo"==c.type&&$("#grid_"+this.name+"_operator_"+b).val("begins");break;case"select":var e='';for(var f in c.options.items){var g=c.options.items[f];if($.isPlainObject(c.options.items[f])){var h=g.id,i=g.text;"undefined"==typeof h&&"undefined"!=typeof g.value&&(h=g.value),"undefined"==typeof i&&"undefined"!=typeof g.caption&&(i=g.caption),null==h&&(h=""),e+='"}else e+='"}$("#grid_"+this.name+"_field_"+b).html(e)}null!=d&&("int"==d.type&&"in"==d.operator&&$("#grid_"+this.name+"_field_"+b).w2field("clear").val(d.value),$("#grid_"+this.name+"_operator_"+b).val(d.operator).trigger("change"),$.isArray(d.value)?"in"==d.operator?$("#grid_"+this.name+"_field_"+b).val(d.value).trigger("change"):($("#grid_"+this.name+"_field_"+b).val(d.value[0]).trigger("change"),$("#grid_"+this.name+"_field2_"+b).val(d.value[1]).trigger("change")):"udefined"!=typeof d.value&&$("#grid_"+this.name+"_field_"+b).val(d.value).trigger("change"))}$("#w2ui-overlay-searches-"+this.name+" .w2ui-grid-searches *[rel=search]").on("keypress",function(b){13==b.keyCode&&(b.ctrlKey||b.metaKey)&&(a.search(),$().w2overlay())})},getColumnsHTML:function(){function a(){var a="";""!=c.columnGroups[c.columnGroups.length-1].caption&&c.columnGroups.push({caption:""}),c.show.lineNumbers&&(a+='
         
        '),c.show.selectColumn&&(a+='
         
        '),c.show.expandColumn&&(a+='
         
        ');for(var b=0,d=0;d
      '),a+='"+i+'
      '+(f.caption?f.caption:" ")+"
      "}else a+='
      '+(e.caption?e.caption:" ")+"
      ";b+=e.span}return a+=""}function b(a){var b="",d=!c.reorderColumns||c.columnGroups&&c.columnGroups.length?"":" w2ui-reorder-cols-head ";c.show.lineNumbers&&(b+='
      #
      "),c.show.selectColumn&&(b+='
      "),c.show.expandColumn&&(b+='
       
      ');for(var e=0,f=0,g=0;g
      '),b+='"+l+'
      '+(h.caption?h.caption:" ")+"
      "}}}return b+='
       
      ',b+=""}var c=this,d="";return this.show.columnHeaders&&(d=this.columnGroups.length>0?b(!0)+a()+b(!1):b(!0)),d},getRecordsHTML:function(){this.show_extra=this.buffered>300?30:300;var a=$("#grid_"+this.name+"_records"),b=Math.floor(a.height()/this.recordHeight)+this.show_extra+1;this.fixedBody||(b=this.buffered);var c=""+this.getRecordHTML(-1,0);c+='';for(var d=0;b>d;d++)c+=this.getRecordHTML(d,d+1);return c+='
      ',this.last.range_start=0,this.last.range_end=b,c +},getSummaryHTML:function(){if(0!=this.summary.length){for(var a="",b=0;b0&&$(b.box).find(".w2ui-grid-data > div").w2marker(a)},50))}var b=((new Date).getTime(),this),c=$("#grid_"+this.name+"_records");if(0!=this.records.length&&0!=c.length&&0!=c.height()){if(this.show_extra=this.buffered>300?30:300,c.height()0&&this.refresh());var d=Math.round(c[0].scrollTop/this.recordHeight+1),e=d+(Math.round(c.height()/this.recordHeight)-1);d>this.buffered&&(d=this.buffered),e>this.buffered&&(e=this.buffered);var f="object"!=typeof this.url?this.url:this.url.get;if($("#grid_"+this.name+"_footer .w2ui-footer-right").html(w2utils.formatNumber(this.offset+d)+"-"+w2utils.formatNumber(this.offset+e)+" "+w2utils.lang("of")+" "+w2utils.formatNumber(this.total)+(f?" ("+w2utils.lang("buffered")+" "+w2utils.formatNumber(this.buffered)+(this.offset>0?", skip "+w2utils.formatNumber(this.offset):"")+")":"")),f||this.fixedBody&&!(this.total<=300)){var g=Math.floor(c[0].scrollTop/this.recordHeight)-this.show_extra,h=g+Math.floor(c.height()/this.recordHeight)+2*this.show_extra+1;1>g&&(g=1),h>this.total&&(h=this.total);var i=c.find("#grid_"+this.name+"_rec_top"),j=c.find("#grid_"+this.name+"_rec_bottom");-1!=String(i.next().prop("id")).indexOf("_expanded_row")&&i.next().remove(),this.total>h&&-1!=String(j.prev().prop("id")).indexOf("_expanded_row")&&j.prev().remove();var k=parseInt(i.next().attr("line")),l=parseInt(j.prev().attr("line"));if(g>k||1==k||this.last.pull_refresh){if(h<=l+this.show_extra-2&&h!=this.total)return;for(this.last.pull_refresh=!1;;){var m=c.find("#grid_"+this.name+"_rec_top").next();if("bottom"==m.attr("line"))break;if(!(parseInt(m.attr("line"))=o;o++)this.records[o-1]&&(this.records[o-1].expanded===!0&&(this.records[o-1].expanded=!1),j.before(this.getRecordHTML(o-1,o)));a(),setTimeout(function(){b.refreshRanges()},0)}else{if(g>=k-this.show_extra+2&&g>1)return;for(;;){var m=c.find("#grid_"+this.name+"_rec_bottom").prev();if("top"==m.attr("line"))break;if(!(parseInt(m.attr("line"))>h))break;m.remove()}var m=c.find("#grid_"+this.name+"_rec_top").next(),n=m.attr("line");"bottom"==n&&(n=h);for(var o=parseInt(n)-1;o>=g;o--)this.records[o-1]&&(this.records[o-1].expanded===!0&&(this.records[o-1].expanded=!1),i.after(this.getRecordHTML(o-1,o)));a(),setTimeout(function(){b.refreshRanges()},0)}var p=(g-1)*b.recordHeight,q=(this.buffered-h)*b.recordHeight;0>q&&(q=0),i.css("height",p+"px"),j.css("height",q+"px"),b.last.range_start=g,b.last.range_end=h;var r=Math.floor(c[0].scrollTop/this.recordHeight),s=r+Math.floor(c.height()/this.recordHeight);if(s+10>this.buffered&&this.last.pull_more!==!0&&this.buffered
      ')}),-1==t.find("td").text().indexOf("Load")&&t.find("td").html("
      "+w2utils.lang("Load")+" "+b.limit+" "+w2utils.lang("More")+"...
      ")}this.buffered>=this.total-this.offset&&$("#grid_"+this.name+"_rec_more").hide()}}},getRecordHTML:function(a,b,c){var d,e="",f=this.last.selection;if(-1==a){e+='
      ',this.show.lineNumbers&&(e+=''),this.show.selectColumn&&(e+=''),this.show.expandColumn&&(e+='');for(var g in this.columns)this.columns[g].hidden||(e+='');return e+='',e+=""}var h="object"!=typeof this.url?this.url:this.url.get;if(c!==!0)if(this.searchData.length>0&&!h){if(a>=this.last.searchIds.length)return"";a=this.last.searchIds[a],d=this.records[a]}else{if(a>=this.records.length)return"";d=this.records[a]}else{if(a>=this.summary.length)return"";d=this.summary[a]}if(!d)return"";var i=(w2utils.escapeId(d.recid),!1);if(-1!=f.indexes.indexOf(a)&&(i=!0),e+='",this.show.lineNumbers&&(e+='"),this.show.selectColumn&&(e+='"),this.show.expandColumn){var j="";j=d.expanded===!0?"-":"+","none"==d.expanded&&(j=""),"spinner"==d.expanded&&(j='
      '),e+='"}for(var k=0;;){var l=this.columns[k];if(l.hidden){if(k++,"undefined"==typeof this.columns[k])break}else{var m=!c&&d.changes&&"undefined"!=typeof d.changes[l.field],n=this.getCellHTML(a,k,c),o="";if("string"==typeof l.render){var p=l.render.toLowerCase().split(":");-1!=["number","int","float","money","currency","percent"].indexOf(p[0])&&(o+="text-align: right;")}"object"==typeof d.style&&"string"==typeof d.style[k]&&(o+=d.style[k]+";");var q=!1;if(i&&-1!=$.inArray(k,f.columns[a])&&(q=!0),e+='",k++,"undefined"==typeof this.columns[k])break}}return e+='',e+=""},getCellHTML:function(a,b,c){var d=this.columns[b],e=c!==!0?this.records[a]:this.summary[a],f=this.getCellValue(a,b,c),g=d.editable;if("undefined"!=typeof d.render){if("function"==typeof d.render&&(f=$.trim(d.render.call(this,e,a,b)),(f.length<4||""+f+"")),"object"==typeof d.render&&(f="
      "+d.render[f]+"
      "),"string"==typeof d.render){var h=d.render.toLowerCase().split(":"),i="",j="";-1!=["number","int","float","money","currency","percent"].indexOf(h[0])&&("undefined"!=typeof h[1]&&w2utils.isInt(h[1])||(h[1]=0),h[1]>20&&(h[1]=20),h[1]<0&&(h[1]=0),-1!=["money","currency"].indexOf(h[0])&&(h[1]=w2utils.settings.currencyPrecision,i=w2utils.settings.currencyPrefix,j=w2utils.settings.currencySuffix),"percent"==h[0]&&(j="%","0"!==h[1]&&(h[1]=1)),"int"==h[0]&&(h[1]=0),f="
      "+(""!==f?i+w2utils.formatNumber(Number(f).toFixed(h[1]))+j:"")+"
      "),"time"==h[0]&&(("undefined"==typeof h[1]||""==h[1])&&(h[1]=w2utils.settings.time_format),f="
      "+i+w2utils.formatTime(f,"h12"==h[1]?"hh:mi pm":"h24:min")+j+"
      "),"date"==h[0]&&(("undefined"==typeof h[1]||""==h[1])&&(h[1]=w2utils.settings.date_display),f="
      "+i+w2utils.formatDate(f,h[1])+j+"
      "),"age"==h[0]&&(f="
      "+i+w2utils.age(f)+j+"
      ")}}else{var k="";if(g&&-1!=["checkbox","check"].indexOf(g.type)){var l=c?-(a+1):a;k="text-align: center",f=''}if(this.show.recordTitles){var m=String(f).replace(/"/g,"''");"undefined"!=typeof d.title&&("function"==typeof d.title&&(m=d.title.call(this,e,a,b)),"string"==typeof d.title&&(m=d.title));var f='
      '+f+"
      "}else var f='
      '+f+"
      "}return(null==f||"undefined"==typeof f)&&(f=""),f},getCellValue:function(a,b,c){var d=this.columns[b],e=c!==!0?this.records[a]:this.summary[a],f=this.parseField(e,d.field);return e.changes&&"undefined"!=typeof e.changes[d.field]&&(f=e.changes[d.field]),(null==f||"undefined"==typeof f)&&(f=""),f},getFooterHTML:function(){return'
      '},status:function(a){if("undefined"!=typeof a)$("#grid_"+this.name+"_footer").find(".w2ui-footer-left").html(a);else{var b="",c=this.getSelection();if(c.length>0){b=String(c.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")+" "+w2utils.lang("selected");var d=c[0];"object"==typeof d&&(d=d.recid+", "+w2utils.lang("Column")+": "+d.column),1==c.length&&(b=w2utils.lang("Record ID")+": "+d+" ")}$("#grid_"+this.name+"_footer .w2ui-footer-left").html(b),1==c.length?this.toolbar.enable("w2ui-edit"):this.toolbar.disable("w2ui-edit"),c.length>=1?this.toolbar.enable("w2ui-delete"):this.toolbar.disable("w2ui-delete")}},lock:function(){var a=$(this.box).find("> div:first-child"),b=Array.prototype.slice.call(arguments,0);b.unshift(a),setTimeout(function(){w2utils.lock.apply(window,b)},10)},unlock:function(){var a=this.box;setTimeout(function(){w2utils.unlock(a)},25)},parseField:function(a,b){var c="";try{c=a;var d=String(b).split(".");for(var e in d)c=c[d[e]]}catch(f){c=""}return c},prepareData:function(){for(var a in this.records){var b=this.records[a];for(var c in this.columns){var d=this.columns[c];if(null!=b[d.field]&&"string"==typeof d.render){if(-1!=["number","int","float","money","currency","percent"].indexOf(d.render.split(":")[0])&&"number"!=typeof b[d.field]&&(b[d.field]=parseFloat(b[d.field])),-1!=["date","age"].indexOf(d.render)&&!b[d.field+"_"]){var e=b[d.field];w2utils.isInt(e)&&(e=parseInt(e)),b[d.field+"_"]=new Date(e)}if(-1!=["time"].indexOf(d.render))if(w2utils.isTime(b[d.field])){var f=w2utils.isTime(b[d.field],!0),e=new Date;e.setHours(f.hours,f.minutes,f.seconds?f.seconds:0,0),b[d.field+"_"]||(b[d.field+"_"]=e)}else{var f=b[d.field];w2utils.isInt(f)&&(f=parseInt(f));var f=null!=f?new Date(f):new Date,e=new Date;e.setHours(f.getHours(),f.getMinutes(),f.getSeconds(),0),b[d.field+"_"]||(b[d.field+"_"]=e)}}}}},nextCell:function(a,b){var c=a+1;if(this.columns.length==c)return!1;if(b===!0){var d=this.columns[c].editable;if(this.columns[c].hidden||"undefined"==typeof d||d&&-1!=["checkbox","check"].indexOf(d.type))return this.nextCell(c,b)}return c},prevCell:function(a,b){var c=a-1;if(0>c)return!1;if(b===!0){var d=this.columns[c].editable;if(this.columns[c].hidden||"undefined"==typeof d||d&&-1!=["checkbox","check"].indexOf(d.type))return this.prevCell(c,b)}return c},nextRow:function(a){if(a+10&&a0)for(;;){if(-1!=$.inArray(a,this.last.searchIds)||a>this.records.length)break;a++}return a}return null},prevRow:function(a){if(a>0&&0==this.last.searchIds.length||this.last.searchIds.length>0&&a>this.last.searchIds[0]){if(a--,this.last.searchIds.length>0)for(;;){if(-1!=$.inArray(a,this.last.searchIds)||0>a)break;a--}return a}return null}},$.extend(w2grid.prototype,w2utils.event),w2obj.grid=w2grid}(),function(){var a=function(a){this.box=null,this.name=null,this.panels=[],this.tmp={},this.padding=1,this.resizer=4,this.style="",this.onShow=null,this.onHide=null,this.onResizing=null,this.onResizerClick=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(!0,this,w2obj.layout,a)},b=["top","left","main","preview","right","bottom"];$.fn.w2layout=function(c){function d(a,b,c){var d=a.get(b);return null!==d&&"undefined"==typeof c&&(c=d.tabs),null===d||null===c?!1:($.isArray(c)&&(c={tabs:c}),$().w2destroy(a.name+"_"+b+"_tabs"),d.tabs=$().w2tabs($.extend({},c,{owner:a,name:a.name+"_"+b+"_tabs"})),d.show.tabs=!0,!0)}function e(a,b,c){var d=a.get(b);return null!==d&&"undefined"==typeof c&&(c=d.toolbar),null===d||null===c?!1:($.isArray(c)&&(c={items:c}),$().w2destroy(a.name+"_"+b+"_toolbar"),d.toolbar=$().w2toolbar($.extend({},c,{owner:a,name:a.name+"_"+b+"_toolbar"})),d.show.toolbar=!0,!0)}if("object"==typeof c||!c){if(!w2utils.checkName(c,"w2layout"))return;var f=c.panels||[],g=new a(c);$.extend(g,{handlers:[],panels:[]});for(var h=0,i=f.length;i>h;h++)g.panels[h]=$.extend(!0,{},a.prototype.panel,f[h]),($.isPlainObject(g.panels[h].tabs)||$.isArray(g.panels[h].tabs))&&d(g,f[h].type),($.isPlainObject(g.panels[h].toolbar)||$.isArray(g.panels[h].toolbar))&&e(g,f[h].type);for(var j in b)j=b[j],null===g.get(j)&&g.panels.push($.extend(!0,{},a.prototype.panel,{type:j,hidden:"main"!==j,size:50}));return $(this).length>0&&g.render($(this)[0]),w2ui[g.name]=g,g}if(w2ui[$(this).attr("name")]){var k=w2ui[$(this).attr("name")];return k[c].apply(k,Array.prototype.slice.call(arguments,1)),this}console.log("ERROR: Method "+c+" does not exist on jQuery.w2layout")},a.prototype={panel:{title:"",type:null,size:100,minSize:20,maxSize:!1,hidden:!1,resizable:!1,overflow:"auto",style:"",content:"",tabs:null,toolbar:null,width:null,height:null,show:{toolbar:!1,tabs:!1},onRefresh:null,onShow:null,onHide:null},html:function(a,b,c){return this.content(a,b,c)},content:function(a,b,c){var d=this,e=this.get(a);if("css"==a)return $("#layout_"+d.name+"_panel_css").html(""),!0;if(null===e)return!1;if("undefined"==typeof b||null===b)return e.content;if(b instanceof jQuery)return console.log("ERROR: You can not pass jQuery object to w2layout.content() method"),!1;var f="#layout_"+this.name+"_panel_"+e.type,g=$(f+"> .w2ui-panel-content"),h=0;if(g.length>0&&($(f).scrollTop(0),h=$(g).position().top),""===e.content)e.content=b,this.refresh(a);else{if(e.content=b,!e.hidden&&null!==c&&""!==c&&"undefined"!=typeof c){var i=$(f+"> .w2ui-panel-content");i.after('
      ');var j=$(f+"> .w2ui-panel-content.new-panel");i.css("top",h),j.css("top",h),"object"==typeof b?(b.box=j[0],b.render()):j.html(b),w2utils.transition(i[0],j[0],c,function(){i.remove(),j.removeClass("new-panel"),j.css("overflow",e.overflow),d.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){d.resize()},100)})}this.refresh(a)}return d.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){d.resize()},100),!0},load:function(a,b,c,d){var e=this;return"css"==a?($.get(b,function(b,c,f){e.content(a,f.responseText),d&&d()}),!0):null!==this.get(a)?($.get(b,function(b,f,g){e.content(a,g.responseText,c),d&&d(),e.resize(),-1!=window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){e.resize()},100)}),!0):!1},sizeTo:function(a,b){var c=this,d=c.get(a);return null===d?!1:($(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),setTimeout(function(){c.set(a,{size:b})},1),setTimeout(function(){$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),c.resize()},500),!0)},show:function(a,b){var c=this,d=this.trigger({phase:"before",type:"show",target:a,object:this.get(a),immediate:b});if(d.isCancelled!==!0){var e=c.get(a);return null===e?!1:(e.hidden=!1,b===!0?($("#layout_"+c.name+"_panel_"+a).css({opacity:"1"}),e.resizable&&$("#layout_"+c.name+"_resizer_"+a).show(),c.trigger($.extend(d,{phase:"after"})),c.resize()):(e.resizable&&$("#layout_"+c.name+"_resizer_"+a).show(),$("#layout_"+c.name+"_panel_"+a).css({opacity:"0"}),$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),setTimeout(function(){c.resize()},1),setTimeout(function(){$("#layout_"+c.name+"_panel_"+a).css({opacity:"1"})},250),setTimeout(function(){$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),c.trigger($.extend(d,{phase:"after"})),c.resize()},500)),!0)}},hide:function(a,b){var c=this,d=this.trigger({phase:"before",type:"hide",target:a,object:this.get(a),immediate:b});if(d.isCancelled!==!0){var e=c.get(a);return null===e?!1:(e.hidden=!0,b===!0?($("#layout_"+c.name+"_panel_"+a).css({opacity:"0"}),$("#layout_"+c.name+"_resizer_"+a).hide(),c.trigger($.extend(d,{phase:"after"})),c.resize()):($("#layout_"+c.name+"_resizer_"+a).hide(),$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),$("#layout_"+c.name+"_panel_"+a).css({opacity:"0"}),setTimeout(function(){c.resize()},1),setTimeout(function(){$(c.box).find(" > div > .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),c.trigger($.extend(d,{phase:"after"})),c.resize()},500)),!0)}},toggle:function(a,b){var c=this.get(a);return null===c?!1:c.hidden?this.show(a,b):this.hide(a,b)},set:function(a,b){var c=this.get(a,!0);return null===c?!1:($.extend(this.panels[c],b),"undefined"!=typeof b.content&&this.refresh(a),this.resize(),!0)},get:function(a,b){for(var c in this.panels)if(this.panels[c].type==a)return b===!0?c:this.panels[c];return null},el:function(a){var b=$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-content");return 1!=b.length?null:b[0]},hideToolbar:function(a){var b=this.get(a);b&&(b.show.toolbar=!1,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-toolbar").hide(),this.resize())},showToolbar:function(a){var b=this.get(a);b&&(b.show.toolbar=!0,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-toolbar").show(),this.resize())},toggleToolbar:function(a){var b=this.get(a);b&&(b.show.toolbar?this.hideToolbar(a):this.showToolbar(a))},hideTabs:function(a){var b=this.get(a);b&&(b.show.tabs=!1,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-tabs").hide(),this.resize())},showTabs:function(a){var b=this.get(a);b&&(b.show.tabs=!0,$("#layout_"+this.name+"_panel_"+a+"> .w2ui-panel-tabs").show(),this.resize())},toggleTabs:function(a){var b=this.get(a);b&&(b.show.tabs?this.hideTabs(a):this.showTabs(a))},render:function(a){function c(){g.tmp.events={resize:function(){w2ui[g.name].resize()},resizeStart:d,mouseMove:f,mouseUp:e},$(window).on("resize",g.tmp.events.resize)}function d(a,c){if(g.box){c||(c=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),$(document).off("mousemove",g.tmp.events.mouseMove).on("mousemove",g.tmp.events.mouseMove),$(document).off("mouseup",g.tmp.events.mouseUp).on("mouseup",g.tmp.events.mouseUp),g.tmp.resize={type:a,x:c.screenX,y:c.screenY,diff_x:0,diff_y:0,value:0};for(var d in b)d=b[d],g.lock(d,{opacity:0});("left"==a||"right"==a)&&(g.tmp.resize.value=parseInt($("#layout_"+g.name+"_resizer_"+a)[0].style.left)),("top"==a||"preview"==a||"bottom"==a)&&(g.tmp.resize.value=parseInt($("#layout_"+g.name+"_resizer_"+a)[0].style.top))}}function e(a){if(g.box&&(a||(a=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),$(document).off("mousemove",g.tmp.events.mouseMove),$(document).off("mouseup",g.tmp.events.mouseUp),"undefined"!=typeof g.tmp.resize)){for(var c in b)g.unlock(b[c]);if(0!==g.tmp.diff_x||0!==g.tmp.resize.diff_y){var d,e,f=g.get("top"),h=g.get("bottom"),i=g.get(g.tmp.resize.type),j=parseInt($(g.box).height()),k=parseInt($(g.box).width()),l=String(i.size);switch(g.tmp.resize.type){case"top":d=parseInt(i.sizeCalculated)+g.tmp.resize.diff_y,e=0;break;case"bottom":d=parseInt(i.sizeCalculated)-g.tmp.resize.diff_y,e=0;break;case"preview":d=parseInt(i.sizeCalculated)-g.tmp.resize.diff_y,e=(f&&!f.hidden?f.sizeCalculated:0)+(h&&!h.hidden?h.sizeCalculated:0);break;case"left":d=parseInt(i.sizeCalculated)+g.tmp.resize.diff_x,e=0;break;case"right":d=parseInt(i.sizeCalculated)-g.tmp.resize.diff_x,e=0}i.size="%"==l.substr(l.length-1)?Math.floor(100*d/("left"==i.type||"right"==i.type?k:j-e)*100)/100+"%":d,g.resize()}$("#layout_"+g.name+"_resizer_"+g.tmp.resize.type).removeClass("active"),delete g.tmp.resize}}function f(a){if(g.box&&(a||(a=window.event),"undefined"!=typeof g.tmp.resize)){var b=g.get(g.tmp.resize.type),c=g.tmp.resize,d=g.trigger({phase:"before",type:"resizing",target:g.name,object:b,originalEvent:a,panel:c?c.type:"all",diff_x:c?c.diff_x:0,diff_y:c?c.diff_y:0});if(d.isCancelled!==!0){var e=$("#layout_"+g.name+"_resizer_"+c.type),f=a.screenX-c.x,h=a.screenY-c.y,i=g.get("main");switch(e.hasClass("active")||e.addClass("active"),c.type){case"left":b.minSize-f>b.width&&(f=b.minSize-b.width),b.maxSize&&b.width+f>b.maxSize&&(f=b.maxSize-b.width),i.minSize+f>i.width&&(f=i.width-i.minSize);break;case"right":b.minSize+f>b.width&&(f=b.width-b.minSize),b.maxSize&&b.width-f>b.maxSize&&(f=b.width-b.maxSize),i.minSize-f>i.width&&(f=i.minSize-i.width);break;case"top":b.minSize-h>b.height&&(h=b.minSize-b.height),b.maxSize&&b.height+h>b.maxSize&&(h=b.maxSize-b.height),i.minSize+h>i.height&&(h=i.height-i.minSize);break;case"preview":case"bottom":b.minSize+h>b.height&&(h=b.height-b.minSize),b.maxSize&&b.height-h>b.maxSize&&(h=b.height-b.maxSize),i.minSize-h>i.height&&(h=i.minSize-i.height)}switch(c.diff_x=f,c.diff_y=h,c.type){case"top":case"preview":case"bottom":c.diff_x=0,e.length>0&&(e[0].style.top=c.value+c.diff_y+"px");break;case"left":case"right":c.diff_y=0,e.length>0&&(e[0].style.left=c.value+c.diff_x+"px")}g.trigger($.extend(d,{phase:"after"}))}}}var g=this,h=(new Date).getTime(),i=g.trigger({phase:"before",type:"render",target:g.name,box:a});if(i.isCancelled!==!0){if("undefined"!=typeof a&&null!==a&&($(g.box).find("#layout_"+g.name+"_panel_main").length>0&&$(g.box).removeAttr("name").removeClass("w2ui-layout").html(""),g.box=a),!g.box)return!1;$(g.box).attr("name",g.name).addClass("w2ui-layout").html("
      "),$(g.box).length>0&&($(g.box)[0].style.cssText+=g.style);for(var j in b){j=b[j];var k=(g.get(j),'
      ');$(g.box).find(" > div").append(k)}return $(g.box).find(" > div").append('
      .w2ui-panel-content")[0],setTimeout(function(){$(f+"> .w2ui-panel-content").length>0&&($(f+"> .w2ui-panel-content").removeClass().addClass("w2ui-panel-content").css("overflow",e.overflow)[0].style.cssText+=";"+e.style),e.content.render()},1)):$(f+"> .w2ui-panel-content").length>0&&($(f+"> .w2ui-panel-content").removeClass().addClass("w2ui-panel-content").html(e.content).css("overflow",e.overflow)[0].style.cssText+=";"+e.style);var h=$(b.box).find(f+"> .w2ui-panel-tabs");e.show.tabs?0===h.find("[name="+e.tabs.name+"]").length&&null!==e.tabs?h.w2render(e.tabs):e.tabs.refresh():h.html("").removeClass("w2ui-tabs").hide(),h=$(b.box).find(f+"> .w2ui-panel-toolbar"),e.show.toolbar?0===h.find("[name="+e.toolbar.name+"]").length&&null!==e.toolbar?h.w2render(e.toolbar):e.toolbar.refresh():h.html("").removeClass("w2ui-toolbar").hide(),h=$(b.box).find(f+"> .w2ui-panel-title"),e.title?h.html(e.title).show():h.html("").hide()}else{if(0==$("#layout_"+b.name+"_panel_main").length)return void b.render();b.resize();for(var i in this.panels)b.refresh(this.panels[i].type)}return b.trigger($.extend(d,{phase:"after"})),(new Date).getTime()-c}},resize:function(){if(!this.box)return!1;var a=(new Date).getTime(),c=this.tmp.resize,d=this.trigger({phase:"before",type:"resize",target:this.name,panel:c?c.type:"all",diff_x:c?c.diff_x:0,diff_y:c?c.diff_y:0});if(d.isCancelled!==!0){this.padding<0&&(this.padding=0);var e=parseInt($(this.box).width()),f=parseInt($(this.box).height());$(this.box).find(" > div").css({width:e+"px",height:f+"px"});var g,h,i,j,k,l=this,m=this.get("main"),n=this.get("preview"),o=this.get("left"),p=this.get("right"),q=this.get("top"),r=this.get("bottom"),s=null!==n&&n.hidden!==!0?!0:!1,t=null!==o&&o.hidden!==!0?!0:!1,u=null!==p&&p.hidden!==!0?!0:!1,v=null!==q&&q.hidden!==!0?!0:!1,w=null!==r&&r.hidden!==!0?!0:!1;for(var x in b)if(x=b[x],"main"!==x){var c=this.get(x);if(c){var y=String(c.size||0);if("%"==y.substr(y.length-1)){var z=f;"preview"==c.type&&(z=z-(q&&!q.hidden?q.sizeCalculated:0)-(r&&!r.hidden?r.sizeCalculated:0)),c.sizeCalculated=parseInt(("left"==c.type||"right"==c.type?e:z)*parseFloat(c.size)/100)}else c.sizeCalculated=parseInt(c.size);c.sizeCalculated=Math.max(c.sizeCalculated,parseInt(c.minSize))}}null!==q&&q.hidden!==!0?(g=0,h=0,i=e,j=q.sizeCalculated,$("#layout_"+this.name+"_panel_top").css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px"}).show(),q.width=i,q.height=j,q.resizable&&(h=q.sizeCalculated-(0===this.padding?this.resizer:0),j=this.resizer>this.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_top").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"top",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("top",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_top").hide(),null!==o&&o.hidden!==!0?(g=0,h=0+(v?q.sizeCalculated+this.padding:0),i=o.sizeCalculated,j=f-(v?q.sizeCalculated+this.padding:0)-(w?r.sizeCalculated+this.padding:0),k=$("#layout_"+this.name+"_panel_left"),-1!=window.navigator.userAgent.indexOf("MSIE")&&k.length>0&&k[0].clientHeightthis.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_left").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"left",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("left",a),l.trigger($.extend(b,{phase:"after"})),!1}))):($("#layout_"+this.name+"_panel_left").hide(),$("#layout_"+this.name+"_resizer_left").hide()),null!==p&&p.hidden!==!0?(g=e-p.sizeCalculated,h=0+(v?q.sizeCalculated+this.padding:0),i=p.sizeCalculated,j=f-(v?q.sizeCalculated+this.padding:0)-(w?r.sizeCalculated+this.padding:0),$("#layout_"+this.name+"_panel_right").css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px"}).show(),p.width=i,p.height=j,p.resizable&&(g-=this.padding,i=this.resizer>this.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_right").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"right",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("right",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_right").hide(),null!==r&&r.hidden!==!0?(g=0,h=f-r.sizeCalculated,i=e,j=r.sizeCalculated,$("#layout_"+this.name+"_panel_bottom").css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px"}).show(),r.width=i,r.height=j,r.resizable&&(h-=0===this.padding?0:this.padding,j=this.resizer>this.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_bottom").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"bottom",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("bottom",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_bottom").hide(),g=0+(t?o.sizeCalculated+this.padding:0),h=0+(v?q.sizeCalculated+this.padding:0),i=e-(t?o.sizeCalculated+this.padding:0)-(u?p.sizeCalculated+this.padding:0),j=f-(v?q.sizeCalculated+this.padding:0)-(w?r.sizeCalculated+this.padding:0)-(s?n.sizeCalculated+this.padding:0),k=$("#layout_"+this.name+"_panel_main"),-1!=window.navigator.userAgent.indexOf("MSIE")&&k.length>0&&k[0].clientHeight0&&k[0].clientHeightthis.padding?this.resizer:this.padding,$("#layout_"+this.name+"_resizer_preview").show().css({display:"block",left:g+"px",top:h+"px",width:i+"px",height:j+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(a){var b=l.trigger({phase:"before",type:"resizerClick",target:"preview",originalEvent:a});if(b.isCancelled!==!0)return w2ui[l.name].tmp.events.resizeStart("preview",a),l.trigger($.extend(b,{phase:"after"})),!1}))):$("#layout_"+this.name+"_panel_preview").hide();for(var A in b){A=b[A];var B=this.get(A),C="#layout_"+this.name+"_panel_"+A+" > .w2ui-panel-",D=0;B&&(B.title&&(D+=w2utils.getSize($(C+"title").css({top:D+"px",display:"block"}),"height")),B.show.tabs&&(null!==B.tabs&&w2ui[this.name+"_"+A+"_tabs"]&&w2ui[this.name+"_"+A+"_tabs"].resize(),D+=w2utils.getSize($(C+"tabs").css({top:D+"px",display:"block"}),"height")),B.show.toolbar&&(null!==B.toolbar&&w2ui[this.name+"_"+A+"_toolbar"]&&w2ui[this.name+"_"+A+"_toolbar"].resize(),D+=w2utils.getSize($(C+"toolbar").css({top:D+"px",display:"block"}),"height"))),$(C+"content").css({display:"block"}).css({top:D+"px"}) +}return clearTimeout(this._resize_timer),this._resize_timer=setTimeout(function(){for(var a in w2ui)if("function"==typeof w2ui[a].resize){"undefined"==w2ui[a].panels&&w2ui[a].resize();var b=$(w2ui[a].box).parents(".w2ui-layout");b.length>0&&b.attr("name")==l.name&&w2ui[a].resize()}},100),this.trigger($.extend(d,{phase:"after"})),(new Date).getTime()-a}},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});if(a.isCancelled!==!0)return"undefined"==typeof w2ui[this.name]?!1:($(this.box).find("#layout_"+this.name+"_panel_main").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-layout").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})),this.tmp.events&&this.tmp.events.resize&&$(window).off("resize",this.tmp.events.resize),!0)},lock:function(a){if(-1==b.indexOf(a))return void console.log("ERROR: First parameter needs to be the a valid panel name.");var c=Array.prototype.slice.call(arguments,0);c[0]="#layout_"+this.name+"_panel_"+a,w2utils.lock.apply(window,c)},unlock:function(a){if(-1==b.indexOf(a))return void console.log("ERROR: First parameter needs to be the a valid panel name.");var c="#layout_"+this.name+"_panel_"+a;w2utils.unlock(c)}},$.extend(a.prototype,w2utils.event),w2obj.layout=a}();var w2popup={};!function(){$.fn.w2popup=function(a,b){"undefined"==typeof a&&(b={},a="open"),$.isPlainObject(a)&&(b=a,a="open"),a=a.toLowerCase(),"load"===a&&"string"==typeof b&&(b=$.extend({url:b},arguments.length>2?arguments[2]:{})),"open"===a&&null!=b.url&&(a="load"),b=b||{};var c={};return $(this).length>0&&($(this).find("div[rel=title], div[rel=body], div[rel=buttons]").length>0?($(this).find("div[rel=title]").length>0&&(c.title=$(this).find("div[rel=title]").html()),$(this).find("div[rel=body]").length>0&&(c.body=$(this).find("div[rel=body]").html(),c.style=$(this).find("div[rel=body]")[0].style.cssText),$(this).find("div[rel=buttons]").length>0&&(c.buttons=$(this).find("div[rel=buttons]").html())):(c.title=" ",c.body=$(this).html()),0!=parseInt($(this).css("width"))&&(c.width=parseInt($(this).css("width"))),0!=parseInt($(this).css("height"))&&(c.height=parseInt($(this).css("height")))),w2popup[a]($.extend({},c,b))},w2popup={defaults:{title:"",body:"",buttons:"",style:"",color:"#000",opacity:.4,speed:.3,modal:!1,maximized:!1,keyboard:!0,width:500,height:300,showClose:!0,showMax:!1,transition:null},status:"closed",handlers:[],onOpen:null,onClose:null,onMax:null,onMin:null,onToggle:null,onKeydown:null,open:function(a){function b(a){return a||(a=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),w2popup.status="moving",p.resizing=!0,p.x=a.screenX,p.y=a.screenY,p.pos_x=$("#w2ui-popup").position().left,p.pos_y=$("#w2ui-popup").position().top,w2popup.lock({opacity:0}),$(document).on("mousemove",p.mvMove),$(document).on("mouseup",p.mvStop),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,a.preventDefault?void a.preventDefault():!1}function c(a){1==p.resizing&&(a||(a=window.event),p.div_x=a.screenX-p.x,p.div_y=a.screenY-p.y,$("#w2ui-popup").css({"-webkit-transition":"none","-webkit-transform":"translate3d("+p.div_x+"px, "+p.div_y+"px, 0px)","-moz-transition":"none","-moz-transform":"translate("+p.div_x+"px, "+p.div_y+"px)","-ms-transition":"none","-ms-transform":"translate("+p.div_x+"px, "+p.div_y+"px)","-o-transition":"none","-o-transform":"translate("+p.div_x+"px, "+p.div_y+"px)"}))}function d(a){1==p.resizing&&(a||(a=window.event),w2popup.status="open",p.div_x=a.screenX-p.x,p.div_y=a.screenY-p.y,$("#w2ui-popup").css({left:p.pos_x+p.div_x+"px",top:p.pos_y+p.div_y+"px","-webkit-transition":"none","-webkit-transform":"translate3d(0px, 0px, 0px)","-moz-transition":"none","-moz-transform":"translate(0px, 0px)","-ms-transition":"none","-ms-transform":"translate(0px, 0px)","-o-transition":"none","-o-transform":"translate(0px, 0px)"}),p.resizing=!1,$(document).off("mousemove",p.mvMove),$(document).off("mouseup",p.mvStop),w2popup.unlock())}var e=this;if("closing"==w2popup.status)return void setTimeout(function(){e.open.call(e,a)},100);var f=$("#w2ui-popup").data("options"),a=$.extend({},this.defaults,{body:""},f,a,{maximized:!1});if(setTimeout(function(){$("#w2ui-popup").data("options",a)},100),0==$("#w2ui-popup").length&&(w2popup.handlers=[],w2popup.onMax=null,w2popup.onMin=null,w2popup.onToggle=null,w2popup.onOpen=null,w2popup.onClose=null,w2popup.onKeydown=null),a.onOpen&&(w2popup.onOpen=a.onOpen),a.onClose&&(w2popup.onClose=a.onClose),a.onMax&&(w2popup.onMax=a.onMax),a.onMin&&(w2popup.onMin=a.onMin),a.onToggle&&(w2popup.onToggle=a.onToggle),a.onKeydown&&(w2popup.onKeydown=a.onKeydown),void 0==window.innerHeight){var g=document.documentElement.offsetWidth,h=document.documentElement.offsetHeight;"IE7"===w2utils.engine&&(g+=21,h+=4)}else var g=window.innerWidth,h=window.innerHeight;parseInt(g)-10';""!=a.title&&(l+='
      '+(a.showClose?'
      Close
      ':"")+(a.showMax?'
      Max
      ':"")+a.title+"
      "),l+='
      ',l+='
      '+a.body+"
      ",l+="
      ",l+='
      ',l+='
      ',l+="
      ",""!=a.buttons&&(l+='
      '+a.buttons+"
      "),l+="
      ",$("body").append(l),setTimeout(function(){$("#w2ui-popup .w2ui-box2").hide(),$("#w2ui-popup").css({"-webkit-transition":a.speed+"s opacity, "+a.speed+"s -webkit-transform","-webkit-transform":"scale(1)","-moz-transition":a.speed+"s opacity, "+a.speed+"s -moz-transform","-moz-transform":"scale(1)","-ms-transition":a.speed+"s opacity, "+a.speed+"s -ms-transform","-ms-transform":"scale(1)","-o-transition":a.speed+"s opacity, "+a.speed+"s -o-transform","-o-transform":"scale(1)",opacity:"1"})},1),setTimeout(function(){$("#w2ui-popup").css({"-webkit-transform":"","-moz-transform":"","-ms-transform":"","-o-transform":""}),w2popup.status="open",setTimeout(function(){e.trigger($.extend(k,{phase:"after"}))},100)},1e3*a.speed)}else{var k=this.trigger({phase:"before",type:"open",target:"popup",options:a,present:!0});if(k.isCancelled===!0)return;w2popup.status="opening",("undefined"==typeof f||f.width!=a.width||f.height!=a.height)&&w2popup.resize(a.width,a.height),"undefined"!=typeof f&&(a.prevSize=a.width+":"+a.height,a.maximized=f.maximized);var m=$("#w2ui-popup .w2ui-box2 > .w2ui-msg-body").html(a.body);m.length>0&&(m[0].style.cssText=a.style),$("#w2ui-popup .w2ui-msg-buttons").html(a.buttons),$("#w2ui-popup .w2ui-msg-title").html((a.showClose?'
      Close
      ':"")+(a.showMax?'
      Max
      ':"")+a.title);var n=$("#w2ui-popup .w2ui-box1")[0],o=$("#w2ui-popup .w2ui-box2")[0];w2utils.transition(n,o,a.transition),o.className="w2ui-box1",n.className="w2ui-box2",$(o).addClass("w2ui-current-box"),$("#w2ui-popup").data("prev-size",null),setTimeout(function(){w2popup.status="open",e.trigger($.extend(k,{phase:"after"}))},100)}a._last_w2ui_name=w2utils.keyboard.active(),w2utils.keyboard.active(null),a.keyboard&&$(document).on("keydown",this.keydown);var p={resizing:!1,mvMove:c,mvStop:d};return $("#w2ui-popup .w2ui-msg-title").on("mousedown",function(a){b(a)}),this},keydown:function(a){var b=$("#w2ui-popup").data("options");if(b.keyboard){var c=w2popup.trigger({phase:"before",type:"keydown",target:"popup",options:b,originalEvent:a});if(c.isCancelled!==!0){switch(a.keyCode){case 27:a.preventDefault(),$("#w2ui-popup .w2ui-popup-message").length>0?w2popup.message():w2popup.close()}w2popup.trigger($.extend(c,{phase:"after"}))}}},close:function(a){var b=this,a=$.extend({},$("#w2ui-popup").data("options"),a);if(0!=$("#w2ui-popup").length){var c=this.trigger({phase:"before",type:"close",target:"popup",options:a});c.isCancelled!==!0&&(w2popup.status="closing",$("#w2ui-popup").css({"-webkit-transition":a.speed+"s opacity, "+a.speed+"s -webkit-transform","-webkit-transform":"scale(0.9)","-moz-transition":a.speed+"s opacity, "+a.speed+"s -moz-transform","-moz-transform":"scale(0.9)","-ms-transition":a.speed+"s opacity, "+a.speed+"s -ms-transform","-ms-transform":"scale(0.9)","-o-transition":a.speed+"s opacity, "+a.speed+"s -o-transform","-o-transform":"scale(0.9)",opacity:"0"}),w2popup.unlockScreen(a),setTimeout(function(){$("#w2ui-popup").remove(),w2popup.status="closed",b.trigger($.extend(c,{phase:"after"}))},1e3*a.speed),w2utils.keyboard.active(a._last_w2ui_name),a.keyboard&&$(document).off("keydown",this.keydown))}},toggle:function(){var a=this,b=$("#w2ui-popup").data("options"),c=this.trigger({phase:"before",type:"toggle",target:"popup",options:b});c.isCancelled!==!0&&(b.maximized===!0?w2popup.min():w2popup.max(),setTimeout(function(){a.trigger($.extend(c,{phase:"after"}))},250))},max:function(){var a=this,b=$("#w2ui-popup").data("options");if(b.maximized!==!0){var c=this.trigger({phase:"before",type:"max",target:"popup",options:b});c.isCancelled!==!0&&(w2popup.status="resizing",b.prevSize=$("#w2ui-popup").css("width")+":"+$("#w2ui-popup").css("height"),w2popup.resize(1e4,1e4,function(){w2popup.status="open",b.maximized=!0,a.trigger($.extend(c,{phase:"after"}))}))}},min:function(){var a=this,b=$("#w2ui-popup").data("options");if(b.maximized===!0){var c=b.prevSize.split(":"),d=this.trigger({phase:"before",type:"min",target:"popup",options:b});d.isCancelled!==!0&&(w2popup.status="resizing",w2popup.resize(c[0],c[1],function(){w2popup.status="open",b.maximized=!1,b.prevSize=null,a.trigger($.extend(d,{phase:"after"}))}))}},get:function(){return $("#w2ui-popup").data("options")},set:function(a){w2popup.open(a)},clear:function(){$("#w2ui-popup .w2ui-msg-title").html(""),$("#w2ui-popup .w2ui-msg-body").html(""),$("#w2ui-popup .w2ui-msg-buttons").html("")},reset:function(){w2popup.open(w2popup.defaults)},load:function(a){function b(b,c){if(delete a.url,$("body").append('"),"undefined"!=typeof c&&$("#w2ui-tmp #"+c).length>0?$("#w2ui-tmp #"+c).w2popup(a):$("#w2ui-tmp > div").w2popup(a),$("#w2ui-tmp > style").length>0){var d=$("
      ").append($("#w2ui-tmp > style").clone()).html();0==$("#w2ui-popup #div-style").length&&$("#w2ui-popup").append('
      '),$("#w2ui-popup #div-style").html(d)}$("#w2ui-tmp").remove()}if(w2popup.status="loading","undefined"==String(a.url))return void console.log("ERROR: The url parameter is empty.");var c=String(a.url).split("#"),d=c[0],e=c[1];"undefined"==String(a)&&(a={});var f=$("#w2ui-popup").data(d);"undefined"!=typeof f&&null!=f?b(f,e):$.get(d,function(a,c,f){b(f.responseText,e),$("#w2ui-popup").data(d,f.responseText)})},message:function(a){$().w2tag(),a||(a={width:200,height:100}),parseInt(a.width)<10&&(a.width=10),parseInt(a.height)<10&&(a.height=10),"undefined"==typeof a.hideOnClick&&(a.hideOnClick=!1);var b=$("#w2ui-popup").data("options");("undefined"==typeof a.width||a.width>b.width-10)&&(a.width=b.width-10),("undefined"==typeof a.height||a.height>b.height-40)&&(a.height=b.height-40);var c=$("#w2ui-popup .w2ui-msg-title"),d=parseInt($("#w2ui-popup").width()),e=$("#w2ui-popup .w2ui-popup-message").length;if(""==$.trim(a.html)){$("#w2ui-popup #w2ui-message"+(e-1)).css("z-Index",250);var a=$("#w2ui-popup #w2ui-message"+(e-1)).data("options")||{};$("#w2ui-popup #w2ui-message"+(e-1)).remove(),"function"==typeof a.onClose&&a.onClose(),1==e?w2popup.unlock():$("#w2ui-popup #w2ui-message"+(e-2)).show()}else{$("#w2ui-popup .w2ui-popup-message").hide(),$("#w2ui-popup .w2ui-box1").before('"),$("#w2ui-popup #w2ui-message"+e).data("options",a);var f=$("#w2ui-popup #w2ui-message"+e).css("display");$("#w2ui-popup #w2ui-message"+e).css({"-webkit-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)","-moz-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)","-ms-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)","-o-transform":"none"==f?"translateY(-"+a.height+"px)":"translateY(0px)"}),"none"==f&&($("#w2ui-popup #w2ui-message"+e).show().html(a.html),setTimeout(function(){$("#w2ui-popup #w2ui-message"+e).css({"-webkit-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)","-moz-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)","-ms-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)","-o-transform":"none"==f?"translateY(0px)":"translateY(-"+a.height+"px)"})},1),setTimeout(function(){$("#w2ui-popup #w2ui-message"+e).css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s","z-Index":1500}),0==e&&w2popup.lock(),"function"==typeof a.onOpen&&a.onOpen()},300))}},lock:function(){var a=Array.prototype.slice.call(arguments,0);a.unshift($("#w2ui-popup")),w2utils.lock.apply(window,a)},unlock:function(){w2utils.unlock($("#w2ui-popup"))},lockScreen:function(a){return $("#w2ui-lock").length>0?!1:("undefined"==typeof a&&(a=$("#w2ui-popup").data("options")),"undefined"==typeof a&&(a={}),a=$.extend({},w2popup.defaults,a),$("body").append('
      '),setTimeout(function(){$("#w2ui-lock").css({"-webkit-transition":a.speed+"s opacity","-moz-transition":a.speed+"s opacity","-ms-transition":a.speed+"s opacity","-o-transition":a.speed+"s opacity",opacity:a.opacity})},1),1==a.modal?($("#w2ui-lock").on("mousedown",function(){$("#w2ui-lock").css({"-webkit-transition":".1s","-moz-transition":".1s","-ms-transition":".1s","-o-transition":".1s",opacity:"0.6"})}),$("#w2ui-lock").on("mouseup",function(){setTimeout(function(){$("#w2ui-lock").css({"-webkit-transition":".1s","-moz-transition":".1s","-ms-transition":".1s","-o-transition":".1s",opacity:a.opacity})},100)})):$("#w2ui-lock").on("mouseup",function(){w2popup.close()}),!0)},unlockScreen:function(a){return 0==$("#w2ui-lock").length?!1:("undefined"==typeof a&&(a=$("#w2ui-popup").data("options")),"undefined"==typeof a&&(a={}),a=$.extend({},w2popup.defaults,a),$("#w2ui-lock").css({"-webkit-transition":a.speed+"s opacity","-moz-transition":a.speed+"s opacity","-ms-transition":a.speed+"s opacity","-o-transition":a.speed+"s opacity",opacity:0}),setTimeout(function(){$("#w2ui-lock").remove()},1e3*a.speed),!0)},resize:function(a,b,c){var d=$("#w2ui-popup").data("options");parseInt($(window).width())-100&&"closing"!=w2popup.status?w2popup.message({width:400,height:150,html:'
      '+a+'
      ",onClose:function(){"function"==typeof c&&c()}}):w2popup.open({width:450,height:200,showMax:!1,title:b,body:'
      '+a+"
      ",buttons:'",onClose:function(){"function"==typeof c&&c()}})},w2confirm=function(a,b){var c=400,d=150,e="Yes",f="",g="",h="No",i="",j="",k=w2utils.lang("Confirmation");if(1==arguments.length&&"object"==typeof a){var l=w2utils.lang(a.msg),b=a.callBack,m=a.btn_yes,n=a.btn_no;a.title&&(k=w2utils.lang(a.title)),w2utils.isInt(a.width)&&(c=a.width),w2utils.isInt(a.height)&&(d=a.height),m&&(m.text&&(e=w2utils.lang(m.text)),m.class&&(f=m.class),m.style&&(g=m.style)),n&&(n.text&&(h=w2utils.lang(n.text)),n.class&&(i=n.class),n.style&&(j=n.style))}else var l=a;$("#w2ui-popup").length>0&&"closing"!=w2popup.status?(c>w2popup.get().width&&(c=w2popup.get().width),d>w2popup.get().height-50&&(d=w2popup.get().height-50),w2popup.message({width:c,height:d,html:'
      '+l+'
      ",onOpen:function(){$("#w2ui-popup .w2ui-popup-message .btn").on("click",function(a){w2popup.message(),"function"==typeof b&&b(a.target.id)})},onKeydown:function(a){switch(a.originalEvent.keyCode){case 13:"function"==typeof b&&b("Yes"),w2popup.message();break;case 27:"function"==typeof b&&b("No"),w2popup.message()}}})):(w2utils.isInt(a.height)||(d+=50),w2popup.open({width:c,height:d,title:k,modal:!0,showClose:!1,body:'
      '+l+"
      ",buttons:'",onOpen:function(a){a.onComplete=function(){$("#w2ui-popup .w2ui-popup-btn").on("click",function(a){w2popup.close(),"function"==typeof b&&b(a.target.id)})}},onKeydown:function(a){switch(a.originalEvent.keyCode){case 13:"function"==typeof b&&b("Yes"),w2popup.close();break;case 27:"function"==typeof b&&b("No"),w2popup.close()}}}))};!function(){var a=function(a){this.box=null,this.name=null,this.active=null,this.tabs=[],this.right="",this.style="",this.onClick=null,this.onClose=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(this,{handlers:[]}),$.extend(!0,this,w2obj.tabs,a)};$.fn.w2tabs=function(b){if("object"!=typeof b&&b){if(w2ui[$(this).attr("name")]){var c=w2ui[$(this).attr("name")];return c[b].apply(c,Array.prototype.slice.call(arguments,1)),this}return void console.log("ERROR: Method "+b+" does not exist on jQuery.w2tabs")}if(w2utils.checkName(b,"w2tabs")){for(var d=b.tabs||[],e=new a(b),f=0;f
      ":"")+'
      "+e.text+"
      ";if(0===f.length){var h="";e.hidden&&(h+="display: none;"),e.disabled&&(h+="opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);");var i='
      ";this.get(a,!0)!==this.tabs.length-1&&$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))+1].id)).length>0?$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))+1].id)).before(i):$(this.box).find("#tabs_"+this.name+"_right").before(i)}else f.html(g),e.hidden?f.css("display","none"):f.css("display",""),f.css(e.disabled?{opacity:"0.2","-moz-opacity":"0.2","-webkit-opacity":"0.2","-o-opacity":"0.2",filter:"alpha(opacity=20)"}:{opacity:"1","-moz-opacity":"1","-webkit-opacity":"1","-o-opacity":"1",filter:"alpha(opacity=100)"})}return $("#tabs_"+this.name+"_right").html(this.right),this.trigger($.extend(c,{phase:"after"})),(new Date).getTime()-b}},render:function(a){var b=(new Date).getTime(),c=this.trigger({phase:"before",type:"render",target:this.name,box:a});if(c.isCancelled!==!0){if("undefined"!=typeof a&&null!==a&&($(this.box).find("> table #tabs_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),this.box=a),!this.box)return!1;var d='
      '+(c!==!0?"
      "+b+"
      ":"")+"
      '+(c!==!0?'
      ":"")+"
      '+(c!==!0?'
      "+j+"
      ":"")+"
      "+n+"
      '+g+"
      '+this.right+"
      ";return $(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-tabs").html(d),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),this.trigger($.extend(c,{phase:"after"})),this.refresh(),(new Date).getTime()-b}},resize:function(){var a=(new Date).getTime(),b=this.trigger({phase:"before",type:"resize",target:this.name});return b.isCancelled!==!0?(this.trigger($.extend(b,{phase:"after"})),(new Date).getTime()-a):void 0},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});a.isCancelled!==!0&&($(this.box).find("> table #tabs_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})))},click:function(a,b){var c=this.get(a);if(null===c||c.disabled)return!1;var d=this.trigger({phase:"before",type:"click",target:a,tab:c,object:c,originalEvent:b});d.isCancelled!==!0&&($(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.active)+" .w2ui-tab").removeClass("active"),this.active=c.id,this.trigger($.extend(d,{phase:"after"})),this.refresh(a))},animateClose:function(a,b){var c=this.get(a);if(null===c||c.disabled)return!1;var d=this.trigger({phase:"before",type:"close",target:a,object:this.get(a),originalEvent:b});if(d.isCancelled!==!0){var e=this;$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(c.id)).css({"-webkit-transition":".2s","-moz-transition":"2s","-ms-transition":".2s","-o-transition":".2s",opacity:"0"}),setTimeout(function(){var a=$(e.box).find("#tabs_"+e.name+"_tab_"+w2utils.escapeId(c.id)).width();$(e.box).find("#tabs_"+e.name+"_tab_"+w2utils.escapeId(c.id)).html('
      '),setTimeout(function(){$(e.box).find("#tabs_"+e.name+"_tab_"+w2utils.escapeId(c.id)).find(":first-child").css({width:"0px"})},50)},200),setTimeout(function(){e.remove(a)},450),this.trigger($.extend(d,{phase:"after"})),this.refresh()}},animateInsert:function(a,b){if(null!==this.get(a)&&$.isPlainObject(b)&&w2utils.checkUniqueId(b.id,this.tabs,"tabs",this.name)){var c=$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(b.id));if(0===c.length){"undefined"!=typeof b.caption&&(b.text=b.caption);var d='
      '+(b.closable?'
      ':"")+'
      '+b.text+"
      ";$("body").append(d);var e='
       
      ',f="";b.hidden&&(f+="display: none;"),b.disabled&&(f+="opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);");var g=''+e+"";this.get(a,!0)!==this.tabs.length&&$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))].id)).length>0?$(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(a,!0))].id)).before(g):$(this.box).find("#tabs_"+this.name+"_right").before(g);var h=this;setTimeout(function(){var a=$("#_tmp_simple_tab").width();$("#_tmp_tabs").remove(),$("#tabs_"+h.name+"_tab_"+w2utils.escapeId(b.id)+" > div").css("width",a+"px")},1),setTimeout(function(){h.insert(a,b)},200)}}}},$.extend(a.prototype,w2utils.event),w2obj.tabs=a}(),function(){var a=function(a){this.box=null,this.name=null,this.items=[],this.right="",this.onClick=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(!0,this,w2obj.toolbar,a)};$.fn.w2toolbar=function(b){if("object"==typeof b||!b){if(!w2utils.checkName(b,"w2toolbar"))return;var c=b.items||[],d=new a(b);$.extend(d,{items:[],handlers:[]});for(var e=0;e table #tb_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),this.box=a),this.box)){for(var d='',e=0;e':'")}return d+='",d+="
      '+this.getItemHTML(f)+"'+this.right+"
      ",$(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-toolbar").html(d),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),this.trigger($.extend(c,{phase:"after"})),(new Date).getTime()-b}},refresh:function(a){var b=(new Date).getTime(),c=this.trigger({phase:"before",type:"refresh",target:"undefined"!=typeof a?a:this.name,item:this.get(a)});if(c.isCancelled!==!0){if(null==a)for(var d=0;d':''+h+"",this.get(a,!0)===this.items.length-1?$(this.box).find("#tb_"+this.name+"_right").before(h):$(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(this.items[parseInt(this.get(a,!0))+1].id)).before(h)):(g.html(h),f.hidden?g.css("display","none"):g.css("display",""),f.disabled?g.addClass("disabled"):g.removeClass("disabled")),this.trigger($.extend(c,{phase:"after"})),(new Date).getTime()-b}},resize:function(){var a=(new Date).getTime(),b=this.trigger({phase:"before",type:"resize",target:this.name});return b.isCancelled!==!0?(this.trigger($.extend(b,{phase:"after"})),(new Date).getTime()-a):void 0},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});a.isCancelled!==!0&&($(this.box).find("> table #tb_"+this.name+"_right").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),$(this.box).html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})))},getItemHTML:function(a){var b="";switch("undefined"!=typeof a.caption&&(a.text=a.caption),"undefined"==typeof a.hint&&(a.hint=""),"undefined"==typeof a.text&&(a.text=""),a.type){case"menu":case"button":case"check":case"radio":case"drop":var c=" ";a.img&&(c='
      '),a.icon&&(c='
      '),b+='
      '+c+(""!==a.text?'":"")+("drop"!==a.type&&"menu"!==a.type||a.arrow===!1?"":'')+"
      '+a.text+"
      ";break;case"break":b+='
       
      ';break;case"html":b+='
      '+a.html+"
      "}var d="";return"function"==typeof a.onRender&&(d=a.onRender.call(this,a.id,b)),"function"==typeof this.onRender&&(d=this.onRender(a.id,b)),""!==d&&null!=d&&(b=d),b},menuClick:function(a){if(a.item&&!a.item.disabled){var b=this.trigger({phase:"before",type:"click",target:a.item.id+":"+a.subItem.id,item:a.item,subItem:a.subItem,originalEvent:a.originalEvent});if(b.isCancelled===!0)return;this.trigger($.extend(b,{phase:"after"}))}},click:function(a,b){var c=this,d=this.get(a);if(d&&!d.disabled){var e=this.trigger({phase:"before",type:"click",target:"undefined"!=typeof a?a:this.name,item:d,object:d,originalEvent:b});if(e.isCancelled===!0)return;var f=$("#tb_"+this.name+"_item_"+w2utils.escapeId(d.id)+" table.w2ui-button");if(f.removeClass("down"),"radio"===d.type){for(var g=0;g19&&(e=19),"drop"===d.type&&b.w2overlay(d.html,$.extend({left:e,top:3},d.overlay)),"menu"===d.type&&b.w2menu(d.items,$.extend({left:e,top:3},d.overlay,{select:function(b){c.menuClick({item:d,subItem:b.item,originalEvent:b.originalEvent}),a()}})),$(document).on("click",a)},1)),("check"===d.type||"drop"===d.type||"menu"===d.type)&&(d.checked=!d.checked,d.checked?f.addClass("checked"):f.removeClass("checked")),this.trigger($.extend(e,{phase:"after"}))}}},$.extend(a.prototype,w2utils.event),w2obj.toolbar=a}(),function(){var a=function(a){this.name=null,this.box=null,this.sidebar=null,this.parent=null,this.nodes=[],this.menu=[],this.selected=null,this.img=null,this.icon=null,this.style="",this.topHTML="",this.bottomHTML="",this.keyboard=!0,this.onClick=null,this.onDblClick=null,this.onContextMenu=null,this.onMenuClick=null,this.onExpand=null,this.onCollapse=null,this.onKeydown=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,$.extend(!0,this,w2obj.sidebar,a)};$.fn.w2sidebar=function(b){if("object"==typeof b||!b){if(!w2utils.checkName(b,"w2sidebar"))return;var c=b.nodes,d=new a(b);return $.extend(d,{handlers:[],nodes:[]}),"undefined"!=typeof c&&d.add(d,c),0!==$(this).length&&d.render($(this)[0]),d.sidebar=d,w2ui[d.name]=d,d}if(w2ui[$(this).attr("name")]){var e=w2ui[$(this).attr("name")];return e[b].apply(e,Array.prototype.slice.call(arguments,1)),this}console.log("ERROR: Method "+b+" does not exist on jQuery.w2sidebar")},a.prototype={node:{id:null,text:"",count:null,img:null,icon:null,nodes:[],style:"",selected:!1,expanded:!1,hidden:!1,disabled:!1,group:!1,groupShowHide:!0,plus:!1,onClick:null,onDblClick:null,onContextMenu:null,onExpand:null,onCollapse:null,parent:null,sidebar:null},add:function(a,b){return 1==arguments.length&&(b=arguments[0],a=this),"string"==typeof a&&(a=this.get(a)),this.insert(a,null,b)},insert:function(b,c,d){var e,f,g,h,i;if(2==arguments.length){if(d=arguments[1],c=arguments[0],f=this.get(c),null===f)return $.isArray(d)||(d=[d]),e=null!=d[0].caption?d[0].caption:d[0].text,console.log('ERROR: Cannot insert node "'+e+'" because cannot find node "'+c+'" to insert before.'),null;b=this.get(c).parent}"string"==typeof b&&(b=this.get(b)),$.isArray(d)||(d=[d]);for(var j in d)if(h=d[j],null!=typeof h.id)if(null===this.get(this,h.id)){if(g=$.extend({},a.prototype.node,h),g.sidebar=this,g.parent=b,i=g.nodes||[],g.nodes=[],null===c)b.nodes.push(g);else{if(f=this.get(b,c,!0),null===f)return e=null!=h.caption?h.caption:h.text,console.log('ERROR: Cannot insert node "'+e+'" because cannot find node "'+c+'" to insert before.'),null;b.nodes.splice(f,0,g)}i.length>0&&this.insert(g,null,i)}else e=null!=h.caption?h.caption:h.text,console.log("ERROR: Cannot insert node with id="+h.id+" (text: "+e+") because another node with the same id already exists.");else e=null!=h.caption?h.caption:h.text,console.log('ERROR: Cannot insert node "'+e+'" because it has no id.');return this.refresh(b.id),g},remove:function(){for(var a,b=0,c=0;c0&&1==arguments.length?this.refresh(a.parent.id):this.refresh(),b},set:function(a,b,c){if(2==arguments.length&&(c=b,b=a,a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return null;for(var d=0;d0&&(c=this.find(a.nodes[d],b,c))}return c},hide:function(){for(var a=0,b=0;b+
      '),c.expanded=!1,this.trigger($.extend(d,{phase:"after"})),setTimeout(function(){b.refresh(a)},200),!0):void 0},collapseAll:function(a){if("undefined"==typeof a&&(a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return!1;for(var b=0;b0&&this.collapseAll(a.nodes[b]);return this.refresh(a.id),!0},expand:function(a){var b=this,c=this.get(a),d=this.trigger({phase:"before",type:"expand",target:a,object:c});return d.isCancelled!==!0?($(this.box).find("#node_"+w2utils.escapeId(a)+"_sub").slideDown(200),$(this.box).find("#node_"+w2utils.escapeId(a)+" .w2ui-node-dots:first-child").html('
      -
      '),c.expanded=!0,this.trigger($.extend(d,{phase:"after"})),setTimeout(function(){b.refresh(a)},200),!0):void 0},expandAll:function(a){if("undefined"==typeof a&&(a=this),"string"==typeof a&&(a=this.get(a)),null==a.nodes)return!1;for(var b=0;b0&&this.collapseAll(a.nodes[b]);this.refresh(a.id)},expandParents:function(a){var b=this.get(a);return null===b?!1:(b.parent&&(b.parent.expanded=!0,this.expandParents(b.parent.id)),this.refresh(a),!0)},click:function(a,b){var c=this,d=this.get(a);if(null!==d&&!d.disabled&&!d.group){$(c.box).find(".w2ui-node.w2ui-selected").each(function(a,b){var d=$(b).attr("id").replace("node_",""),e=c.get(d);null!=e&&(e.selected=!1),$(b).removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected")});var e=$(c.box).find("#node_"+w2utils.escapeId(a)),f=$(c.box).find("#node_"+w2utils.escapeId(c.selected));e.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected"),setTimeout(function(){var g=c.trigger({phase:"before",type:"click",target:a,originalEvent:b,node:d,object:d});return g.isCancelled===!0?(e.removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected"),void f.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected")):(null!==f&&(f.selected=!1),c.get(a).selected=!0,c.selected=a,void c.trigger($.extend(g,{phase:"after"})))},1)}},keydown:function(a){function b(a,b){null===a||a.hidden||a.disabled||a.group||(g.click(a.id,b),setTimeout(function(){g.scrollIntoView()},50))}function c(a,b){for(a=b(a);null!==a&&(a.hidden||a.disabled)&&!a.group;)a=b(a);return a}function d(a,b){if(null===a)return null;var c=a.parent,e=g.get(a.id,!0),f=null;if(a.expanded&&a.nodes.length>0&&b!==!0){var h=a.nodes[0];f=h.hidden||h.disabled||h.group?d(h):h}else f=c&&e+10?f(b.nodes[c-1]):b;return null!==d&&(d.hidden||d.disabled||d.group)&&(d=e(d)),d}function f(a){if(a.expanded&&a.nodes.length>0){var b=a.nodes[a.nodes.length-1];return b.hidden||b.disabled||b.group?e(b):f(b)}return a}var g=this,h=g.get(g.selected);if(h&&g.keyboard===!0){var i=g.trigger({phase:"before",type:"keydown",target:g.name,originalEvent:a});i.isCancelled!==!0&&((13==a.keyCode||32==a.keyCode)&&h.nodes.length>0&&g.toggle(g.selected),37==a.keyCode&&(h.nodes.length>0&&h.expanded?g.collapse(g.selected):(b(h.parent),h.parent.group||g.collapse(h.parent.id))),39==a.keyCode&&(h.nodes.length>0||h.plus)&&!h.expanded&&g.expand(g.selected),38==a.keyCode&&b(c(h,e)),40==a.keyCode&&b(c(h,d)),-1!=$.inArray(a.keyCode,[13,32,37,38,39,40])&&(a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation()),g.trigger($.extend(i,{phase:"after"})))}},scrollIntoView:function(a){"undefined"==typeof a&&(a=this.selected);var b=this.get(a);if(null!==b){var c=$(this.box).find(".w2ui-sidebar-div"),d=$(this.box).find("#node_"+w2utils.escapeId(a)),e=d.offset().top-c.offset().top;e+d.height()>c.height()&&c.animate({scrollTop:c.scrollTop()+c.height()/1.3},250,"linear"),0>=e&&c.animate({scrollTop:c.scrollTop()-c.height()/1.3},250,"linear")}},dblClick:function(a,b){var c=this.get(a),d=this.trigger({phase:"before",type:"dblClick",target:a,originalEvent:b,object:c});d.isCancelled!==!0&&(this.toggle(a),this.trigger($.extend(d,{phase:"after"})))},contextMenu:function(a,b){var c=this,d=c.get(a);a!=c.selected&&c.click(a),setTimeout(function(){var e=c.trigger({phase:"before",type:"contextMenu",target:a,originalEvent:b,object:d});e.isCancelled!==!0&&(d.group||d.disabled||(c.menu.length>0&&$(c.box).find("#node_"+w2utils.escapeId(a)).w2menu(c.menu,{left:(b?b.offsetX||b.pageX:50)-25,onSelect:function(b){c.menuClick(a,parseInt(b.index),b.originalEvent)}}),c.trigger($.extend(e,{phase:"after"}))))},150)},menuClick:function(a,b,c){var d=this,e=d.trigger({phase:"before",type:"menuClick",target:a,originalEvent:c,menuIndex:b,menuItem:d.menu[b]});e.isCancelled!==!0&&d.trigger($.extend(e,{phase:"after"}))},render:function(a){var b=(new Date).getTime(),c=this.trigger({phase:"before",type:"render",target:this.name,box:a});return c.isCancelled!==!0&&("undefined"!=typeof a&&null!==a&&($(this.box).find("> div > div.w2ui-sidebar-div").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),this.box=a),this.box)?($(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-sidebar").html('
      '),$(this.box).find("> div").css({width:$(this.box).width()+"px",height:$(this.box).height()+"px"}),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),""!==this.topHTML&&($(this.box).find(".w2ui-sidebar-top").html(this.topHTML),$(this.box).find(".w2ui-sidebar-div").css("top",$(this.box).find(".w2ui-sidebar-top").height()+"px")),""!==this.bottomHTML&&($(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),$(this.box).find(".w2ui-sidebar-div").css("bottom",$(this.box).find(".w2ui-sidebar-bottom").height()+"px")),this.trigger($.extend(c,{phase:"after"})),this.refresh(),(new Date).getTime()-b):void 0},refresh:function(a){function b(a){var b="",c=a.img;null===c&&(c=this.img);var d=a.icon;null===d&&(d=this.icon);for(var e=a.parent,f=0;e&&null!==e.parent;)e.group&&f--,e=e.parent,f++;return"undefined"!=typeof a.caption&&(a.text=a.caption),a.group?b='
      "+(a.groupShowHide?""+w2utils.lang(!a.hidden&&a.expanded?"Hide":"Show")+"":"")+" "+a.text+'
      ':(a.selected&&!a.disabled&&(h.selected=a.id),e="",c&&(e='
      '),d&&(e='
      '),b='
      '+(a.nodes.length>0?a.expanded?"-":"+":a.plus?"+":"")+'
      '+e+(a.count||0===a.count?'
      '+a.count+"
      ":"")+'
      '+a.text+'
      '),b}var c=(new Date).getTime(),d=this.trigger({phase:"before",type:"refresh",target:"undefined"!=typeof a?a:this.name});if(d.isCancelled!==!0){""!==this.topHTML&&($(this.box).find(".w2ui-sidebar-top").html(this.topHTML),$(this.box).find(".w2ui-sidebar-div").css("top",$(this.box).find(".w2ui-sidebar-top").height()+"px")),""!==this.bottomHTML&&($(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),$(this.box).find(".w2ui-sidebar-div").css("bottom",$(this.box).find(".w2ui-sidebar-bottom").height()+"px")),$(this.box).find("> div").css({width:$(this.box).width()+"px",height:$(this.box).height()+"px"});var e,f,g,h=this;if("undefined"==typeof a)e=this,g=".w2ui-sidebar-div";else{if(e=this.get(a),null===e)return;g="#node_"+w2utils.escapeId(e.id)+"_sub"}var i;if(e!==this){var j="#node_"+w2utils.escapeId(e.id);i=b(e),$(this.box).find(j).before(''),$(this.box).find(j).remove(),$(this.box).find(g).remove(),$("#sidebar_"+this.name+"_tmp").before(i),$("#sidebar_"+this.name+"_tmp").remove()}$(this.box).find(g).html("");for(var k=0;k div").css({width:$(this.box).width()+"px",height:$(this.box).height()+"px"}),this.trigger($.extend(b,{phase:"after"})),(new Date).getTime()-a):void 0},destroy:function(){var a=this.trigger({phase:"before",type:"destroy",target:this.name});a.isCancelled!==!0&&($(this.box).find("> div > div.w2ui-sidebar-div").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),delete w2ui[this.name],this.trigger($.extend(a,{phase:"after"})))},lock:function(){var a=$(this.box).find("> div:first-child"),b=Array.prototype.slice.call(arguments,0);b.unshift(a),w2utils.lock.apply(window,b)},unlock:function(){w2utils.unlock(this.box)}},$.extend(a.prototype,w2utils.event),w2obj.sidebar=a}(),function(a){var b=function(b){this.el=null,this.helpers={},this.type=b.type||"text",this.options=a.extend(!0,{},b),this.onSearch=b.onSearch||null,this.onRequest=b.onRequest||null,this.onLoad=b.onLoad||null,this.onError=b.onError||null,this.onClick=b.onClick||null,this.onAdd=b.onAdd||null,this.onNew=b.onNew||null,this.onRemove=b.onRemove||null,this.onMouseOver=b.onMouseOver||null,this.onMouseOut=b.onMouseOut||null,this.onIconClick=b.onIconClick||null,this.tmp={},delete this.options.type,delete this.options.onSearch,delete this.options.onRequest,delete this.options.onLoad,delete this.options.onError,delete this.options.onClick,delete this.options.onMouseOver,delete this.options.onMouseOut,delete this.options.onIconClick,a.extend(!0,this,w2obj.field)};a.fn.w2field=function(c,d){if(0!=this.length)return"string"==typeof c&&"object"==typeof d&&(c=a.extend(!0,{},d,{type:c})),"string"==typeof c&&"undefined"==typeof d&&(c={type:c}),c.type=String(c.type).toLowerCase(),this.each(function(d,e){var f=a(e).data("w2field");if("undefined"==typeof f){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}if(f.clear(),"clear"!=c.type){var f=new b(c);return a.extend(f,{handlers:[]}),e&&(f.el=a(e)[0]),f.init(),a(e).data("w2field",f),f}});var e=b.prototype;return e[c]?e[c].apply(e,Array.prototype.slice.call(arguments,1)):void 0},b.prototype={custom:{},pallete:[["000000","444444","666666","999999","CCCCCC","EEEEEE","F3F3F3","FFFFFF"],["FF011B","FF9838","FFFD59","01FD55","00FFFE","0424F3","9B24F4","FF21F5"],["F4CCCC","FCE5CD","FFF2CC","D9EAD3","D0E0E3","CFE2F3","D9D1E9","EAD1DC"],["EA9899","F9CB9C","FEE599","B6D7A8","A2C4C9","9FC5E8","B4A7D6","D5A6BD"],["E06666","F6B26B","FED966","93C47D","76A5AF","6FA8DC","8E7CC3","C27BA0"],["CC0814","E69138","F1C232","6AA84F","45818E","3D85C6","674EA7","A54D79"],["99050C","B45F17","BF901F","37761D","124F5C","0A5394","351C75","741B47"],["660205","783F0B","7F6011","274E12","0C343D","063762","20124D","4C1030"]],addType:function(a,b){return a=String(a).toLowerCase(),this.custom[a]=b,!0},removeType:function(a){return a=String(a).toLowerCase(),this.custom[a]?(delete this.custom[a],!0):!1},init:function(){var b,c=this,d=this.options;if("function"==typeof this.custom[this.type])return void this.custom[this.type].call(this,d);if(-1==["INPUT","TEXTAREA"].indexOf(this.el.tagName))return void console.log("ERROR: w2field could only be applied to INPUT or TEXTAREA.",this.el);switch(this.type){case"text":case"int":case"float":case"money":case"currency":case"percent":case"alphanumeric":case"hex":b={min:null,max:null,step:1,placeholder:"",autoFormat:!0,currencyPrefix:w2utils.settings.currencyPrefix,currencySuffix:w2utils.settings.currencySuffix,currencyPrecision:w2utils.settings.currencyPrecision,groupSymbol:w2utils.settings.groupSymbol,arrows:!1,keyboard:!0,precision:null,silent:!0,prefix:"",suffix:""},this.options=a.extend(!0,{},b,d),d=this.options,d.numberRE=new RegExp("["+d.groupSymbol+"]","g"),d.moneyRE=new RegExp("["+d.currencyPrefix+d.currencySuffix+d.groupSymbol+"]","g"),d.percentRE=new RegExp("["+d.groupSymbol+"%]","g"),-1!=["text","alphanumeric","hex"].indexOf(this.type)&&(d.arrows=!1,d.keyboard=!1),this.addPrefix(),this.addSuffix(),a(this.el).attr("placeholder",d.placeholder);break;case"color":b={prefix:"#",suffix:'
       
      ',placeholder:"",arrows:!1,keyboard:!1},a.extend(d,b),this.addPrefix(),this.addSuffix(),a(this.el).attr("maxlength",6),""!=a(this.el).val()&&setTimeout(function(){a(c.el).change()},1),a(this.el).attr("placeholder",d.placeholder);break;case"date":b={format:w2utils.settings.date_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:"",blocked:{},colored:{}},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:d.format);break;case"time":b={format:w2utils.settings.time_format,placeholder:"",keyboard:!0,silent:!0,start:"",end:""},this.options=a.extend(!0,{},b,d),d=this.options,a(this.el).attr("placeholder",d.placeholder?d.placeholder:"h12"==d.format?"hh:mi pm":"hh:mi");break;case"datetime":break;case"list":case"combo":if(b={items:[],selected:{},placeholder:"",url:null,postData:{},minLength:1,cacheMax:250,maxDropHeight:350,match:"begins",silent:!0,icon:null,iconStyle:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onIconClick:null,renderDrop:null,prefix:"",suffix:"",openOnFocus:!1,markSearch:!1},"list"==this.type&&(b.openOnFocus=!0,b.suffix='
      ',a(this.el).addClass("w2ui-select"),!a.isPlainObject(d.selected)))for(var e in d.items){var f=d.items[e];if(f&&f.id==d.selected){d.selected=a.extend(!0,{},f);break}}d=a.extend({},b,d,{align:"both",altRows:!0}),d.items=this.normMenu(d.items),this.options=d,a.isPlainObject(d.selected)||(d.selected={}),a(this.el).data("selected",d.selected),d.url&&this.request(0),d.icon&&(d.prefix=''),"list"==this.type&&this.addFocus(),this.addPrefix(),this.addSuffix(),setTimeout(function(){c.refresh()},10),a(this.el).attr("placeholder",d.placeholder).attr("autocomplete","off"),"undefined"!=typeof d.selected.text&&a(this.el).val(d.selected.text);break;case"enum":b={items:[],selected:[],placeholder:"",max:0,url:null,postData:{},minLength:1,cacheMax:250,maxWidth:250,maxHeight:350,maxDropHeight:350,match:"contains",silent:!0,openOnFocus:!1,markSearch:!0,renderDrop:null,renderItem:null,style:"",onSearch:null,onRequest:null,onLoad:null,onError:null,onClick:null,onAdd:null,onNew:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",suffix:"",altRows:!0}),d.items=this.normMenu(d.items),d.selected=this.normMenu(d.selected),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),d.url&&this.request(0),this.addSuffix(),this.addMulti();break;case"file":b={selected:[],placeholder:w2utils.lang("Attach files by dragging and dropping or Click to Select"),max:0,maxSize:0,maxFileSize:0,maxWidth:250,maxHeight:350,maxDropHeight:350,silent:!0,renderItem:null,style:"",onClick:null,onAdd:null,onRemove:null,onMouseOver:null,onMouseOut:null},d=a.extend({},b,d,{align:"both",altRows:!0}),this.options=d,a.isArray(d.selected)||(d.selected=[]),a(this.el).data("selected",d.selected),this.addMulti()}this.tmp={onChange:function(a){c.change.call(c,a)},onClick:function(a){c.click.call(c,a)},onFocus:function(a){c.focus.call(c,a)},onBlur:function(a){c.blur.call(c,a)},onKeydown:function(a){c.keyDown.call(c,a)},onKeyup:function(a){c.keyUp.call(c,a)},onKeypress:function(a){c.keyPress.call(c,a)}},a(this.el).addClass("w2field").data("w2field",this).on("change",this.tmp.onChange).on("click",this.tmp.onClick).on("focus",this.tmp.onFocus).on("blur",this.tmp.onBlur).on("keydown",this.tmp.onKeydown).on("keyup",this.tmp.onKeyup).on("keypress",this.tmp.onKeypress).css({"box-sizing":"border-box","-webkit-box-sizing":"border-box","-moz-box-sizing":"border-box","-ms-box-sizing":"border-box","-o-box-sizing":"border-box"}),this.change(a.Event("change"))},clear:function(){var b=this.options;-1!=["money","currency"].indexOf(this.type)&&a(this.el).val(a(this.el).val().replace(b.moneyRE,"")),"percent"==this.type&&a(this.el).val(a(this.el).val().replace(/%/g,"")),"color"==this.type&&a(this.el).removeAttr("maxlength"),"list"==this.type&&a(this.el).removeClass("w2ui-select"),this.type="clear";var c=a(this.el).data("tmp");if(this.tmp){"undefined"!=typeof c&&(c&&c["old-padding-left"]&&a(this.el).css("padding-left",c["old-padding-left"]),c&&c["old-padding-right"]&&a(this.el).css("padding-right",c["old-padding-right"])),a(this.el).val(this.clean(a(this.el).val())).removeClass("w2field").removeData().off("change",this.tmp.onChange).off("click",this.tmp.onClick).off("focus",this.tmp.onFocus).off("blur",this.tmp.onBlur).off("keydown",this.tmp.onKeydown).off("keyup",this.tmp.onKeyup).off("keypress",this.tmp.onKeypress);for(var d in this.helpers)a(this.helpers[d]).remove();this.helpers={}}},refresh:function(){var b=this,c=this.options,d=a(this.el).data("selected"),e=(new Date).getTime();if(-1!=["list"].indexOf(this.type)&&(a(b.el).parent().css("white-space","nowrap"),b.helpers.prefix&&b.helpers.prefix.hide(),setTimeout(function(){var c=b.helpers.focus.find("input");""==a(c).val()?(a(c).css("opacity",0).prev().css("opacity",0),a(b.el).val(d&&null!=d.text?d.text:""),a(b.el).attr("placeholder",a(b.el).attr("_placeholder")),a.isEmptyObject(d)?b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide():b.helpers&&b.helpers.prefix&&b.helpers.prefix.show()):(a(c).css("opacity",1).prev().css("opacity",1),b.helpers&&b.helpers.prefix&&b.helpers.prefix.hide(),a(b.el).val(""),a(b.el).attr("_placeholder",a(b.el).attr("placeholder")).removeAttr("placeholder"))},1)),-1!=["enum","file"].indexOf(this.type)){var f="";for(var g in d){var h=d[g],i="";i="function"==typeof c.renderItem?c.renderItem(h,g,'
        
      '):'
        
      '+("enum"==b.type?h.text:h.name+' - '+w2utils.size(h.size)+""),f+='
    • '+i+"
    • " +}var j=b.helpers.multi,k=j.find("ul");if(j.attr("style",j.attr("style")+";"+c.style),a(b.el).attr("readonly")?j.addClass("w2ui-readonly"):j.removeClass("w2ui-readonly"),j.find(".w2ui-enum-placeholder").remove(),k.find("li").not("li.nomouse").remove(),""!=f)k.prepend(f);else if("undefined"!=typeof c.placeholder){var l="padding-top: "+a(this.el).css("padding-top")+";padding-left: "+a(this.el).css("padding-left")+"; box-sizing: "+a(this.el).css("box-sizing")+"; line-height: "+a(this.el).css("line-height")+"; font-size: "+a(this.el).css("font-size")+"; font-family: "+a(this.el).css("font-family")+"; ";j.prepend('
      '+c.placeholder+"
      ")}j.find("li").data("mouse","out").on("click",function(c){var e=d[a(c.target).attr("index")];if(!a(c.target).hasClass("nomouse")){c.stopPropagation();var f=b.trigger({phase:"before",type:"click",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled!==!0){if(a(c.target).hasClass("w2ui-list-remove")){if(a(b.el).attr("readonly"))return;var f=b.trigger({phase:"before",type:"remove",target:b.el,originalEvent:c.originalEvent,item:e});if(f.isCancelled===!0)return;a().w2overlay(),d.splice(a(c.target).attr("index"),1),a(b.el).trigger("change"),a(c.target).parent().fadeOut("fast"),setTimeout(function(){b.refresh(),b.trigger(a.extend(f,{phase:"after"}))},300)}if("file"==b.type&&!a(c.target).hasClass("w2ui-list-remove")){var g="";/image/i.test(e.type)&&(g='
      ');var h='style="padding: 3px; text-align: right; color: #777;"',i='style="padding: 3px"';g+='
      Name:"+e.name+"
      Size:"+w2utils.size(e.size)+"
      Type: '+e.type+"
      Modified:"+w2utils.date(e.modified)+"
      ",a(c.target).w2overlay(g)}b.trigger(a.extend(f,{phase:"after"}))}}}).on("mouseover",function(c){var e=c.target;if("LI"!=e.tagName&&(e=e.parentNode),!a(e).hasClass("nomouse")){if("out"==a(e).data("mouse")){var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"mouseOver",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}a(e).data("mouse","over")}}).on("mouseout",function(c){var e=c.target;"LI"!=e.tagName&&(e=e.parentNode),a(e).hasClass("nomouse")||(a(e).data("mouse","leaving"),setTimeout(function(){if("leaving"==a(e).data("mouse")){a(e).data("mouse","out");var f=d[a(e).attr("index")],g=b.trigger({phase:"before",type:"f",target:b.el,originalEvent:c.originalEvent,item:f});if(g.isCancelled===!0)return;b.trigger(a.extend(g,{phase:"after"}))}},0))}),a(this.el).height("auto");var m=a(j).find("> div").height()+2*w2utils.getSize(j,"+height");26>m&&(m=26),m>c.maxHeight&&(m=c.maxHeight),j.length>0&&(j[0].scrollTop=1e3);var n=w2utils.getSize(a(this.el),"height")-2;n>m&&(m=n),a(j).css({height:m+"px",overflow:m==c.maxHeight?"auto":"hidden"}),mc.max&&(b=c.max,a(this.el).val(c.max))),b=""!==b&&w2utils.isFloat(b)?Number(b):""),b},format:function(a){var b=this.options;if(b.autoFormat&&""!=a)switch(this.type){case"money":case"currency":a=w2utils.formatNumber(Number(a).toFixed(b.currencyPrecision),b.groupSymbol),""!=a&&(a=b.currencyPrefix+a+b.currencySuffix);break;case"percent":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol),""!=a&&(a+="%");break;case"float":a=w2utils.formatNumber(b.precision?Number(a).toFixed(b.precision):a,b.groupSymbol);break;case"int":a=w2utils.formatNumber(a,b.groupSymbol)}return a},change:function(b){{var c=this;c.options}if(-1!=["int","float","money","currency","percent"].indexOf(this.type)){var d=a(this.el).val(),e=this.format(this.clean(a(this.el).val()));if(""!=d&&d!=e)return a(this.el).val(e).change(),b.stopPropagation(),b.preventDefault(),!1}if("color"==this.type){var f="#"+a(this.el).val();6!=a(this.el).val().length&&3!=a(this.el).val().length&&(f=""),a(this.el).next().find("div").css("background-color",f),a(c.el).is(":focus")&&this.updateOverlay()}},click:function(b){b.stopPropagation(),-1!=["list","combo","enum"].indexOf(this.type)&&(a(this.el).is(":focus")||this.focus(b)),-1!=["date","time","color"].indexOf(this.type)&&this.updateOverlay()},focus:function(){{var b=this;this.options}if(-1!==["color","date","time"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){b.updateOverlay()},150)}if(-1!=["list","combo","enum"].indexOf(b.type)){if(a(b.el).attr("readonly"))return;a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),setTimeout(function(){return"list"==b.type&&a(b.el).is(":focus")?void a(b.helpers.focus).find("input").focus():(b.search(),void setTimeout(function(){b.updateOverlay()},1))},1)}"file"==b.type&&a(b.helpers.multi).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"})},blur:function(){var b=this,c=b.options,d=a(b.el).val().trim();-1!=["color","date","time","list","combo","enum"].indexOf(b.type)&&a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),-1!=["int","float","money","currency","percent"].indexOf(b.type)&&(""===d||b.checkType(d)||(a(b.el).val("").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid number"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),-1!=["date","time"].indexOf(b.type)&&(w2utils.isInt(b.el.value)&&a(b.el).val(w2utils.formatDate(new Date(parseInt(b.el.value)),c.format)).change(),""===d||b.inRange(b.el.value)?("date"!=b.type||""===d||w2utils.isDate(b.el.value,c.format)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid date"),setTimeout(function(){a(b.el).w2tag("")},3e3))),"time"!=b.type||""===d||w2utils.isTime(b.el.value)||(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not a valid time"),setTimeout(function(){a(b.el).w2tag("")},3e3)))):(a(b.el).val("").removeData("selected").change(),c.silent===!1&&(a(b.el).w2tag("Not in range"),setTimeout(function(){a(b.el).w2tag("")},3e3)))),"enum"==b.type&&a(b.helpers.multi).find("input").val("").width(20),"file"==b.type&&a(b.helpers.multi).css({outline:"none"})},keyPress:function(a){{var b=this;b.options}if(-1!=["int","float","money","currency","percent","hex","color","alphanumeric"].indexOf(b.type)){if(a.metaKey||a.ctrlKey||a.altKey||a.charCode!=a.keyCode&&a.keyCode>0)return;var c=String.fromCharCode(a.charCode);if(!b.checkType(c,!0)&&13!=a.keyCode)return a.preventDefault(),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,!1}-1!=["date","time"].indexOf(b.type)&&setTimeout(function(){b.updateOverlay()},1)},keyDown:function(b,c){var d=this,e=d.options,f=b.keyCode||c&&c.keyCode;if(-1!=["int","float","money","currency","percent"].indexOf(d.type)){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,h=parseFloat(a(d.el).val().replace(e.moneyRE,""))||0,i=e.step;switch((b.ctrlKey||b.metaKey)&&(i=10),f){case 38:if(b.shiftKey)break;a(d.el).val(h+i<=e.max||null===e.max?Number((h+i).toFixed(12)):e.max).change(),g=!0;break;case 40:if(b.shiftKey)break;a(d.el).val(h-i>=e.min||null===e.min?Number((h-i).toFixed(12)):e.min).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("date"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,j=864e5,i=1;(b.ctrlKey||b.metaKey)&&(i=10),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatDate(new Date(parseInt(d.el.value)),e.format)).change();var k=w2utils.isDate(a(d.el).val(),e.format,!0);switch(k||(k=new Date,j=0),f){case 38:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()+j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()+1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0;break;case 40:if(b.shiftKey)break;var l=w2utils.formatDate(k.getTime()-j,e.format);10==i&&(l=w2utils.formatDate(new Date(k.getFullYear(),k.getMonth()-1,k.getDate()),e.format)),a(d.el).val(l).change(),g=!0}g&&(b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length),d.updateOverlay()},0))}if("time"==d.type){if(!e.keyboard||a(d.el).attr("readonly"))return;var g=!1,i=1;(b.ctrlKey||b.metaKey)&&(i=60),w2utils.isInt(d.el.value)&&a(d.el).val(w2utils.formatTime(new Date(parseInt(d.el.value)),e.format)).change();var h=a(d.el).val(),m=d.toMin(h)||d.toMin((new Date).getHours()+":"+((new Date).getMinutes()-1));switch(f){case 38:if(b.shiftKey)break;m+=i,g=!0;break;case 40:if(b.shiftKey)break;m-=i,g=!0}g&&(a(d.el).val(d.fromMin(m)).change(),b.preventDefault(),setTimeout(function(){d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0))}if("color"==d.type){if(a(d.el).attr("readonly"))return;if(86==b.keyCode&&(b.ctrlKey||b.metaKey)&&(a(d.el).prop("maxlength",7),setTimeout(function(){var b=a(d).val();"#"==b.substr(0,1)&&(b=b.substr(1)),w2utils.isHex(b)||(b=""),a(d).val(b).prop("maxlength",6).change()},20)),(b.ctrlKey||b.metaKey)&&!b.shiftKey){if("undefined"==typeof d.tmp.cind1)d.tmp.cind1=-1,d.tmp.cind2=-1;else{switch(f){case 38:d.tmp.cind1--;break;case 40:d.tmp.cind1++;break;case 39:d.tmp.cind2++;break;case 37:d.tmp.cind2--}d.tmp.cind1<0&&(d.tmp.cind1=0),d.tmp.cind1>this.pallete.length-1&&(d.tmp.cind1=this.pallete.length-1),d.tmp.cind2<0&&(d.tmp.cind2=0),d.tmp.cind2>this.pallete[0].length-1&&(d.tmp.cind2=this.pallete[0].length-1)}-1!=[37,38,39,40].indexOf(f)&&(a(d.el).val(this.pallete[d.tmp.cind1][d.tmp.cind2]).change(),b.preventDefault())}}if(-1!=["list","combo","enum"].indexOf(d.type)){if(a(d.el).attr("readonly"))return;var g=!1,n=a(d.el).data("selected"),o=a(d.helpers.focus).find("input");switch("list"==d.type&&-1==[37,38,39,40].indexOf(f)&&d.refresh(),f){case 27:"list"==d.type&&(""==a(o).val()?a(d.el).data("selected",{}):a(o).val(""),d.refresh(),b.stopPropagation());break;case 37:case 39:break;case 13:if(0==a("#w2ui-overlay").length)break;var p=e.items[e.index],q=a(d.helpers.multi).find("input");if("enum"==d.type)if(null!=p){var r=d.trigger({phase:"before",type:"add",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,n.length>=e.max&&e.max>0&&n.pop(),delete p.hidden,delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}else{p={id:q.val(),text:q.val()};var r=d.trigger({phase:"before",type:"new",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;p=r.item,"function"==typeof d.onNew&&(n.length>=e.max&&e.max>0&&n.pop(),delete d.tmp.force_open,n.push(p),a(d.el).change(),q.val("").width(20),d.refresh()),d.trigger(a.extend(r,{phase:"after"}))}else p&&a(d.el).data("selected",p).val(p.text).change(),""==a(d.el).val()&&a(d.el).data("selected")&&a(d.el).removeData("selected").val("").change(),"list"==d.type&&(o.val(""),d.refresh()),d.tmp.force_hide=!0;break;case 8:if(-1!=["enum"].indexOf(d.type)&&""==a(d.helpers.multi).find("input").val()&&n.length>0){var p=n[n.length-1],r=d.trigger({phase:"before",type:"remove",target:d.el,originalEvent:b.originalEvent,item:p});if(r.isCancelled===!0)return;n.pop(),a(d.el).trigger("change"),d.refresh(),d.trigger(a.extend(r,{phase:"after"}))}break;case 38:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):0,e.index--;e.index>0&&e.items[e.index].hidden;)e.index--;if(0==e.index&&e.items[e.index].hidden)for(;e.items[e.index]&&e.items[e.index].hidden;)e.index++;g=!0;break;case 40:for(e.index=w2utils.isInt(e.index)?parseInt(e.index):-1,e.index++;e.index=e.items.length&&(e.index=e.items.length-1),d.updateOverlay(),b.preventDefault(),void setTimeout(function(){if("enum"==d.type){var a=d.helpers.multi.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else if("list"==d.type){var a=d.helpers.focus.find("input").get(0);a.setSelectionRange(a.value.length,a.value.length)}else d.el.setSelectionRange(d.el.value.length,d.el.value.length)},0);if("enum"==d.type){var s=d.helpers.multi.find("input"),t=s.val();s.width(8*(t.length+2)+"px")}-1==[16,17,18,20,37,39,91].indexOf(f)&&setTimeout(function(){d.tmp.force_hide||d.request(),d.search()},1)}},keyUp:function(b){"color"==this.type&&86==b.keyCode&&(b.ctrlKey||b.metaKey)&&a(this).prop("maxlength",6)},clearCache:function(){var a=this.options;a.items=[],this.tmp.xhr_loading=!1,this.tmp.xhr_search="",this.tmp.xhr_total=-1,this.search()},request:function(b){var c=this,d=this.options,e=a(c.el).val()||"";if(d.url){if("enum"==c.type){var f=a(c.helpers.multi).find("input");e=0==f.length?"":f.val()}if("list"==c.type){var f=a(c.helpers.focus).find("input");e=0==f.length?"":f.val()}if(0!=d.minLength&&e.lengthc.tmp.xhr_search.length||e.length>=c.tmp.xhr_search.length&&e.substr(0,c.tmp.xhr_search.length)!=c.tmp.xhr_search||e.lengthd.cacheMax&&b.items.splice(d.cacheMax,1e5),c.tmp.xhr_loading=!1,c.tmp.xhr_search=e,c.tmp.xhr_total=b.items.length,d.items=b.items,c.tmp.emptySet=""==e&&0==b.items.length?!0:!1,c.search(),c.trigger(a.extend(i,{phase:"after"}))}}).error(function(b,d,f){var g={status:d,exceptionThrown:f,rawResponseText:b.responseText},h=c.trigger({phase:"before",type:"error",target:c.el,search:e,error:g,xhr:b});h.isCancelled!==!0&&(console.log("ERROR: server communication failed. The server should return",{status:"success",items:[{id:1,text:"item"}]},", instead the AJAX request produced this: ",g),c.clearCache(),c.trigger(a.extend(h,{phase:"after"})))}),c.trigger(a.extend(g,{phase:"after"})))},b))}},search:function(){var b=this,c=this.options,d=a(b.el).val(),e=b.el,f=[],g=a(b.el).data("selected");if("enum"==b.type){e=a(b.helpers.multi).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}if("list"==b.type){e=a(b.helpers.focus).find("input"),d=e.val();for(var h in g)g[h]&&f.push(g[h].id)}var i=b.trigger({phase:"before",type:"search",target:e,search:d});if(i.isCancelled!==!0){if(b.tmp.xhr_loading!==!0){var j=0;for(var k in c.items){var l=c.items[k],m="",n="";-1!=["is","begins"].indexOf(c.match)&&(m="^"),-1!=["is","ends"].indexOf(c.match)&&(n="$");try{var o=new RegExp(m+d+n,"i");l.hidden=o.test(l.text)||"..."==l.text?!1:!0}catch(p){}"enum"==b.type&&-1!=a.inArray(l.id,f)&&(l.hidden=!0),l.hidden!==!0&&j++}if("combo"!=b.type)for(c.index=0;c.items[c.index]&&c.items[c.index].hidden;)c.index++;else c.index=-1;0>=j&&(c.index=-1),c.spinner=!1,b.updateOverlay(),setTimeout(function(){var b=a("#w2ui-overlay").html()||"";c.markSearch&&-1!=b.indexOf("$.fn.w2menuHandler")&&a("#w2ui-overlay").w2marker(d)},1)}else c.items.splice(0,c.cacheMax),c.spinner=!0,b.updateOverlay();b.trigger(a.extend(i,{phase:"after"}))}},updateOverlay:function(){var b=this,c=this.options;if("color"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length?a(b.el).w2overlay(b.getColorHTML()):a("#w2ui-overlay").html(b.getColorHTML()),a("#w2ui-overlay .color").on("mousedown",function(c){var d=a(c.originalEvent.target).attr("name"),e=a(c.originalEvent.target).attr("index").split(":");b.tmp.cind1=e[0],b.tmp.cind2=e[1],a(b.el).val(d).change(),a(this).html("•")}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})}if("date"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
      ',{css:{"background-color":"#f5f5f5"}});var d,e,f=w2utils.isDate(a(b.el).val(),b.options.format,!0);f&&(d=f.getMonth()+1,e=f.getFullYear()),function k(c,d){a("#w2ui-overlay > div > div").html(b.getMonthHTML(c,d)),a("#w2ui-overlay .w2ui-calendar-title").on("mousedown",function(){if(a(this).next().hasClass("w2ui-calendar-jump"))a(this).next().remove();else{var c,d;a(this).after('
      '),a(this).next().hide().html(b.getYearHTML()).fadeIn(200),setTimeout(function(){a("#w2ui-overlay .w2ui-calendar-jump").find(".w2ui-jump-month, .w2ui-jump-year").on("click",function(){a(this).hasClass("w2ui-jump-month")&&(a(this).parent().find(".w2ui-jump-month").removeClass("selected"),a(this).addClass("selected"),d=a(this).attr("name")),a(this).hasClass("w2ui-jump-year")&&(a(this).parent().find(".w2ui-jump-year").removeClass("selected"),a(this).addClass("selected"),c=a(this).attr("name")),null!=c&&null!=d&&(a("#w2ui-overlay .w2ui-calendar-jump").fadeOut(100),setTimeout(function(){k(parseInt(d)+1,c)},100))}),a("#w2ui-overlay .w2ui-calendar-jump >:last-child").prop("scrollTop",2e3)},1)}}),a("#w2ui-overlay .w2ui-date").on("mousedown",function(){var c=a(this).attr("date");a(b.el).val(c).change(),a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"})}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)}),a("#w2ui-overlay .previous").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])-1,k(a[0],a[1])}),a("#w2ui-overlay .next").on("mousedown",function(){var a=b.options.current.split("/");a[0]=parseInt(a[0])+1,k(a[0],a[1])})}(d,e)}if("time"==this.type){if(a(b.el).attr("readonly"))return;0==a("#w2ui-overlay").length&&a(b.el).w2overlay('
      ',{css:{"background-color":"#fff"}});var g="h24"==this.options.format?!0:!1;a("#w2ui-overlay > div").html(b.getHourHTML()),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var c=a(this).attr("hour");a(b.el).val((c>12&&!g?c-12:c)+":00"+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){var c=a(this).attr("hour");a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),a(b.el).w2overlay('
      ',{css:{"background-color":"#fff"}}),a("#w2ui-overlay > div").html(b.getMinHTML(c)),a("#w2ui-overlay .w2ui-time").on("mousedown",function(){a(this).css({"background-color":"#B6D5FB","border-color":"#aaa"});var d=a(this).attr("min");a(b.el).val((c>12&&!g?c-12:c)+":"+(10>d?0:"")+d+(g?"":12>c?" am":" pm")).change()}).on("mouseup",function(){setTimeout(function(){a("#w2ui-overlay").length>0&&a("#w2ui-overlay").removeData("keepOpen")[0].hide()},10)})})}if(-1!=["list","combo","enum"].indexOf(this.type)){var h=this.el,i=this.el;if("enum"==this.type&&(h=a(this.helpers.multi),i=a(h).find("input")),"list"==this.type&&(i=a(this.helpers.focus).find("input")),a(i).is(":focus")){if(c.openOnFocus===!1&&""==a(i).val()&&b.tmp.force_open!==!0)return void a().w2overlay();if(b.tmp.force_hide)return a().w2overlay(),void setTimeout(function(){delete b.tmp.force_hide},1);""!=a(i).val()&&delete b.tmp.force_open,0==a("#w2ui-overlay").length&&(c.index=0);var j=w2utils.lang("No matches");null!=c.url&&a(i).val().length=c.max&&c.max>0&&e.pop(),delete d.item.hidden,e.push(d.item),a(b.el).data("selected",e).change(),a(b.helpers.multi).find("input").val("").width(20),b.refresh(),a("#w2ui-overlay").length>0&&a("#w2ui-overlay")[0].hide(),b.trigger(a.extend(f,{phase:"after"}))}}else a(b.el).data("selected",d.item).val(d.item.text).change(),b.helpers.focus&&(b.helpers.focus.find("input").val(""),b.refresh())}}))}}},inRange:function(b){var c=!1;if("date"==this.type){var d=w2utils.isDate(b,this.options.format,!0);if(d){if(this.options.start||this.options.end){var e="string"==typeof this.options.start?this.options.start:a(this.options.start).val(),f="string"==typeof this.options.end?this.options.end:a(this.options.end).val(),g=w2utils.isDate(e,this.options.format,!0),h=w2utils.isDate(f,this.options.format,!0),i=new Date(d);g||(g=i),h||(h=i),i>=g&&h>=i&&(c=!0)}else c=!0;this.options.blocked&&-1!=a.inArray(b,this.options.blocked)&&(c=!1)}}if("time"==this.type)if(this.options.start||this.options.end){var j=this.toMin(b),k=this.toMin(this.options.start),l=this.toMin(this.options.end);k||(k=j),l||(l=j),j>=k&&l>=j&&(c=!0)}else c=!0;return c},checkType:function(a,b){var c=this;switch(c.type){case"int":return b&&-1!=["-"].indexOf(a)?!0:w2utils.isInt(a.replace(c.options.numberRE,""));case"percent":a=a.replace(/%/g,"");case"float":return b&&-1!=["-","."].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.numberRE,""));case"money":case"currency":return b&&-1!=["-",".",c.options.groupSymbol,c.options.currencyPrefix,c.options.currencySuffix].indexOf(a)?!0:w2utils.isFloat(a.replace(c.options.moneyRE,""));case"hex":case"color":return w2utils.isHex(a);case"alphanumeric":return w2utils.isAlphaNumeric(a)}return!0},addPrefix:function(){var b=this;setTimeout(function(){if("clear"!==b.type){var c,d=a(b.el).data("tmp")||{};d["old-padding-left"]&&a(b.el).css("padding-left",d["old-padding-left"]),d["old-padding-left"]=a(b.el).css("padding-left"),a(b.el).data("tmp",d),""!==b.options.prefix&&(b.helpers.prefix&&a(b.helpers.prefix).remove(),a(b.el).before('
      '+b.options.prefix+"
      "),c=a(b.el).prev(),c.css({color:a(b.el).css("color"),"font-family":a(b.el).css("font-family"),"font-size":a(b.el).css("font-size"),"padding-top":a(b.el).css("padding-top"),"padding-bottom":a(b.el).css("padding-bottom"),"padding-left":a(b.el).css("padding-left"),"padding-right":0,"margin-top":parseInt(a(b.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(b.el).css("margin-bottom"),10)+1+"px","margin-left":a(b.el).css("margin-left"),"margin-right":0}).on("click",function(){if(b.options.icon&&"function"==typeof b.onIconClick){var c=b.trigger({phase:"before",type:"iconClick",target:b.el,el:a(this).find("span.w2ui-icon")[0]});if(c.isCancelled===!0)return;b.trigger(a.extend(c,{phase:"after"}))}else"list"==b.type?a(b.helpers.focus).find("input").focus():a(b.el).focus()}),a(b.el).css("padding-left",c.width()+parseInt(a(b.el).css("padding-left"),10)+"px"),b.helpers.prefix=c)}},1)},addSuffix:function(){var b,c,d=this;setTimeout(function(){if("clear"!==d.type){var e=a(d.el).data("tmp")||{};if(e["old-padding-right"]&&a(d.el).css("padding-right",e["old-padding-right"]),e["old-padding-right"]=a(d.el).css("padding-right"),a(d.el).data("tmp",e),c=parseInt(a(d.el).css("padding-right"),10),d.options.arrows){d.helpers.arrows&&a(d.helpers.arrows).remove(),a(d.el).after('
       
      ');{w2utils.getSize(d.el,"height")}b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),height:a(d.el).height()+parseInt(a(d.el).css("padding-top"),10)+parseInt(a(d.el).css("padding-bottom"),10)+"px",padding:0,"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":0,"border-left":"1px solid silver"}).css("margin-left","-"+(b.width()+parseInt(a(d.el).css("margin-right"),10)+12)+"px").on("mousedown",function(b){function c(){clearTimeout(a("body").data("_field_update_timer")),a("body").off("mouseup",c)}function e(c){a(d.el).focus(),d.keyDown(a.Event("keydown"),{keyCode:"up"==a(b.target).attr("type")?38:40}),c!==!1&&a("body").data("_field_update_timer",setTimeout(e,60))}a("body").on("mouseup",c),a("body").data("_field_update_timer",setTimeout(e,700)),e(!1)}),c+=b.width()+12,a(d.el).css("padding-right",c+"px"),d.helpers.arrows=b}""!==d.options.suffix&&(d.helpers.suffix&&a(d.helpers.suffix).remove(),a(d.el).after('
      '+d.options.suffix+"
      "),b=a(d.el).next(),b.css({color:a(d.el).css("color"),"font-family":a(d.el).css("font-family"),"font-size":a(d.el).css("font-size"),"padding-top":a(d.el).css("padding-top"),"padding-bottom":a(d.el).css("padding-bottom"),"padding-left":"3px","padding-right":a(d.el).css("padding-right"),"margin-top":parseInt(a(d.el).css("margin-top"),10)+1+"px","margin-bottom":parseInt(a(d.el).css("margin-bottom"),10)+1+"px"}).on("click",function(){"list"==d.type?a(d.helpers.focus).find("input").focus():a(d.el).focus()}),b.css("margin-left","-"+(w2utils.getSize(b,"width")+parseInt(a(d.el).css("margin-right"),10)+2)+"px"),c+=b.width()+3,a(d.el).css("padding-right",c+"px"),d.helpers.suffix=b)}},1)},addFocus:function(){var b=this,c=this.options,d=0;c.icon&&(d=11),a(b.helpers.focus).remove();var e='
      ';a(b.el).attr("tabindex",-1).before(e);var f=a(b.el).prev();b.helpers.focus=f,f.css({width:a(b.el).width(),"margin-top":a(b.el).css("margin-top"),"margin-left":parseInt(a(b.el).css("margin-left"))+parseInt(a(b.el).css("padding-left"))+"px","margin-bottom":a(b.el).css("margin-bottom"),"margin-right":a(b.el).css("margin-right")}).find("input").css({cursor:"default",width:"100%",outline:"none",opacity:1,margin:0,border:"1px solid transparent",padding:a(b.el).css("padding-top"),"padding-left":0,"margin-left":d+(d>0?6:0),"background-color":"transparent"}),f.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),c.stopPropagation()}).on("focus",function(c){a(b.el).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(this).val(""),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(b.el).css("outline","none"),a(this).val(""),b.refresh(),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){b.keyPress(a)}),f.on("click",function(){a(this).find("input").focus()}),b.refresh()},addMulti:function(){{var b=this;this.options}a(b.helpers.multi).remove();var c="",d="margin-top : 0px; margin-bottom : 0px; margin-left : "+a(b.el).css("margin-left")+"; margin-right : "+a(b.el).css("margin-right")+"; width : "+(w2utils.getSize(b.el,"width")-parseInt(a(b.el).css("margin-left"),10)-parseInt(a(b.el).css("margin-right"),10))+"px;";"enum"==b.type&&(c='
      • "),"file"==b.type&&(c='
        '),a(b.el).before(c).css({"background-color":"transparent","border-color":"transparent"});var e=a(b.el).prev();b.helpers.multi=e,"enum"==b.type&&(a(b.el).attr("tabindex",-1),e.find("input").on("click",function(c){0==a("#w2ui-overlay").length&&b.focus(c),a(b.el).triggerHandler("click")}).on("focus",function(c){a(e).css({outline:"auto 5px #7DB4F3","outline-offset":"-2px"}),a(b.el).triggerHandler("focus"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("blur",function(c){a(e).css("outline","none"),a(b.el).triggerHandler("blur"),c.stopPropagation?c.stopPropagation():c.cancelBubble=!0}).on("keyup",function(a){b.keyUp(a)}).on("keydown",function(a){b.keyDown(a)}).on("keypress",function(a){e.find(".w2ui-enum-placeholder").remove(),b.keyPress(a)}),e.on("click",function(){a(this).find("input").focus()})),"file"==b.type&&(a(b.el).css("outline","none"),e.on("click",function(c){a(b.el).focus(),a(b.el).attr("readonly")||(b.blur(c),e.find("input").click())}).on("dragenter",function(){a(b.el).attr("readonly")||a(e).addClass("w2ui-file-dragover")}).on("dragleave",function(c){if(!a(b.el).attr("readonly")){var d=a(c.target).parents(".w2ui-field-helper");0==d.length&&a(e).removeClass("w2ui-file-dragover")}}).on("drop",function(c){if(!a(b.el).attr("readonly")){a(e).removeClass("w2ui-file-dragover");for(var d=c.originalEvent.dataTransfer.files,f=0,g=d.length;g>f;f++)b.addFile.call(b,d[f]);c.preventDefault(),c.stopPropagation()}}).on("dragover",function(a){a.preventDefault(),a.stopPropagation()}),e.find("input").on("click",function(a){a.stopPropagation()}).on("change",function(){if("undefined"!=typeof this.files)for(var a=0,c=this.files.length;c>a;a++)b.addFile.call(b,this.files[a])})),b.refresh()},addFile:function(b){var c,d=this,e=this.options,f=a(d.el).data("selected"),g={name:b.name,type:b.type,modified:b.lastModifiedDate,size:b.size,content:null},h=0,i=0;for(var j in f)h+=f[j].size,i++;var k=d.trigger({phase:"before",type:"add",target:d.el,file:g,total:i,totalSize:h});if(k.isCancelled!==!0){if(0!==e.maxFileSize&&g.size>e.maxFileSize)return c="Maximum file size is "+w2utils.size(e.maxFileSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c); +if(0!==e.maxSize&&h+g.size>e.maxSize)return c="Maximum total size is "+w2utils.size(e.maxSize),e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(0!==e.max&&i>=e.max)return c="Maximum number of files is "+e.max,e.silent===!1&&a(d.el).w2tag(c),void console.log("ERROR: "+c);if(f.push(g),"undefined"!=typeof FileReader){var l=new FileReader;l.onload=function(){return function(b){var c=b.target.result,e=c.indexOf(",");g.content=c.substr(e+1),d.refresh(),a(d.el).trigger("change"),d.trigger(a.extend(k,{phase:"after"}))}}(),l.readAsDataURL(b)}else d.refresh(),a(d.el).trigger("change")}},normMenu:function(b){if(a.isArray(b)){for(var c=0;cc;c++){b+="";for(var d=0;8>d;d++)b+='
        '+(a(this.el).val()==this.pallete[c][d]?"•":" ")+"
        ";b+="",2>c&&(b+='')}return b+="
        "},getMonthHTML:function(a,b){var c=new Date,d=w2utils.settings.fullmonths,e=(w2utils.settings.fulldays,["31","28","31","30","31","30","31","31","30","31","30","31"]),f=c.getFullYear()+"/"+(Number(c.getMonth())+1)+"/"+c.getDate();b=w2utils.isInt(b)?parseInt(b):c.getFullYear(),a=w2utils.isInt(a)?parseInt(a):c.getMonth()+1,a>12&&(a-=12,b++),(1>a||0===a)&&(a+=12,b--),e[1]=b/4==Math.floor(b/4)?"29":"28",this.options.current=a+"/"+b,c=new Date(b,a-1,1);for(var g=c.getDay(),h=w2utils.settings.shortdays,i="",j=0,k=h.length;k>j;j++)i+=""+h[j]+"";for(var l='
        '+d[a-1]+", "+b+'
        '+i+"",m=1,n=1;43>n;n++){if(0===g&&1==n){for(var o=0;6>o;o++)l+='';n+=6}else if(g>n||m>e[a-1]){l+='',n%7===0&&(l+="");continue}var p=b+"/"+a+"/"+m,q="";n%7==6&&(q=" w2ui-saturday"),n%7===0&&(q=" w2ui-sunday"),p==f&&(q+=" w2ui-today");var r=m,s="",t="",u=w2utils.formatDate(p,this.options.format);this.options.colored&&void 0!==this.options.colored[u]&&(tmp=this.options.colored[u].split(":"),t="background-color: "+tmp[0]+";",s="color: "+tmp[1]+";"),l+='",(n%7===0||0===g&&1==n)&&(l+=""),m++}return l+="
          
        '+r+"
        "},getYearHTML:function(){var a=w2utils.settings.shortmonths,b="",c="";for(var d in a)b+='
        '+a[d]+"
        ";for(var e=1950;2020>=e;e++)c+='
        '+e+"
        ";return"
        "+b+"
        "+c+"
        "},getHourHTML:function(){for(var a=[],b="h24"==this.options.format?!0:!1,c=0;24>c;c++){var d=(c>=12&&!b?c-12:c)+":00"+(b?"":12>c?" am":" pm");12!=c||b||(d="12:00 pm"),a[Math.floor(c/8)]||(a[Math.floor(c/8)]="");var e=this.fromMin(this.toMin(d)),f=this.fromMin(this.toMin(d)+59);a[Math.floor(c/8)]+='
        '+d+"
        "}var g='
        '+a[0]+" "+a[1]+" "+a[2]+"
        ";return g},getMinHTML:function(a){"undefined"==typeof a&&(a=0);for(var b="h24"==this.options.format?!0:!1,c=[],d=0;60>d;d+=5){var e=(a>12&&!b?a-12:a)+":"+(10>d?0:"")+d+" "+(b?"":12>a?"am":"pm"),f=20>d?0:40>d?1:2;c[f]||(c[f]=""),c[f]+='
        '+e+"
        "}var g='
        '+c[0]+" "+c[1]+" "+c[2]+"
        ";return g},toMin:function(a){if("string"!=typeof a)return null;var b=a.split(":");return 2!=b.length?null:(b[0]=parseInt(b[0]),b[1]=parseInt(b[1]),-1!=a.indexOf("pm")&&12!=b[0]&&(b[0]+=12),60*b[0]+b[1])},fromMin:function(a){var b="";a>=1440&&(a%=1440),0>a&&(a=1440+a);var c=Math.floor(a/60),d=(10>a%60?"0":"")+a%60;return b=-1!=this.options.format.indexOf("h24")?c+":"+d:(12>=c?c:c-12)+":"+d+" "+(c>=12?"pm":"am")}},a.extend(b.prototype,w2utils.event),w2obj.field=b}(jQuery),function(){var w2form=function(a){this.name=null,this.header="",this.box=null,this.url="",this.formURL="",this.formHTML="",this.page=0,this.recid=0,this.fields=[],this.actions={},this.record={},this.original={},this.postData={},this.toolbar={},this.tabs={},this.style="",this.focus=0,this.msgNotJSON=w2utils.lang("Return data is not in JSON format."),this.msgAJAXerror=w2utils.lang("AJAX error. See console for more details."),this.msgRefresh=w2utils.lang("Refreshing..."),this.msgSaving=w2utils.lang("Saving..."),this.onRequest=null,this.onLoad=null,this.onValidate=null,this.onSubmit=null,this.onSave=null,this.onChange=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,this.onAction=null,this.onToolbar=null,this.onError=null,this.isGenerated=!1,this.last={xhr:null},$.extend(!0,this,w2obj.form,a)};$.fn.w2form=function(a){if("object"==typeof a||!a){var b=this;if(!w2utils.checkName(a,"w2form"))return;var c=a.record,d=a.original,e=a.fields,f=a.toolbar,g=a.tabs,h=new w2form(a);if($.extend(h,{record:{},original:{},fields:[],tabs:{},toolbar:{},handlers:[]}),$.isArray(g)){$.extend(!0,h.tabs,{tabs:[]});for(var i in g){var j=g[i];h.tabs.tabs.push("object"==typeof j?j:{id:j,caption:j})}}else $.extend(!0,h.tabs,g);$.extend(!0,h.toolbar,f);for(var k in e)h.fields[k]=$.extend(!0,{},e[k]);for(var k in c)h.record[k]=$.isPlainObject(c[k])?$.extend(!0,{},c[k]):c[k];for(var k in d)h.original[k]=$.isPlainObject(d[k])?$.extend(!0,{},d[k]):d[k];return b.length>0&&(h.box=b[0]),""!=h.formURL?$.get(h.formURL,function(a){h.formHTML=a,h.isGenerated=!0,(0!=$(h.box).length||0!=a.length)&&($(h.box).html(a),h.render(h.box))}):""!=h.formHTML||(h.formHTML=0!=$(this).length&&""!=$.trim($(this).html())?$(this).html():h.generateHTML()),w2ui[h.name]=h,""==h.formURL&&(-1==String(h.formHTML).indexOf("w2ui-page")&&(h.formHTML='
        '+h.formHTML+"
        "),$(h.box).html(h.formHTML),h.isGenerated=!0,h.render(h.box)),h}if(w2ui[$(this).attr("name")]){var b=w2ui[$(this).attr("name")];return b[a].apply(b,Array.prototype.slice.call(arguments,1)),this}console.log("ERROR: Method "+a+" does not exist on jQuery.w2form")},w2form.prototype={get:function(a,b){if(0===arguments.length){var c=[];for(var d in this.fields)null!=this.fields[d].name&&c.push(this.fields[d].name);return c}for(var e in this.fields)if(this.fields[e].name==a)return b===!0?e:this.fields[e];return null},set:function(a,b){for(var c in this.fields)if(this.fields[c].name==a)return $.extend(this.fields[c],b),this.refresh(),!0;return!1},reload:function(a){var b="object"!=typeof this.url?this.url:this.url.get;b&&0!=this.recid?this.request(a):(this.refresh(),"function"==typeof a&&a())},clear:function(){this.recid=0,this.record={},$().w2tag(),this.refresh()},error:function(a){var b=this.trigger({target:this.name,type:"error",message:a,xhr:this.last.xhr});return b.isCancelled===!0?void("function"==typeof callBack&&callBack()):(setTimeout(function(){w2alert(a,"Error")},1),void this.trigger($.extend(b,{phase:"after"})))},validate:function(a){"undefined"==typeof a&&(a=!0),$().w2tag();var b=[];for(var c in this.fields){var d=this.fields[c];switch(null==this.record[d.name]&&(this.record[d.name]=""),d.type){case"int":this.record[d.name]&&!w2utils.isInt(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not an integer")});break;case"float":this.record[d.name]&&!w2utils.isFloat(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not a float")});break;case"money":this.record[d.name]&&!w2utils.isMoney(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not in money format")});break;case"color":case"hex":this.record[d.name]&&!w2utils.isHex(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not a hex number")});break;case"email":this.record[d.name]&&!w2utils.isEmail(this.record[d.name])&&b.push({field:d,error:w2utils.lang("Not a valid email")});break;case"checkbox":this.record[d.name]=1==this.record[d.name]?1:0;break;case"date":this.record[d.name]&&!w2utils.isDate(this.record[d.name],d.options.format)&&b.push({field:d,error:w2utils.lang("Not a valid date")+": "+d.options.format});break;case"list":case"combo":break;case"enum":}var e=this.record[d.name];d.required&&(""===e||$.isArray(e)&&0==e.length)&&b.push({field:d,error:w2utils.lang("Required field")}),d.equalto&&this.record[d.name]!=this.record[d.equalto]&&b.push({field:d,error:w2utils.lang("Field should be equal to ")+d.equalto})}var f=this.trigger({phase:"before",target:this.name,type:"validate",errors:b});if(f.isCancelled!==!0){if(a)for(var g in f.errors){var h=f.errors[g];"radio"==h.field.type?$($(h.field.el).parents("div")[0]).w2tag(h.error,{"class":"w2ui-error"}):-1!=["enum","file"].indexOf(h.field.type)?!function(a){setTimeout(function(){var b=$(a.field.el).data("w2field").helpers.multi;$(a.field.el).w2tag(a.error),$(b).addClass("w2ui-error")},1)}(h):$(h.field.el).w2tag(h.error,{"class":"w2ui-error"})}return this.trigger($.extend(f,{phase:"after"})),b}},getChanges:function(){var a=function(b,c,d){for(var e in b)"object"==typeof b[e]?(d[e]=a(b[e],c[e]||{},{}),(!d[e]||$.isEmptyObject(d[e]))&&delete d[e]):b[e]!=c[e]&&(d[e]=b[e]);return d};return a(this.record,this.original,{})},request:function(postData,callBack){var obj=this;if("function"==typeof postData&&(callBack=postData,postData=null),("undefined"==typeof postData||null==postData)&&(postData={}),this.url&&("object"!=typeof this.url||this.url.get)){(null==this.recid||"undefined"==typeof this.recid)&&(this.recid=0);var params={};params.cmd="get-record",params.name=this.name,params.recid=this.recid,$.extend(params,this.postData),$.extend(params,postData);var eventData=this.trigger({phase:"before",type:"request",target:this.name,url:this.url,postData:params});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Request aborted."}));this.record={},this.original={},this.lock(this.msgRefresh);var url=eventData.url;if("object"==typeof eventData.url&&eventData.url.get&&(url=eventData.url.get),this.last.xhr)try{this.last.xhr.abort()}catch(e){}this.last.xhr=$.ajax({type:"GET",url:url,data:String($.param(eventData.postData,!1)).replace(/%5B/g,"[").replace(/%5D/g,"]"),dataType:"text",complete:function(xhr,status){obj.unlock();var eventData=obj.trigger({phase:"before",target:obj.name,type:"load",xhr:xhr,status:status});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Request aborted."}));var data,responseText=obj.last.xhr.responseText;if("error"!=status){if("undefined"!=typeof responseText&&""!=responseText){if("object"==typeof responseText)data=responseText;else try{eval("data = "+responseText)}catch(e){}"undefined"==typeof data&&(data={status:"error",message:obj.msgNotJSON,responseText:responseText}),"error"==data.status?obj.error(data.message):(obj.record=$.extend({},data.record),obj.original=$.extend({},data.record))}}else obj.error("AJAX Error "+xhr.status+": "+xhr.statusText),data={status:"error",message:obj.msgAJAXerror,responseText:responseText};obj.trigger($.extend(eventData,{phase:"after"})),obj.refresh(),"function"==typeof callBack&&callBack(data)}}),this.trigger($.extend(eventData,{phase:"after"}))}},submit:function(a,b){return this.save(a,b)},save:function(postData,callBack){var obj=this;$(this.box).find(":focus").change(),"function"==typeof postData&&(callBack=postData,postData=null);var errors=obj.validate(!0);return 0!==errors.length?void obj.goto(errors[0].field.page):(("undefined"==typeof postData||null==postData)&&(postData={}),!obj.url||"object"==typeof obj.url&&!obj.url.save?void console.log("ERROR: Form cannot be saved because no url is defined."):(obj.lock(obj.msgSaving+' '),void setTimeout(function(){var params={};params.cmd="save-record",params.name=obj.name,params.recid=obj.recid,$.extend(params,obj.postData),$.extend(params,postData),params.record=$.extend(!0,{},obj.record);var eventData=obj.trigger({phase:"before",type:"submit",target:obj.name,url:obj.url,postData:params});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Saving aborted."}));var url=eventData.url;if("object"==typeof eventData.url&&eventData.url.save&&(url=eventData.url.save),obj.last.xhr)try{obj.last.xhr.abort()}catch(e){}obj.last.xhr=$.ajax({type:w2utils.settings.RESTfull?0==obj.recid?"POST":"PUT":"POST",url:url,data:String($.param(eventData.postData,!1)).replace(/%5B/g,"[").replace(/%5D/g,"]"),dataType:"text",xhr:function(){var a=new window.XMLHttpRequest;return a.upload.addEventListener("progress",function(a){if(a.lengthComputable){var b=Math.round(a.loaded/a.total*100);$("#"+obj.name+"_progress").text(""+b+"%")}},!1),a},complete:function(xhr,status){obj.unlock();var eventData=obj.trigger({phase:"before",target:obj.name,type:"save",xhr:xhr,status:status});if(eventData.isCancelled===!0)return void("function"==typeof callBack&&callBack({status:"error",message:"Saving aborted."}));var data,responseText=xhr.responseText;if("error"!=status){if("undefined"!=typeof responseText&&""!=responseText){if("object"==typeof responseText)data=responseText;else try{eval("data = "+responseText)}catch(e){}"undefined"==typeof data&&(data={status:"error",message:obj.msgNotJSON,responseText:responseText}),"error"==data.status?obj.error(data.message):obj.original=$.extend({},obj.record)}}else obj.error("AJAX Error "+xhr.status+": "+xhr.statusText),data={status:"error",message:obj.msgAJAXerror,responseText:responseText};obj.trigger($.extend(eventData,{phase:"after"})),obj.refresh(),"function"==typeof callBack&&callBack(data)}}),obj.trigger($.extend(eventData,{phase:"after"}))},50)))},lock:function(){var a=$(this.box).find("> div:first-child"),b=Array.prototype.slice.call(arguments,0);b.unshift(a),w2utils.lock.apply(window,b)},unlock:function(){var a=this;setTimeout(function(){w2utils.unlock(a.box)},25)},"goto":function(a){"undefined"!=typeof a&&(this.page=a),$(this.box).data("auto-size")===!0&&$(this.box).height(0),this.refresh()},generateHTML:function(){var a=[];for(var b in this.fields){var c="",d=this.fields[b];"undefined"==typeof d.html&&(d.html={}),d.html=$.extend(!0,{caption:"",span:6,attr:"",text:"",page:0},d.html),""==d.html.caption&&(d.html.caption=d.name);var e='";("pass"===d.type||"password"===d.type)&&(e='"),"checkbox"==d.type&&(e='"),"textarea"==d.type&&(e='"),c+='\n
        '+d.html.caption+':
        \n
        '+e+d.html.text+"
        ","undefined"==typeof a[d.html.page]&&(a[d.html.page]='
        '),a[d.html.page]+=c}for(var f in a)a[f]+="\n
        ";var g="";if(!$.isEmptyObject(this.actions)){g+='\n
        ';for(var h in this.actions)g+='\n ";g+="\n
        "}return a.join("")+g},action:function(a,b){var c=this.trigger({phase:"before",target:a,type:"action",originalEvent:b});c.isCancelled!==!0&&("function"==typeof this.actions[a]&&this.actions[a].call(this,b),this.trigger($.extend(c,{phase:"after"})))},resize:function(){function a(){d.width($(b.box).width()).height($(b.box).height()),f.css("top",""!=b.header?w2utils.getSize(e,"height"):0),g.css("top",(""!=b.header?w2utils.getSize(e,"height"):0)+("object"==typeof b.toolbar&&$.isArray(b.toolbar.items)&&b.toolbar.items.length>0?w2utils.getSize(f,"height"):0)),h.css("top",(""!=b.header?w2utils.getSize(e,"height"):0)+("object"==typeof b.toolbar&&$.isArray(b.toolbar.items)&&b.toolbar.items.length>0?w2utils.getSize(f,"height")+5:0)+("object"==typeof b.tabs&&$.isArray(b.tabs.tabs)&&b.tabs.tabs.length>0?w2utils.getSize(g,"height")+5:0)),h.css("bottom",k.length>0?w2utils.getSize(k,"height"):0)}var b=this,c=this.trigger({phase:"before",target:this.name,type:"resize"});if(c.isCancelled!==!0){var d=$(this.box).find("> div"),e=$(this.box).find("> div .w2ui-form-header"),f=$(this.box).find("> div .w2ui-form-toolbar"),g=$(this.box).find("> div .w2ui-form-tabs"),h=$(this.box).find("> div .w2ui-page"),i=$(this.box).find("> div .w2ui-page.page-"+this.page),j=$(this.box).find("> div .w2ui-page.page-"+this.page+" > div"),k=$(this.box).find("> div .w2ui-buttons");a(),(0==parseInt($(this.box).height())||$(this.box).data("auto-size")===!0)&&($(this.box).height((e.length>0?w2utils.getSize(e,"height"):0)+("object"==typeof this.tabs&&$.isArray(this.tabs.tabs)&&this.tabs.tabs.length>0?w2utils.getSize(g,"height"):0)+("object"==typeof this.toolbar&&$.isArray(this.toolbar.items)&&this.toolbar.items.length>0?w2utils.getSize(f,"height"):0)+(h.length>0?w2utils.getSize(j,"height")+w2utils.getSize(i,"+height")+12:0)+(k.length>0?w2utils.getSize(k,"height"):0)),$(this.box).data("auto-size",!0)),a(),b.trigger($.extend(c,{phase:"after"}))}},refresh:function(){var a=(new Date).getTime(),b=this;if(this.box&&this.isGenerated&&"undefined"!=typeof $(this.box).html()){$(this.box).find("input, textarea, select").each(function(a,c){var d=$(c).attr("undefined"!=typeof $(c).attr("name")?"name":"id"),e=b.get(d);if(e){var f=$(c).parents(".w2ui-page");if(f.length>0)for(var g=0;100>g;g++)if(f.hasClass("page-"+g)){e.page=g;break}}});var c=this.trigger({phase:"before",target:this.name,type:"refresh",page:this.page});if(c.isCancelled!==!0){$(this.box).find(".w2ui-page").hide(),$(this.box).find(".w2ui-page.page-"+this.page).show(),$(this.box).find(".w2ui-form-header").html(this.header),"object"==typeof this.tabs&&$.isArray(this.tabs.tabs)&&this.tabs.tabs.length>0?($("#form_"+this.name+"_tabs").show(),this.tabs.active=this.tabs.tabs[this.page].id,this.tabs.refresh()):$("#form_"+this.name+"_tabs").hide(),"object"==typeof this.toolbar&&$.isArray(this.toolbar.items)&&this.toolbar.items.length>0?($("#form_"+this.name+"_toolbar").show(),this.toolbar.refresh()):$("#form_"+this.name+"_toolbar").hide();for(var d in this.fields){var e=this.fields[d];e.$el=$(this.box).find('[name="'+String(e.name).replace(/\\/g,"\\\\")+'"]'),e.el=e.$el[0],"undefined"==typeof e.el&&console.log('ERROR: Cannot associate field "'+e.name+'" with html control. Make sure html control exists with the same name.'),e.el&&(e.el.id=e.name);var f=$(e).data("w2field");f&&f.clear(),$(e.$el).off("change").on("change",function(){var a=this.value,c=b.record[this.name]?b.record[this.name]:"",d=b.get(this.name);if(-1!=["list","enum","file"].indexOf(d.type)&&$(this).data("selected")){var e=$(this).data("selected"),f=b.record[this.name];if($.isArray(e)){a=[];for(var g in e)a[g]=$.extend(!0,{},e[g])}if($.isPlainObject(e)&&(a=$.extend(!0,{},e)),$.isArray(f)){c=[];for(var g in f)c[g]=$.extend(!0,{},f[g])}$.isPlainObject(f)&&(c=$.extend(!0,{},f))}if(-1!=["int","float","percent","money","currency"].indexOf(d.type)&&(a=$(this).data("w2field").clean(a)),a!==c){var h=b.trigger({phase:"before",target:this.name,type:"change",value_new:a,value_previous:c});if(h.isCancelled===!0)return void $(this).val(b.record[this.name]);var i=this.value;if("select"==this.type&&(i=this.value),"checkbox"==this.type&&(i=this.checked?!0:!1),"radio"==this.type&&d.$el.each(function(a,b){b.checked&&(i=b.value)}),-1!=["int","float","percent","money","currency","list","combo","enum","file"].indexOf(d.type)&&(i=a),-1!=["enum","file"].indexOf(d.type)&&i.length>0){var j=$(d.el).data("w2field").helpers.multi;$(j).removeClass("w2ui-error")}b.record[this.name]=i,b.trigger($.extend(h,{phase:"after"}))}}),e.required?$(e.el).parent().addClass("w2ui-required"):$(e.el).parent().removeClass("w2ui-required")}$(this.box).find("button, input[type=button]").each(function(a,c){$(c).off("click").on("click",function(a){var c=this.value;this.name&&(c=this.name),this.id&&(c=this.id),b.action(c,a)})});for(var d in this.fields){var e=this.fields[d],g="undefined"!=typeof this.record[e.name]?this.record[e.name]:"";if(e.el)switch(e.type=String(e.type).toLowerCase(),e.options||(e.options={}),e.type){case"text":case"textarea":case"email":case"password":e.el.value=g;break;case"int":case"float":case"money":case"currency":case"percent":case"hex":case"alphanumeric":case"color":case"date":case"time":e.el.value=g,$(e.el).w2field($.extend({},e.options,{type:e.type}));break;case"list":case"combo":if("list"!=e.type||$.isPlainObject(g))e.el.value="combo"!=e.type||$.isPlainObject(g)?$.isPlainObject(g)&&"undefined"!=typeof g.text?g.text:"":g;else for(var h in e.options.items){var i=e.options.items[h];if(i&&i.id==g){g=$.extend(!0,{},i),b.record[e.name]=g;break}}$.isPlainObject(g)||(g={}),$(e.el).w2field($.extend({},e.options,{type:e.type,selected:g}));break;case"enum":case"file":$.isArray(g)||(g=[]),$(e.el).w2field($.extend({},e.options,{type:e.type,selected:g}));break;case"select":var j=e.options.items;if("undefined"!=typeof j&&j.length>0){j=w2obj.field.prototype.normMenu(j),$(e.el).html("");for(var k in j)$(e.el).append('
        - - - - - - - - - - - - - -
        idstring, id of the item
        eventkeyboard or mouse event, holds state of modificarors keys
        isMouseboolean, indicates if event come from mouse
        + + + + + + + + + + + + + +
        idstring, id of the item
        eventkeyboard or mouse event, holds state of modificarors keys
        isMouseboolean, indicates if event come from mouse
        Returns undefined. @@ -31,12 +31,12 @@

        Description

        If you have listview defined in the following way: diff --git a/docs/details/w2listview.viewType.html b/docs/details/w2listview.viewType.html index 723ee4304..2bc7e7e8c 100644 --- a/docs/details/w2listview.viewType.html +++ b/docs/details/w2listview.viewType.html @@ -1,16 +1,16 @@ Returns current view type or sets a new one.
        - viewType([value]) + viewType([value])
        - - - - - -
        valuestring, optional, new view type to be set
        + + + + + +
        valuestring, optional, new view type to be set
        Returns string. @@ -25,13 +25,13 @@

        Description

        If you have listview defined in the following way: diff --git a/docs/details/w2popup.clear.html b/docs/details/w2popup.clear.html index 00d71ce4d..89041b53a 100644 --- a/docs/details/w2popup.clear.html +++ b/docs/details/w2popup.clear.html @@ -1,7 +1,7 @@ Clears title, body, buttons of the popup.
        - clear() + clear()

        Description

        diff --git a/docs/details/w2popup.close.html b/docs/details/w2popup.close.html index 2e9755963..e4f049b8b 100644 --- a/docs/details/w2popup.close.html +++ b/docs/details/w2popup.close.html @@ -1,7 +1,7 @@ Closes popup.
        - close() + close()

        Description

        diff --git a/docs/details/w2popup.defaults.html b/docs/details/w2popup.defaults.html index dd26ca870..b4708294c 100644 --- a/docs/details/w2popup.defaults.html +++ b/docs/details/w2popup.defaults.html @@ -1,28 +1,28 @@ Array of default settings for the popup.
        - Array, default - see below + Array, default - see below
        The code below shows the initial object: diff --git a/docs/details/w2popup.get.html b/docs/details/w2popup.get.html index 1fde0ad63..3c2cf44f0 100644 --- a/docs/details/w2popup.get.html +++ b/docs/details/w2popup.get.html @@ -1,7 +1,7 @@ Returns current popup options.
        - get() + get()

        Description

        diff --git a/docs/details/w2popup.keydown.html b/docs/details/w2popup.keydown.html index fa7d3aba4..c98f64b42 100644 --- a/docs/details/w2popup.keydown.html +++ b/docs/details/w2popup.keydown.html @@ -1,16 +1,16 @@ Processes keyboard actions
        - keydown(event) + keydown(event)
        - - - - - -
        eventDOM Event object, event object
        + + + + + +
        eventDOM Event object, event object

        Description

        diff --git a/docs/details/w2popup.load.html b/docs/details/w2popup.load.html index 1eed5070e..266f5728e 100644 --- a/docs/details/w2popup.load.html +++ b/docs/details/w2popup.load.html @@ -1,16 +1,16 @@ Loads new content for the popup from the server.
        - load(options) + load(options)
        - - - - - -
        optionsobject, options for the popup
        + + + + + +
        optionsobject, options for the popup

        Description

        @@ -30,15 +30,15 @@

        Description

        diff --git a/docs/details/w2popup.lock.html b/docs/details/w2popup.lock.html index 67f34b851..37b0a3284 100644 --- a/docs/details/w2popup.lock.html +++ b/docs/details/w2popup.lock.html @@ -1,20 +1,20 @@ Locks popup window.
        - lock(message, [showSpinner]) + lock(message, [showSpinner])
        - - - - - - - - - -
        messagestring, message
        showSpinnerboolean, optional, spinner indicator
        + + + + + + + + + +
        messagestring, message
        showSpinnerboolean, optional, spinner indicator

        Description

        diff --git a/docs/details/w2popup.lockScreen.html b/docs/details/w2popup.lockScreen.html index abe647fdd..a9a522d2b 100644 --- a/docs/details/w2popup.lockScreen.html +++ b/docs/details/w2popup.lockScreen.html @@ -1,16 +1,16 @@ Locks screen behind the popup
        - lockScreen([options]) + lockScreen([options])
        - - - - - -
        optionsobject, optional, options for the popup
        + + + + + +
        optionsobject, optional, options for the popup

        Description

        @@ -32,13 +32,13 @@

        Description

        OR you can also lock screen and display a popup \ No newline at end of file diff --git a/docs/details/w2popup.max.html b/docs/details/w2popup.max.html index b722530f9..0f51e45e1 100644 --- a/docs/details/w2popup.max.html +++ b/docs/details/w2popup.max.html @@ -1,7 +1,7 @@ Maximizes popup.
        - max() + max()

        Description

        diff --git a/docs/details/w2popup.message.html b/docs/details/w2popup.message.html index 3f3235292..f2f795c61 100644 --- a/docs/details/w2popup.message.html +++ b/docs/details/w2popup.message.html @@ -1,7 +1,7 @@ Displays a message at the top of current popup.
        - message(msgOptions); + message(msgOptions);

        Description

        @@ -28,11 +28,11 @@

        Description

        To display the message diff --git a/docs/details/w2popup.min.html b/docs/details/w2popup.min.html index 1cadce901..28b3ea3d1 100644 --- a/docs/details/w2popup.min.html +++ b/docs/details/w2popup.min.html @@ -1,7 +1,7 @@ Minimizes popup.
        - min() + min()

        Description

        diff --git a/docs/details/w2popup.onClose.html b/docs/details/w2popup.onClose.html index 69003cc6f..4ffe2673d 100644 --- a/docs/details/w2popup.onClose.html +++ b/docs/details/w2popup.onClose.html @@ -1,18 +1,18 @@ Called when popup is closed.
        - onClose = function(event) + onClose = function(event)
        You can add event listener during the object creation: @@ -20,7 +20,7 @@ diff --git a/docs/details/w2popup.onKeydown.html b/docs/details/w2popup.onKeydown.html index b1b9bd4c4..21b17bda3 100644 --- a/docs/details/w2popup.onKeydown.html +++ b/docs/details/w2popup.onKeydown.html @@ -1,7 +1,7 @@ Called when user presses a keyboard key and popup is open.
        - onKeydown = function(event) + onKeydown = function(event)
        The event will only be triggered if .keyboard property of the sidebar is true. @@ -11,11 +11,11 @@ @@ -23,7 +23,7 @@ diff --git a/docs/details/w2popup.onMax.html b/docs/details/w2popup.onMax.html index 53ec30212..5d6d8d42e 100644 --- a/docs/details/w2popup.onMax.html +++ b/docs/details/w2popup.onMax.html @@ -1,18 +1,18 @@ Called when popup is minimized.
        - onMax = function(event) + onMax = function(event)
        You can add event listener during the object creation: @@ -20,7 +20,7 @@ diff --git a/docs/details/w2popup.onMin.html b/docs/details/w2popup.onMin.html index 9b3c0c38d..89de75a10 100644 --- a/docs/details/w2popup.onMin.html +++ b/docs/details/w2popup.onMin.html @@ -1,18 +1,18 @@ Called when popup is minimized.
        - onMin = function(event) + onMin = function(event)
        You can add event listener during the object creation: @@ -20,7 +20,7 @@ diff --git a/docs/details/w2popup.onOpen.html b/docs/details/w2popup.onOpen.html index 5dc3d0b83..4f7b29be4 100644 --- a/docs/details/w2popup.onOpen.html +++ b/docs/details/w2popup.onOpen.html @@ -1,7 +1,7 @@ Called when popup is opened or transitions to the new content.
        - onOpen = function(event) + onOpen = function(event)
        This event is triggered when popup is first opened and any time .open or @@ -14,11 +14,11 @@ @@ -26,7 +26,7 @@ diff --git a/docs/details/w2popup.open.html b/docs/details/w2popup.open.html index 6f9b1f347..0e81ccabd 100644 --- a/docs/details/w2popup.open.html +++ b/docs/details/w2popup.open.html @@ -1,31 +1,31 @@ Opens new popup or transitions to new content.
        - open(options); + open(options);
        - - - - - -
        optionsobject, options for the popup
        + + + + + +
        optionsobject, options for the popup
        OR
        - $('#id-content').w2popup('open', options); + $('#id-content').w2popup('open', options);
        - - - - - -
        optionsobject, options for the popup
        + + + + + +
        optionsobject, options for the popup

        Description

        @@ -49,12 +49,12 @@

        Examples

        @@ -62,25 +62,25 @@

        Examples

        diff --git a/docs/details/w2popup.reset.html b/docs/details/w2popup.reset.html index 0e8dcefee..a6f21cae5 100644 --- a/docs/details/w2popup.reset.html +++ b/docs/details/w2popup.reset.html @@ -1,7 +1,7 @@ Resets popup to default options.
        - reset() + reset()

        Description

        diff --git a/docs/details/w2popup.resize.html b/docs/details/w2popup.resize.html index f17f613eb..380a8c9fd 100644 --- a/docs/details/w2popup.resize.html +++ b/docs/details/w2popup.resize.html @@ -1,24 +1,24 @@ Resizes existing popup.
        - resize(width, height, [callBack]) + resize(width, height, [callBack])
        - - - - - - - - - - - - - -
        widthint, new width for the popup
        heightint, new height for the popup
        callBackfunction, call back function on finish
        + + + + + + + + + + + + + +
        widthint, new width for the popup
        heightint, new height for the popup
        callBackfunction, call back function on finish

        Description

        diff --git a/docs/details/w2popup.set.html b/docs/details/w2popup.set.html index 7ec324b38..c7b9086f4 100644 --- a/docs/details/w2popup.set.html +++ b/docs/details/w2popup.set.html @@ -1,7 +1,7 @@ Transitions popup to the new state.
        - set(options) + set(options)

        Description

        The popup must exists. The method is an alias for the open method. \ No newline at end of file diff --git a/docs/details/w2popup.toggle.html b/docs/details/w2popup.toggle.html index 4b86ec7a2..2dc880b32 100644 --- a/docs/details/w2popup.toggle.html +++ b/docs/details/w2popup.toggle.html @@ -1,7 +1,7 @@ Toggles popup between maximized and normal states.
        - toggle() + toggle()

        Description

        diff --git a/docs/details/w2popup.unlock.html b/docs/details/w2popup.unlock.html index 4567c8fa8..2294d9fb3 100644 --- a/docs/details/w2popup.unlock.html +++ b/docs/details/w2popup.unlock.html @@ -1,7 +1,7 @@ Unlocks popup window.
        - unlock() + unlock()

        Description

        diff --git a/docs/details/w2popup.unlockScreen.html b/docs/details/w2popup.unlockScreen.html index 503588695..598514c80 100644 --- a/docs/details/w2popup.unlockScreen.html +++ b/docs/details/w2popup.unlockScreen.html @@ -1,7 +1,7 @@ Unlocks screen behind popup.
        - unlockScreen() + unlockScreen()

        Description

        diff --git a/docs/details/w2sidebar.add.html b/docs/details/w2sidebar.add.html index 8d669184a..ca2c510dc 100644 --- a/docs/details/w2sidebar.add.html +++ b/docs/details/w2sidebar.add.html @@ -1,20 +1,20 @@ Adds a sidebar node or nodes.
        - add([parent], nodes) + add([parent], nodes)
        - - - - - - - - - -
        parentstring, id of the parent node (optional)
        nodesobject or array, sidebar nodes to add
        + + + + + + + + + +
        parentstring, id of the parent node (optional)
        nodesobject or array, sidebar nodes to add
        Returns object. @@ -30,19 +30,19 @@

        Description

        parent node is not specified, new nodes will be inserted at the root level.
        -The method will return last inserted node. +The method will return last inserted node.
        If you defined the object in the following way: @@ -51,8 +51,8 @@

        Description

        w2ui['sidebar'].add('id-1', { id: 'id-1-1', text: 'Level 1-1' }); // or w2ui['sidebar'].add('id-2', [ - { id: 'id-2-1', text: 'Level 2-1' }, - { id: 'id-2-2', text: 'Level 2-2' }, - { id: 'id-2-3', text: 'Level 2-3' } + { id: 'id-2-1', text: 'Level 2-1' }, + { id: 'id-2-2', text: 'Level 2-2' }, + { id: 'id-2-3', text: 'Level 2-3' } ]); diff --git a/docs/details/w2sidebar.bottomHTML.html b/docs/details/w2sidebar.bottomHTML.html index 3717d5d9f..1f32071d7 100644 --- a/docs/details/w2sidebar.bottomHTML.html +++ b/docs/details/w2sidebar.bottomHTML.html @@ -1,7 +1,7 @@ Defines HTML on the bottom of the sidebar.
        - String, default = '' + String, default = ''
        If you set bottomHTML property it will appear on the bottom of the sidebar. The property will accept any HTML or @@ -11,13 +11,13 @@ You can define it during object creation: diff --git a/docs/details/w2sidebar.click.html b/docs/details/w2sidebar.click.html index 51232eb56..b52ba5a5a 100644 --- a/docs/details/w2sidebar.click.html +++ b/docs/details/w2sidebar.click.html @@ -1,20 +1,20 @@ Called when user clicks the node.
        - click(id, [event]) + click(id, [event])
        - - - - - - - - - -
        idstring, id of the tab
        eventobject, DOM Event object
        + + + + + + + + + +
        idstring, id of the tab
        eventobject, DOM Event object
        Returns undefined. @@ -28,16 +28,16 @@

        Description

        If you have sidebar defined in the following way: diff --git a/docs/details/w2sidebar.collapse.html b/docs/details/w2sidebar.collapse.html index d4702c334..b2f73ea7e 100644 --- a/docs/details/w2sidebar.collapse.html +++ b/docs/details/w2sidebar.collapse.html @@ -1,16 +1,16 @@ Collapses node with id.
        - collapse(id) + collapse(id)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns undefined. @@ -24,16 +24,16 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.collapseAll.html b/docs/details/w2sidebar.collapseAll.html index 2ddf9d968..92f588f4e 100644 --- a/docs/details/w2sidebar.collapseAll.html +++ b/docs/details/w2sidebar.collapseAll.html @@ -1,16 +1,16 @@ Collapses all expanded children of specified node.
        - collapseAll([parent]) + collapseAll([parent])
        - - - - - -
        parentstring, id of the sidebar node, (optional)
        + + + + + +
        parentstring, id of the sidebar node, (optional)
        Returns undefined. @@ -25,16 +25,16 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.contextMenu.html b/docs/details/w2sidebar.contextMenu.html index 939556ab4..f0efb5064 100644 --- a/docs/details/w2sidebar.contextMenu.html +++ b/docs/details/w2sidebar.contextMenu.html @@ -1,20 +1,20 @@ Called when user right clicks the node.
        - contextMenu(id, [event]) + contextMenu(id, [event])
        - - - - - - - - - -
        idstring, id of the tab
        eventobject, optional, DOM Event object
        + + + + + + + + + +
        idstring, id of the tab
        eventobject, optional, DOM Event object
        Returns undefined. @@ -29,16 +29,16 @@

        Description

        If you have sidebar defined in the following way: diff --git a/docs/details/w2sidebar.dblClick.html b/docs/details/w2sidebar.dblClick.html index 8fa3d275b..698cea85b 100644 --- a/docs/details/w2sidebar.dblClick.html +++ b/docs/details/w2sidebar.dblClick.html @@ -1,20 +1,20 @@ Called when user double clicks the node.
        - dblClick(id, [event]) + dblClick(id, [event])
        - - - - - - - - - -
        idstring, id of the tab
        eventobject, DOM Event object
        + + + + + + + + + +
        idstring, id of the tab
        eventobject, DOM Event object
        Returns undefined. @@ -28,16 +28,16 @@

        Description

        If you have sidebar defined in the following way: diff --git a/docs/details/w2sidebar.disable.html b/docs/details/w2sidebar.disable.html index e39dc5f72..855181039 100644 --- a/docs/details/w2sidebar.disable.html +++ b/docs/details/w2sidebar.disable.html @@ -1,16 +1,16 @@ Disables sidebar node or nodes with id.
        - disable(id1, [id2], ...) + disable(id1, [id2], ...)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns integer. @@ -24,13 +24,13 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.enable.html b/docs/details/w2sidebar.enable.html index 6f742ee09..e8c28daa3 100644 --- a/docs/details/w2sidebar.enable.html +++ b/docs/details/w2sidebar.enable.html @@ -1,16 +1,16 @@ Enables sidebar node or nodes with id.
        - enable(id1, [id2], ...) + enable(id1, [id2], ...)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns integer. @@ -24,13 +24,13 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.expand.html b/docs/details/w2sidebar.expand.html index f9d2b1e35..3e9c9fa4d 100644 --- a/docs/details/w2sidebar.expand.html +++ b/docs/details/w2sidebar.expand.html @@ -1,16 +1,16 @@ Expands sidebar node with id.
        - expand(id) + expand(id)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns undefined. @@ -24,16 +24,16 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.expandAll.html b/docs/details/w2sidebar.expandAll.html index 73ab5b182..e5ae22c81 100644 --- a/docs/details/w2sidebar.expandAll.html +++ b/docs/details/w2sidebar.expandAll.html @@ -1,16 +1,16 @@ Expands all collapsed children of specified node.
        - expandAll([parent]) + expandAll([parent])
        - - - - - -
        parentstring, id of the sidebar node
        + + + + + +
        parentstring, id of the sidebar node
        Returns undefined. @@ -25,16 +25,16 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.expandParents.html b/docs/details/w2sidebar.expandParents.html index 68f80a147..0185d630f 100644 --- a/docs/details/w2sidebar.expandParents.html +++ b/docs/details/w2sidebar.expandParents.html @@ -1,16 +1,16 @@ Expands each parent of the specified node.
        - expandParents(id) + expandParents(id)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns undefined. @@ -24,16 +24,16 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.get.html b/docs/details/w2sidebar.get.html index 3aed3a0f9..8e4100a31 100644 --- a/docs/details/w2sidebar.get.html +++ b/docs/details/w2sidebar.get.html @@ -1,24 +1,24 @@ Finds sidebar node with id and returns it or its index.
        - get([parent], id, [returnIndex]) + get([parent], id, [returnIndex])
        - - - - - - - - - - - - - -
        parentstring, id of the parent node (optional)
        idstring, id of the sidebar node
        returnIndexboolean, if true returns index in the items array (optional)
        + + + + + + + + + + + + + +
        parentstring, id of the parent node (optional)
        idstring, id of the sidebar node
        returnIndexboolean, if true returns index in the items array (optional)
        Returns object or integer or null. @@ -41,13 +41,13 @@

        Description

        If you defined the object in the following way: diff --git a/docs/details/w2sidebar.hide.html b/docs/details/w2sidebar.hide.html index bdec45a56..bbdda5dc4 100644 --- a/docs/details/w2sidebar.hide.html +++ b/docs/details/w2sidebar.hide.html @@ -1,16 +1,16 @@ Hides sidebar node or nodes with id.
        - hide(id1, [id2], ...) + hide(id1, [id2], ...)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns integer. @@ -25,13 +25,13 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.icon.html b/docs/details/w2sidebar.icon.html index ab30d267a..6565e9709 100644 --- a/docs/details/w2sidebar.icon.html +++ b/docs/details/w2sidebar.icon.html @@ -1,7 +1,7 @@ Default node icon.
        - String, default = '' + String, default = ''
        For any node if its icon property is not defined, then default icon will be used. @@ -20,13 +20,13 @@ diff --git a/docs/details/w2sidebar.img.html b/docs/details/w2sidebar.img.html index 72953a12c..bf4c39532 100644 --- a/docs/details/w2sidebar.img.html +++ b/docs/details/w2sidebar.img.html @@ -1,7 +1,7 @@ Default node image.
        - String, default = '' + String, default = ''
        For any node if its img property is not defined, then default img will be used. @@ -13,18 +13,18 @@ There are several default icons in w2ui.css file you can use or you can create your own css file with icons. Majority of default -icons are used in w2grid. Default icons are: +icons are used in w2grid. Default icons are:
          -
        • icon-folder
        • -
        • icon-page
        • -
        • icon-reload
        • -
        • icon-columns
        • -
        • icon-search
        • -
        • icon-add
        • -
        • icon-delete
        • -
        • icon-save
        • -
        • icon-edit
        • -
        • icon-bullet-black
        • +
        • icon-folder
        • +
        • icon-page
        • +
        • icon-reload
        • +
        • icon-columns
        • +
        • icon-search
        • +
        • icon-add
        • +
        • icon-delete
        • +
        • icon-save
        • +
        • icon-edit
        • +
        • icon-bullet-black
        The difference between img and icon is that img @@ -35,13 +35,13 @@ diff --git a/docs/details/w2sidebar.insert.html b/docs/details/w2sidebar.insert.html index 540f71eb4..98919bdd4 100644 --- a/docs/details/w2sidebar.insert.html +++ b/docs/details/w2sidebar.insert.html @@ -1,24 +1,24 @@ Inserts a node or nodes before node before.
        - insert([parent], before, nodes) + insert([parent], before, nodes)
        - - - - - - - - - - - - - -
        parentstring, id of the node (optional)
        beforestring or object, id of the node or node object
        nodesobject or array, sidebar nodes to add
        + + + + + + + + + + + + + +
        parentstring, id of the node (optional)
        beforestring or object, id of the node or node object
        nodesobject or array, sidebar nodes to add
        Returns object. @@ -34,7 +34,7 @@

        Description

        The first optional argument parent is an id of the parent node or parent node itself. If parent node is not specified, new nodes will be inserted to the parent of the before node.
        - + New nodes will be inserted before node before, which is an id of the node or node object. If you want to append nodes, the before argument should be null. You can also use .add() method. @@ -46,13 +46,13 @@

        Description

        If you defined the object in the following way: @@ -61,8 +61,8 @@

        Description

        w2ui['sidebar'].insert('id-2', { id: 'id-1-1', text: 'Level 1-1' }); // or w2ui['sidebar'].insert('id-3', [ - { id: 'id-2-1', text: 'Level 2-1' }, - { id: 'id-2-2', text: 'Level 2-2' }, - { id: 'id-2-3', text: 'Level 2-3' } + { id: 'id-2-1', text: 'Level 2-1' }, + { id: 'id-2-2', text: 'Level 2-2' }, + { id: 'id-2-3', text: 'Level 2-3' } ]); diff --git a/docs/details/w2sidebar.keyboard.html b/docs/details/w2sidebar.keyboard.html index b551ac4d1..42e6be27c 100644 --- a/docs/details/w2sidebar.keyboard.html +++ b/docs/details/w2sidebar.keyboard.html @@ -1,32 +1,32 @@ Indicates if sidebar should listen to keyboard.
        - Boolean, default = true + Boolean, default = true
        If .keyboard property is set to true, the sidebar will add event listener to listen for keyboard events. There are several keyboard keys linked to the sidebar actions:
          -
        • Arrow up - previous node
        • -
        • Arrow down - next node
        • -
        • Arrow right - expand node
        • -
        • Arrow left - collapse node
        • +
        • Arrow up - previous node
        • +
        • Arrow down - next node
        • +
        • Arrow right - expand node
        • +
        • Arrow left - collapse node
        This property can be defined during object creation: diff --git a/docs/details/w2sidebar.keydown.html b/docs/details/w2sidebar.keydown.html index be7178fc2..852a1b20d 100644 --- a/docs/details/w2sidebar.keydown.html +++ b/docs/details/w2sidebar.keydown.html @@ -1,16 +1,16 @@ Processes keydown events.
        - keydown(event) + keydown(event)
        - - - - - -
        eventDOM Event, event object corresponding to keydown event
        + + + + + +
        eventDOM Event, event object corresponding to keydown event
        Returns undefined. @@ -24,15 +24,15 @@

        Description

        This method can be overwritten: \ No newline at end of file diff --git a/docs/details/w2sidebar.lock.html b/docs/details/w2sidebar.lock.html index 7201c7535..c31e37553 100644 --- a/docs/details/w2sidebar.lock.html +++ b/docs/details/w2sidebar.lock.html @@ -1,20 +1,20 @@ Locks the sidebar.
        - lock(message, [showSpinner]) + lock(message, [showSpinner])
        - - - - - - - - - -
        messagestring, message
        showSpinnerboolean, optional, spinner indicator
        + + + + + + + + + +
        messagestring, message
        showSpinnerboolean, optional, spinner indicator
        Returns undefined. @@ -29,13 +29,13 @@

        Description

        If you have following sidebar: diff --git a/docs/details/w2sidebar.menu.html b/docs/details/w2sidebar.menu.html index 44a7d1faf..26f0975d0 100644 --- a/docs/details/w2sidebar.menu.html +++ b/docs/details/w2sidebar.menu.html @@ -1,37 +1,37 @@ Context menu for the sidebar.
        - Array, default = [] + Array, default = []
        You can use this property if you want to define a context menu for the sidebar. Internally, context menu is implemented using $().w2menu plugin that similar to $().w2overlay() and located in w2utils. This array holds objects of the following structure: You can define it during object creation: @@ -39,8 +39,8 @@ \ No newline at end of file diff --git a/docs/details/w2sidebar.menuClick.html b/docs/details/w2sidebar.menuClick.html index bb8cdf672..d564c5c5c 100644 --- a/docs/details/w2sidebar.menuClick.html +++ b/docs/details/w2sidebar.menuClick.html @@ -1,24 +1,24 @@ Called when user select item from context menu.
        - menuClick(id, index, [event]) + menuClick(id, index, [event])
        - - - - - - - - - - - - - -
        idstring, id of the tab
        indexinteger, index of the item in the menu
        eventobject, optional, DOM Event object
        + + + + + + + + + + + + + +
        idstring, id of the tab
        indexinteger, index of the item in the menu
        eventobject, optional, DOM Event object
        Returns undefined. @@ -32,21 +32,21 @@

        Description

        If you have sidebar defined in the following way: diff --git a/docs/details/w2sidebar.nodes.html b/docs/details/w2sidebar.nodes.html index fc1db839c..66f6396f2 100644 --- a/docs/details/w2sidebar.nodes.html +++ b/docs/details/w2sidebar.nodes.html @@ -1,35 +1,35 @@ Array of node objects.
        - Array, default = [] + Array, default = []
        This array contains all the node objects of the sidebar. Each node object may in turn contain other nodes thus allowing unlimited nestedness. A node object has following structure: @@ -37,13 +37,13 @@ diff --git a/docs/details/w2sidebar.onClick.html b/docs/details/w2sidebar.onClick.html index 501a2544b..f0439dd35 100644 --- a/docs/details/w2sidebar.onClick.html +++ b/docs/details/w2sidebar.onClick.html @@ -1,22 +1,22 @@ Called when user clicks the node.
        - onClick = function(event) + onClick = function(event)
        You can add event listener during the object creation: @@ -24,7 +24,7 @@ diff --git a/docs/details/w2sidebar.onCollapse.html b/docs/details/w2sidebar.onCollapse.html index 482e5102d..4a5719f7d 100644 --- a/docs/details/w2sidebar.onCollapse.html +++ b/docs/details/w2sidebar.onCollapse.html @@ -1,22 +1,22 @@ Called when user collapses sub-nodes of the node.
        - onCollapse = function(event) + onCollapse = function(event)
        You can add event listener during the object creation: @@ -24,7 +24,7 @@ diff --git a/docs/details/w2sidebar.onContextMenu.html b/docs/details/w2sidebar.onContextMenu.html index cf16a8ad8..9decd477a 100644 --- a/docs/details/w2sidebar.onContextMenu.html +++ b/docs/details/w2sidebar.onContextMenu.html @@ -1,22 +1,22 @@ Called when user clicks right mouse button on the node.
        - onContextMenu = function(event) + onContextMenu = function(event)
        You can add event listener during the object creation: @@ -24,7 +24,7 @@ diff --git a/docs/details/w2sidebar.onDblClick.html b/docs/details/w2sidebar.onDblClick.html index 60d0d0908..da76008c7 100644 --- a/docs/details/w2sidebar.onDblClick.html +++ b/docs/details/w2sidebar.onDblClick.html @@ -1,22 +1,22 @@ Called when user double clicks the node.
        - onDblClick = function(event) + onDblClick = function(event)
        You can add event listener during the object creation: @@ -24,7 +24,7 @@ diff --git a/docs/details/w2sidebar.onExpand.html b/docs/details/w2sidebar.onExpand.html index 5ca370c30..508d78bc9 100644 --- a/docs/details/w2sidebar.onExpand.html +++ b/docs/details/w2sidebar.onExpand.html @@ -1,22 +1,22 @@ Called when user expands sub-nodes of the node.
        - onExpand = function(event) + onExpand = function(event)
        You can add event listener during the object creation: @@ -24,7 +24,7 @@ diff --git a/docs/details/w2sidebar.onKeydown.html b/docs/details/w2sidebar.onKeydown.html index d25a6f836..13b916e1e 100644 --- a/docs/details/w2sidebar.onKeydown.html +++ b/docs/details/w2sidebar.onKeydown.html @@ -1,7 +1,7 @@ Called when user clicks a keyboard key and sidebar is active.
        - onKeydown = function(event) + onKeydown = function(event)
        The event will only be triggered if .keyboard property of the sidebar is true. @@ -11,15 +11,15 @@ @@ -27,7 +27,7 @@ diff --git a/docs/details/w2sidebar.onMenuClick.html b/docs/details/w2sidebar.onMenuClick.html index 167ccc135..8a70b7847 100644 --- a/docs/details/w2sidebar.onMenuClick.html +++ b/docs/details/w2sidebar.onMenuClick.html @@ -1,22 +1,22 @@ Called when user selects and item from the context menu.
        - onClick = function(event) + onClick = function(event)
        You can add event listener during the object creation: @@ -24,7 +24,7 @@ diff --git a/docs/details/w2sidebar.parent.html b/docs/details/w2sidebar.parent.html index 386600923..29d376747 100644 --- a/docs/details/w2sidebar.parent.html +++ b/docs/details/w2sidebar.parent.html @@ -1,7 +1,7 @@ Reference to parent node. Read Only.
        - null + null
        Nodes in w2sidebar can be nested indefinitely. The object itself becomes the root node. In order to allow pretty recursive diff --git a/docs/details/w2sidebar.remove.html b/docs/details/w2sidebar.remove.html index 7fdc7854e..d38d4b9a7 100644 --- a/docs/details/w2sidebar.remove.html +++ b/docs/details/w2sidebar.remove.html @@ -1,16 +1,16 @@ Removes nodes from the sidebar.
        - remove(id1, id2, ...) + remove(id1, id2, ...)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns integer. @@ -26,12 +26,12 @@

        Description

        If you have sidebar defined in the following way: diff --git a/docs/details/w2sidebar.scrollIntoView.html b/docs/details/w2sidebar.scrollIntoView.html index 7e2e49e1b..0d0e29769 100644 --- a/docs/details/w2sidebar.scrollIntoView.html +++ b/docs/details/w2sidebar.scrollIntoView.html @@ -1,16 +1,16 @@ Scroll nodes into view
        - scrollIntoView([id]) + scrollIntoView([id])
        - - - - - -
        idstring, optional, id of the sidebar node
        + + + + + +
        idstring, optional, id of the sidebar node
        Returns undefined. @@ -25,12 +25,12 @@

        Description

        If you have sidebar defined in the following way: diff --git a/docs/details/w2sidebar.select.html b/docs/details/w2sidebar.select.html index f7bbf39fe..d7b20bcd9 100644 --- a/docs/details/w2sidebar.select.html +++ b/docs/details/w2sidebar.select.html @@ -1,16 +1,16 @@ Selects sidebar node with id.
        - select(id) + select(id)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns undefined. @@ -26,13 +26,13 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.selected.html b/docs/details/w2sidebar.selected.html index 22fa2c401..7b60fde69 100644 --- a/docs/details/w2sidebar.selected.html +++ b/docs/details/w2sidebar.selected.html @@ -1,7 +1,7 @@ The id of the selected node. Read Only.
        - String, default = '' + String, default = ''
        Each node has .selected property that determines if the node is selected. It is time consuming @@ -14,13 +14,13 @@ diff --git a/docs/details/w2sidebar.set.html b/docs/details/w2sidebar.set.html index 45f11df93..b3770642a 100644 --- a/docs/details/w2sidebar.set.html +++ b/docs/details/w2sidebar.set.html @@ -1,24 +1,24 @@ Finds sidebar node with id and extends it with node object.
        - set([parent], id, node) + set([parent], id, node)
        - - - - - - - - - - - - - -
        parentstring, id of the parent node (optional)
        idstring, id of the sidebar node
        nodeobject, new sidebar node object
        + + + + + + + + + + + + + +
        parentstring, id of the parent node (optional)
        idstring, id of the sidebar node
        nodeobject, new sidebar node object
        Returns boolean. @@ -39,13 +39,13 @@

        Description

        If you defined the object in the following way: diff --git a/docs/details/w2sidebar.show.html b/docs/details/w2sidebar.show.html index 1aac3369c..95876cf80 100644 --- a/docs/details/w2sidebar.show.html +++ b/docs/details/w2sidebar.show.html @@ -1,16 +1,16 @@ Shows sidebar node or nodes with id.
        - show(id1, [id2], ...) + show(id1, [id2], ...)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns integer. @@ -25,13 +25,13 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.sidebar.html b/docs/details/w2sidebar.sidebar.html index 75519ee25..2fd83d877 100644 --- a/docs/details/w2sidebar.sidebar.html +++ b/docs/details/w2sidebar.sidebar.html @@ -1,7 +1,7 @@ Reference to itself. Read Only.
        - Object + Object
        Nodes in w2sidebar can be nested indefinitely. The object itself becomes the root node. In order to allow pretty recursive diff --git a/docs/details/w2sidebar.toggle.html b/docs/details/w2sidebar.toggle.html index 4c791435f..06bf6369a 100644 --- a/docs/details/w2sidebar.toggle.html +++ b/docs/details/w2sidebar.toggle.html @@ -1,16 +1,16 @@ Toggles sidebar node with id.
        - toggle(id) + toggle(id)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns undefined. @@ -25,16 +25,16 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2sidebar.topHTML.html b/docs/details/w2sidebar.topHTML.html index 8de97dccb..3041981be 100644 --- a/docs/details/w2sidebar.topHTML.html +++ b/docs/details/w2sidebar.topHTML.html @@ -1,7 +1,7 @@ Defines HTML on the top of the sidebar.
        - String, default = '' + String, default = ''
        If you set topHTML property it will appear on the top of the sidebar. The property will accept any HTML or @@ -11,13 +11,13 @@ You can define it during object creation: diff --git a/docs/details/w2sidebar.unlock.html b/docs/details/w2sidebar.unlock.html index 668a94822..8ad984ea2 100644 --- a/docs/details/w2sidebar.unlock.html +++ b/docs/details/w2sidebar.unlock.html @@ -1,7 +1,7 @@ Unlocks the sidebar.
        - unlock() + unlock()
        Returns undefined. @@ -11,17 +11,17 @@

        Description

        This method will unlock the sidebar previously locked with .lock() method. This method will call w2utils.unlock() to perform the action.
        - + If you have following sidebar: diff --git a/docs/details/w2sidebar.unselect.html b/docs/details/w2sidebar.unselect.html index 8d9e1e2ec..76b6a45be 100644 --- a/docs/details/w2sidebar.unselect.html +++ b/docs/details/w2sidebar.unselect.html @@ -1,16 +1,16 @@ Unselects sidebar node with id.
        - unselect(id) + unselect(id)
        - - - - - -
        idstring, id of the sidebar node
        + + + + + +
        idstring, id of the sidebar node
        Returns boolean. @@ -25,13 +25,13 @@

        Description

        If you have defined object in the following way: diff --git a/docs/details/w2tabs.active.html b/docs/details/w2tabs.active.html index 85646a32a..0a3908a77 100644 --- a/docs/details/w2tabs.active.html +++ b/docs/details/w2tabs.active.html @@ -1,7 +1,7 @@ Id of the active tab.
        - String, default = '' + String, default = ''
        There can only be one active tab. If you change this property, you will need to call .refresh() @@ -11,14 +11,14 @@ Active tab can be defined during object creation: diff --git a/docs/details/w2tabs.add.html b/docs/details/w2tabs.add.html index 4989c2038..6fb504e2f 100644 --- a/docs/details/w2tabs.add.html +++ b/docs/details/w2tabs.add.html @@ -1,16 +1,16 @@ Adds a tab or tabs.
        - add(tabs) + add(tabs)
        - - - - - -
        tabsobject or array, tab or array of tabs
        + + + + + +
        tabsobject or array, tab or array of tabs
        Returns undefined. @@ -21,18 +21,18 @@

        Description

        represents a tab object that will be added to .tabs array. If it is an array then each element of the array will be treated as a separate tab object.
        - + If you have tabs defined in the following way: @@ -41,8 +41,8 @@

        Description

        w2ui['tabs'].add({ id: 'tab5', caption: 'Tab 5' }); // or w2ui['tabs'].add([ - { id: 'tab6', caption: 'Tab 6' }, - { id: 'tab7', caption: 'Tab 7' }, - { id: 'tab8', caption: 'Tab 8' } + { id: 'tab6', caption: 'Tab 6' }, + { id: 'tab7', caption: 'Tab 7' }, + { id: 'tab8', caption: 'Tab 8' } ]); diff --git a/docs/details/w2tabs.animateClose.html b/docs/details/w2tabs.animateClose.html index af6722902..1abf02883 100644 --- a/docs/details/w2tabs.animateClose.html +++ b/docs/details/w2tabs.animateClose.html @@ -1,20 +1,20 @@ Removes and animates closing of the tab.
        - animateClose(id, [event]) + animateClose(id, [event])
        - - - - - - - - - -
        idstring, id of tab to close
        eventobject or array, tab or array of tabs
        + + + + + + + + + +
        idstring, id of tab to close
        eventobject or array, tab or array of tabs
        Returns undefined. @@ -22,18 +22,18 @@

        Description

        This method will remove and animate closing of the tab with id = id. - + If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.animateInsert.html b/docs/details/w2tabs.animateInsert.html index 1db506a38..47612256f 100644 --- a/docs/details/w2tabs.animateInsert.html +++ b/docs/details/w2tabs.animateInsert.html @@ -1,20 +1,20 @@ Add and animates insertion a tab or tabs.
        - animateInsert(before, tabs) + animateInsert(before, tabs)
        - - - - - - - - - -
        beforestring, id of tab to insert before
        tabsobject or array, tab or array of tabs
        + + + + + + + + + +
        beforestring, id of tab to insert before
        tabsobject or array, tab or array of tabs
        Returns undefined. @@ -22,18 +22,18 @@

        Description

        This method will first animate inserting of the space before tab with id = before and then will call .insert() to insert the tab and display it. - + If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.click.html b/docs/details/w2tabs.click.html index b59c7a670..a812ad53c 100644 --- a/docs/details/w2tabs.click.html +++ b/docs/details/w2tabs.click.html @@ -1,20 +1,20 @@ Called when user clicks the tab.
        - click(id, [event]) + click(id, [event])
        - - - - - - - - - -
        idstring, id of the tab
        eventobject, DOM Event object
        + + + + + + + + + +
        idstring, id of the tab
        eventobject, DOM Event object
        Returns undefined. @@ -28,14 +28,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.disable.html b/docs/details/w2tabs.disable.html index e2e945918..3a9381550 100644 --- a/docs/details/w2tabs.disable.html +++ b/docs/details/w2tabs.disable.html @@ -1,16 +1,16 @@ Disables a tab or tabs.
        - disable(id1, [id2], ...) + disable(id1, [id2], ...)
        - - - - - -
        idstring, id of the tab
        + + + + + +
        idstring, id of the tab
        Returns integer. @@ -24,14 +24,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.enable.html b/docs/details/w2tabs.enable.html index 97cf74ec4..0628ff939 100644 --- a/docs/details/w2tabs.enable.html +++ b/docs/details/w2tabs.enable.html @@ -1,16 +1,16 @@ Enables a tab or tabs.
        - enable(id1, [id2], ...) + enable(id1, [id2], ...)
        - - - - - -
        idstring, id of the tab
        + + + + + +
        idstring, id of the tab
        Returns integer. @@ -24,14 +24,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.get.html b/docs/details/w2tabs.get.html index c63802e6f..b890e935a 100644 --- a/docs/details/w2tabs.get.html +++ b/docs/details/w2tabs.get.html @@ -1,20 +1,20 @@ Finds and returns specified tab.
        - get(id, [returnIndex]) + get(id, [returnIndex])
        - - - - - - - - - -
        idstring, id of the tab
        returnIndexboolean, if true returns index in the tabs array (optional)
        + + + + + + + + + +
        idstring, id of the tab
        returnIndexboolean, if true returns index in the tabs array (optional)
        Returns object or integer or null. @@ -33,14 +33,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.hide.html b/docs/details/w2tabs.hide.html index 69e36bfb9..bb62adcd0 100644 --- a/docs/details/w2tabs.hide.html +++ b/docs/details/w2tabs.hide.html @@ -1,16 +1,16 @@ Hides tab or tabs with id.
        - hide(id1, [id2], ...) + hide(id1, [id2], ...)
        - - - - - -
        idstring, id of the tab
        + + + + + +
        idstring, id of the tab
        Returns integer. @@ -25,14 +25,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.insert.html b/docs/details/w2tabs.insert.html index 30f19285b..510fb7747 100644 --- a/docs/details/w2tabs.insert.html +++ b/docs/details/w2tabs.insert.html @@ -1,20 +1,20 @@ Inserts a tab or tabs before tab with id=before
        - insert(before, tabs) + insert(before, tabs)
        - - - - - - - - - -
        beforestring, id of tab to insert before
        tabsobject or array, tab or array of tabs
        + + + + + + + + + +
        beforestring, id of tab to insert before
        tabsobject or array, tab or array of tabs
        Returns undefined. @@ -24,18 +24,18 @@

        Description

        will be appended at the end. The tabs argument can be either an object or array of objects. If it is an object it represents a tab that will be added to .tabs array. If it is an array then each element of the array will be treated as a separate tab object.
        - + If you have tabs defined in the following way: @@ -44,8 +44,8 @@

        Description

        w2ui['tabs'].insert('tab3', { id: 'tab5', caption: 'Tab 5' }); // or w2ui['tabs'].insert('tab3', [ - { id: 'tab6', caption: 'Tab 6' }, - { id: 'tab7', caption: 'Tab 7' }, - { id: 'tab8', caption: 'Tab 8' } + { id: 'tab6', caption: 'Tab 6' }, + { id: 'tab7', caption: 'Tab 7' }, + { id: 'tab8', caption: 'Tab 8' } ]); diff --git a/docs/details/w2tabs.onClick.html b/docs/details/w2tabs.onClick.html index 3926f8593..03416cd78 100644 --- a/docs/details/w2tabs.onClick.html +++ b/docs/details/w2tabs.onClick.html @@ -1,23 +1,23 @@ Called when tab is clicked.
        - onClick = function(event) + onClick = function(event)
        You can add event listener during the object creation: @@ -25,7 +25,7 @@ diff --git a/docs/details/w2tabs.onClose.html b/docs/details/w2tabs.onClose.html index 857519e87..c4e5bb73a 100644 --- a/docs/details/w2tabs.onClose.html +++ b/docs/details/w2tabs.onClose.html @@ -1,23 +1,23 @@ Called when tab is closed.
        - onClose = function(event) + onClose = function(event)
        You can add event listener during the object creation: @@ -25,7 +25,7 @@ diff --git a/docs/details/w2tabs.remove.html b/docs/details/w2tabs.remove.html index 56404110b..ec6fca301 100644 --- a/docs/details/w2tabs.remove.html +++ b/docs/details/w2tabs.remove.html @@ -1,16 +1,16 @@ Removes tabs.
        - remove(id1, [id2], ...) + remove(id1, [id2], ...)
        - - - - - -
        idstring, id of the tab
        + + + + + +
        idstring, id of the tab
        Returns integer. @@ -24,14 +24,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.right.html b/docs/details/w2tabs.right.html index 5701f15ed..90915eb4d 100644 --- a/docs/details/w2tabs.right.html +++ b/docs/details/w2tabs.right.html @@ -1,7 +1,7 @@ Defines HTML in the right corner of the tabs.
        - String, default = '' + String, default = ''
        If you set .right property it will appear in the right corner of the tabs. This property will accept @@ -11,14 +11,14 @@ You can defined it during object creation: diff --git a/docs/details/w2tabs.select.html b/docs/details/w2tabs.select.html index 425fdf985..82866fee0 100644 --- a/docs/details/w2tabs.select.html +++ b/docs/details/w2tabs.select.html @@ -1,16 +1,16 @@ Finds tab with id and makes it active.
        - select(id) + select(id)
        - - - - - -
        idstring, id of the tab object
        + + + + + +
        idstring, id of the tab object
        Return boolean. @@ -26,14 +26,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.set.html b/docs/details/w2tabs.set.html index c5058d58f..176353cfd 100644 --- a/docs/details/w2tabs.set.html +++ b/docs/details/w2tabs.set.html @@ -1,20 +1,20 @@ Finds tab with id and extends it with tab object.
        - set(id, tab) + set(id, tab)
        - - - - - - - - - -
        idstring, id of the tab object
        tabobject, new tab object
        + + + + + + + + + +
        idstring, id of the tab object
        tabobject, new tab object
        Returns boolean. @@ -31,14 +31,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.show.html b/docs/details/w2tabs.show.html index 591cf69cb..bf5d06b22 100644 --- a/docs/details/w2tabs.show.html +++ b/docs/details/w2tabs.show.html @@ -1,16 +1,16 @@ Shows tab or tabs with id.
        - show(id1, [id2], ...) + show(id1, [id2], ...)
        - - - - - -
        idstring, id of the tab
        + + + + + +
        idstring, id of the tab
        Returns integer. @@ -24,14 +24,14 @@

        Description

        If you have tabs defined in the following way: diff --git a/docs/details/w2tabs.tabs.html b/docs/details/w2tabs.tabs.html index 4139b44b9..e9bf9aac5 100644 --- a/docs/details/w2tabs.tabs.html +++ b/docs/details/w2tabs.tabs.html @@ -1,33 +1,33 @@ Array of tab objects.
        - Array, default = [] + Array, default = []
        This array contains all the tab objects. A tab object has the following structure: You can defined them during object creation: diff --git a/docs/details/w2toolbar.add.html b/docs/details/w2toolbar.add.html index 5cbea39bf..ac6372d75 100644 --- a/docs/details/w2toolbar.add.html +++ b/docs/details/w2toolbar.add.html @@ -1,16 +1,16 @@ Adds a toolbar item or items.
        - add(items) + add(items)
        - - - - - -
        itemsobject or array, toolbar items to add
        + + + + + +
        itemsobject or array, toolbar items to add
        Returns undefined. @@ -21,16 +21,16 @@

        Description

        represents a toolbar item that will be added to .items array. If it is an array then each element of the array will be treated as a separate toolbar item object.
        - + If you have toolbar defined in the following way: @@ -39,8 +39,8 @@

        Description

        w2ui['toolbar'].add({ type: 'radio', id: 'item31', group: '1', caption: 'Radio 3', img: 'icon-add' }); // or w2ui['toolbar'].add([ - { type: 'radio', id: 'item5', group: '1', caption: 'Radio 5', img: 'icon-add' }, - { type: 'radio', id: 'item6', group: '1', caption: 'Radio 6', img: 'icon-add' }, - { type: 'radio', id: 'item7', group: '1', caption: 'Radio 7', img: 'icon-add' }, + { type: 'radio', id: 'item5', group: '1', caption: 'Radio 5', img: 'icon-add' }, + { type: 'radio', id: 'item6', group: '1', caption: 'Radio 6', img: 'icon-add' }, + { type: 'radio', id: 'item7', group: '1', caption: 'Radio 7', img: 'icon-add' }, ]); diff --git a/docs/details/w2toolbar.check.html b/docs/details/w2toolbar.check.html index 429c3687f..826def69a 100644 --- a/docs/details/w2toolbar.check.html +++ b/docs/details/w2toolbar.check.html @@ -1,16 +1,16 @@ Checks toolbar item or items with id (visually looks like pressed button).
        - check(id1, [id2], ...) + check(id1, [id2], ...)
        - - - - - -
        idstring, id of the toolbar item
        + + + + + +
        idstring, id of the toolbar item
        Returns integer. @@ -25,12 +25,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.click.html b/docs/details/w2toolbar.click.html index 3f54cb6a8..484be2ffc 100644 --- a/docs/details/w2toolbar.click.html +++ b/docs/details/w2toolbar.click.html @@ -1,20 +1,20 @@ Called when user clicks on a toolbar item.
        - click(id, [event]) + click(id, [event])
        - - - - - - - - - -
        idstring, id of the toolbar item
        eventobject, DOM Event object
        + + + + + + + + + +
        idstring, id of the toolbar item
        eventobject, DOM Event object
        Returns undefined. @@ -28,12 +28,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.disable.html b/docs/details/w2toolbar.disable.html index a2379f4b9..1a64d77f6 100644 --- a/docs/details/w2toolbar.disable.html +++ b/docs/details/w2toolbar.disable.html @@ -1,16 +1,16 @@ Disables toolbar item or items with id.
        - disable(id1, [id2], ...) + disable(id1, [id2], ...)
        - - - - - -
        idstring, id of the toolbar item
        + + + + + +
        idstring, id of the toolbar item
        Returns integer. @@ -25,12 +25,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.enable.html b/docs/details/w2toolbar.enable.html index c3e3ca64b..497c0482f 100644 --- a/docs/details/w2toolbar.enable.html +++ b/docs/details/w2toolbar.enable.html @@ -1,16 +1,16 @@ Enables toolbar item or items with id.
        - enable(id1, [id2], ...) + enable(id1, [id2], ...)
        - - - - - -
        idstring, id of the toolbar item
        + + + + + +
        idstring, id of the toolbar item
        Returns integer. @@ -25,12 +25,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.get.html b/docs/details/w2toolbar.get.html index 894d8e95d..9cfc8ed98 100644 --- a/docs/details/w2toolbar.get.html +++ b/docs/details/w2toolbar.get.html @@ -1,20 +1,20 @@ Finds toolbar item with id and returns it or its index.
        - get(id, [returnIndex]) + get(id, [returnIndex])
        - - - - - - - - - -
        idstring, id of the toolbar item
        returnIndexboolean, if true returns index in the items array (optional)
        + + + + + + + + + +
        idstring, id of the toolbar item
        returnIndexboolean, if true returns index in the items array (optional)
        Returns object or integer or null. @@ -32,13 +32,13 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.getItemHTML.html b/docs/details/w2toolbar.getItemHTML.html index 0f025693f..ae641fe9d 100644 --- a/docs/details/w2toolbar.getItemHTML.html +++ b/docs/details/w2toolbar.getItemHTML.html @@ -1,16 +1,16 @@ Generates HTML for the toolbar item.
        - getItemHTML(item) + getItemHTML(item)
        - - - - - -
        itemobject, toolbar item object
        + + + + + +
        itemobject, toolbar item object
        Returns HTML string. @@ -25,13 +25,13 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.hide.html b/docs/details/w2toolbar.hide.html index df724aaa5..cfde50ac2 100644 --- a/docs/details/w2toolbar.hide.html +++ b/docs/details/w2toolbar.hide.html @@ -1,16 +1,16 @@ Hides toolbar item or items with id.
        - hide(id1, [id2], ...) + hide(id1, [id2], ...)
        - - - - - -
        idstring, id of the toolbar item
        + + + + + +
        idstring, id of the toolbar item
        Returns integer. @@ -24,12 +24,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.insert.html b/docs/details/w2toolbar.insert.html index fde0b3374..db1d15954 100644 --- a/docs/details/w2toolbar.insert.html +++ b/docs/details/w2toolbar.insert.html @@ -1,20 +1,20 @@ Inserts a toolbar item or items before item with id=before.
        - insert(before, items) + insert(before, items)
        - - - - - - - - - -
        beforestring, id of the item to insert before
        itemsobject or array, toolbar items to add
        + + + + + + + + + +
        beforestring, id of the item to insert before
        itemsobject or array, toolbar items to add
        Returns undefined. @@ -26,16 +26,16 @@

        Description

        represents a toolbar item that will be added to .items array. If it is an array then each element of the array will be treated as a separate toolbar item object.
        - + If you have toolbar defined in the following way: @@ -44,8 +44,8 @@

        Description

        w2ui['toolbar'].insert('item3', { type: 'check', id: 'item31', caption: 'Check 2', img: 'icon-page' }); // or w2ui['toolbar'].insert('item3', [ - { type: 'radio', id: 'item5', group: '1', caption: 'Radio 5', img: 'icon-add' }, - { type: 'radio', id: 'item6', group: '1', caption: 'Radio 6', img: 'icon-add' }, - { type: 'radio', id: 'item7', group: '1', caption: 'Radio 7', img: 'icon-add' }, + { type: 'radio', id: 'item5', group: '1', caption: 'Radio 5', img: 'icon-add' }, + { type: 'radio', id: 'item6', group: '1', caption: 'Radio 6', img: 'icon-add' }, + { type: 'radio', id: 'item7', group: '1', caption: 'Radio 7', img: 'icon-add' }, ]); diff --git a/docs/details/w2toolbar.items.html b/docs/details/w2toolbar.items.html index 997c2bb6f..9cc377635 100644 --- a/docs/details/w2toolbar.items.html +++ b/docs/details/w2toolbar.items.html @@ -1,7 +1,7 @@ Array of the item objects.
        - Array, default = [] + Array, default = []
        The .items property defines all toolbar items (buttons, drop down menues, etc.) You @@ -9,13 +9,13 @@ @@ -28,66 +28,66 @@ An item object has the following structure: There are 7 types of toolbar items - - - - - - - - - + + There are several default icons in w2ui.css file you can use or you can create your own css file with icons. Majority of + default icons are used in w2grid. Default icons are: + icon-folder, + icon-page, + icon-reload, + icon-columns, + icon-search, + icon-add, + icon-delete, + icon-save, + icon-edit, + icon-bullet-black + + + +
        button regular button
        check check button (2 states: checked and unchecked. See .checked property.
        radio radio button, similar to check button but other buttons in the group will be unchecked. See .checked and .group property
        drop simple drop down, whatever in .html property will be display in the drop down
        menu drop down menu. The .items property will be treated as menu items. This property - either an array of strings or array of objects. If it is array of string, then each element of the array is a menu item. If it is array of - object, then each element of the array is an object of the following type: - - There are several default icons in w2ui.css file you can use or you can create your own css file with icons. Majority of - default icons are used in w2grid. Default icons are: - icon-folder, - icon-page, - icon-reload, - icon-columns, - icon-search, - icon-add, - icon-delete, - icon-save, - icon-edit, - icon-bullet-black -
        html html item, this html will be displayed instead of the toolbar item
        break vertical separator
        spacer horizontal spacer, will push all following buttons to the right hand side
        html html item, this html will be displayed instead of the toolbar item
        break vertical separator
        spacer horizontal spacer, will push all following buttons to the right hand side
        \ No newline at end of file diff --git a/docs/details/w2toolbar.menuClick.html b/docs/details/w2toolbar.menuClick.html index 01a7c1414..8b2ab61f0 100644 --- a/docs/details/w2toolbar.menuClick.html +++ b/docs/details/w2toolbar.menuClick.html @@ -1,24 +1,24 @@ Called when user selects an item from a drop down menu.
        - menuClick(id, menu_index, [event]) + menuClick(id, menu_index, [event])
        - - - - - - - - - - - - - -
        idstring, id of the toolbar item
        menu_indexinteger, index of the clicked item in the menu array
        eventobject, DOM Event object
        + + + + + + + + + + + + + +
        idstring, id of the toolbar item
        menu_indexinteger, index of the clicked item in the menu array
        eventobject, DOM Event object
        Returns undefined. @@ -32,13 +32,13 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.onClick.html b/docs/details/w2toolbar.onClick.html index ad2b9b39b..63a802744 100644 --- a/docs/details/w2toolbar.onClick.html +++ b/docs/details/w2toolbar.onClick.html @@ -1,22 +1,22 @@ Called when toolbar item is clicked.
        - onClick = function(event) + onClick = function(event)
        You can add event listener during the object creation: @@ -24,7 +24,7 @@ diff --git a/docs/details/w2toolbar.remove.html b/docs/details/w2toolbar.remove.html index 3a6adee04..6f5b006a7 100644 --- a/docs/details/w2toolbar.remove.html +++ b/docs/details/w2toolbar.remove.html @@ -1,16 +1,16 @@ Removes items from the toolbar.
        - remove(id1, [id2], ...) + remove(id1, [id2], ...)
        - - - - - -
        idstring, id of the toolbar item
        + + + + + +
        idstring, id of the toolbar item
        Returns integer. @@ -24,12 +24,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.right.html b/docs/details/w2toolbar.right.html index fb51bc196..d2672bcdf 100644 --- a/docs/details/w2toolbar.right.html +++ b/docs/details/w2toolbar.right.html @@ -1,7 +1,7 @@ Defines HTML in the right corner of the toolbar.
        - String, default = '' + String, default = ''
        If you set .right property it will appear in the right corner of the toolbar. You can also render buttons @@ -11,13 +11,13 @@ You can defined it during object creation: diff --git a/docs/details/w2toolbar.set.html b/docs/details/w2toolbar.set.html index a18477361..054a4a1c7 100644 --- a/docs/details/w2toolbar.set.html +++ b/docs/details/w2toolbar.set.html @@ -1,20 +1,20 @@ Finds toolbar item with id and extends it with item object.
        - set(id, item) + set(id, item)
        - - - - - - - - - -
        idstring, id of the toolbar item
        itemobject, new toolbar item object
        + + + + + + + + + +
        idstring, id of the toolbar item
        itemobject, new toolbar item object
        Returns boolean. @@ -31,12 +31,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.show.html b/docs/details/w2toolbar.show.html index f99786fd6..8eef127b6 100644 --- a/docs/details/w2toolbar.show.html +++ b/docs/details/w2toolbar.show.html @@ -1,16 +1,16 @@ Shows toolbar item or items with id.
        - show(id1, [id2], ...) + show(id1, [id2], ...)
        - - - - - -
        idstring, id of the toolbar item
        + + + + + +
        idstring, id of the toolbar item
        Returns integer. @@ -25,12 +25,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2toolbar.uncheck.html b/docs/details/w2toolbar.uncheck.html index 215f3a7e4..885f36d1d 100644 --- a/docs/details/w2toolbar.uncheck.html +++ b/docs/details/w2toolbar.uncheck.html @@ -1,16 +1,16 @@ Unchecks toolbar item or items with id (visually looks like pressed button).
        - uncheck(id1, [id2], ...) + uncheck(id1, [id2], ...)
        - - - - - -
        idstring, id of the toolbar item
        + + + + + +
        idstring, id of the toolbar item
        Returns integer. @@ -24,12 +24,12 @@

        Description

        If you have toolbar defined in the following way: diff --git a/docs/details/w2utils.age.html b/docs/details/w2utils.age.html index 3500bdb8e..e01b609dd 100644 --- a/docs/details/w2utils.age.html +++ b/docs/details/w2utils.age.html @@ -1,16 +1,16 @@ Returns age in human readable format.
        - w2utils.age(dateStr) + w2utils.age(dateStr)
        - - - - - -
        dateStrstring or number, date in common format
        + + + + + +
        dateStrstring or number, date in common format
        The dateStr argument can be any standard date or unix epoch, which is used to create JavaScript diff --git a/docs/details/w2utils.base64decode.html b/docs/details/w2utils.base64decode.html index 888a19679..1f3165d69 100644 --- a/docs/details/w2utils.base64decode.html +++ b/docs/details/w2utils.base64decode.html @@ -1,16 +1,16 @@ Decodes string using base64 method.
        - w2utils.base64decode(str) + w2utils.base64decode(str)
        - - - - - -
        strstring, string to decode
        + + + + + +
        strstring, string to decode
        Returns decoded string. diff --git a/docs/details/w2utils.base64encode.html b/docs/details/w2utils.base64encode.html index 09932d928..5c6aaea0d 100644 --- a/docs/details/w2utils.base64encode.html +++ b/docs/details/w2utils.base64encode.html @@ -1,16 +1,16 @@ Encodes string using base64 method.
        - w2utils.base64encode(str) + w2utils.base64encode(str)
        - - - - - -
        strstring, string to encode
        + + + + + +
        strstring, string to encode
        Returns encoded string. diff --git a/docs/details/w2utils.date.html b/docs/details/w2utils.date.html index 64f1dcc4b..b33ac213b 100644 --- a/docs/details/w2utils.date.html +++ b/docs/details/w2utils.date.html @@ -1,16 +1,16 @@ Returns date in human readable format.
        - w2utils.date(dateStr) + w2utils.date(dateStr)
        - - - - - -
        dateStrstring or number, date in common format
        + + + + + +
        dateStrstring or number, date in common format
        The str argument can be any standard date or unix epoch, which is used to diff --git a/docs/details/w2utils.encodeTags.html b/docs/details/w2utils.encodeTags.html index 4c658cccb..65fe0ff1b 100644 --- a/docs/details/w2utils.encodeTags.html +++ b/docs/details/w2utils.encodeTags.html @@ -1,16 +1,16 @@ Encodes HTML tags.
        - w2utils.encodeTags(str) + w2utils.encodeTags(str)
        - - - - - -
        dateStrstring, string to encode
        + + + + + +
        dateStrstring, string to encode
        The first str argument should be a string. The method will encode HTML tags (into &gt; &lt; &amp; etc.) and diff --git a/docs/details/w2utils.escapeId.html b/docs/details/w2utils.escapeId.html index cea69cf81..af06aa9c4 100644 --- a/docs/details/w2utils.escapeId.html +++ b/docs/details/w2utils.escapeId.html @@ -1,16 +1,16 @@ Escapes id for the use in jQuery.
        - w2utils.escapeId(id) + w2utils.escapeId(id)
        - - - - - -
        idstring, id to escape
        + + + + + +
        idstring, id to escape
        If you use jQuery to want to use "!"#$%&\'()*+,./:;<=>?@[\]^`{|}~ " in element ids you need to escape them. diff --git a/docs/details/w2utils.event.html b/docs/details/w2utils.event.html index 52fb14c62..3a99b6dd3 100644 --- a/docs/details/w2utils.event.html +++ b/docs/details/w2utils.event.html @@ -1,7 +1,7 @@ An object to work with custom events.
        - w2utils.event - object + w2utils.event - object
        This method is used internally to provide funcitonality for all other widgets and have on, off, trigger functions for the events. \ No newline at end of file diff --git a/docs/details/w2utils.formatDate.html b/docs/details/w2utils.formatDate.html index 48ec889a8..06559ab79 100644 --- a/docs/details/w2utils.formatDate.html +++ b/docs/details/w2utils.formatDate.html @@ -1,20 +1,20 @@ Returns date in requested format.
        - w2utils.formatDate(dateStr, format) + w2utils.formatDate(dateStr, format)
        - - - - - - - - - -
        dateStrstring or number, date in common format
        formatstring, format to output
        + + + + + + + + + +
        dateStrstring or number, date in common format
        formatstring, format to output
        The str argument can be any standard date or unix epoch, which is used to diff --git a/docs/details/w2utils.formatDateTime.html b/docs/details/w2utils.formatDateTime.html index 5ea5c3702..757cb2b96 100644 --- a/docs/details/w2utils.formatDateTime.html +++ b/docs/details/w2utils.formatDateTime.html @@ -1,20 +1,20 @@ Returns date and time in requested format.
        - w2utils.formatDateTime(dateStr, format) + w2utils.formatDateTime(dateStr, format)
        - - - - - - - - - -
        dateStrstring or number, date in common format
        formatstring, format to output
        + + + + + + + + + +
        dateStrstring or number, date in common format
        formatstring, format to output
        The str argument can be any standard date or unix epoch, which is used to diff --git a/docs/details/w2utils.formatNumber.html b/docs/details/w2utils.formatNumber.html index 104caf4b6..83823c6e4 100644 --- a/docs/details/w2utils.formatNumber.html +++ b/docs/details/w2utils.formatNumber.html @@ -1,16 +1,16 @@ Formats a number adding commas.
        - w2utils.formatNumber(val) + w2utils.formatNumber(val)
        - - - - - -
        valstring or number, a number to format
        + + + + + +
        valstring or number, a number to format
        The val argument can be an integer, float on in money format. The method will add commas after each there diff --git a/docs/details/w2utils.formatTime.html b/docs/details/w2utils.formatTime.html index 827ef4cc7..39e142094 100644 --- a/docs/details/w2utils.formatTime.html +++ b/docs/details/w2utils.formatTime.html @@ -1,20 +1,20 @@ Returns time in requested format.
        - w2utils.formatTime(dateStr, format) + w2utils.formatTime(dateStr, format)
        - - - - - - - - - -
        dateStrstring or number, date in common format
        formatstring, format to output
        + + + + + + + + + +
        dateStrstring or number, date in common format
        formatstring, format to output
        The str argument can be any standard date or unix epoch, which is used to diff --git a/docs/details/w2utils.getSize.html b/docs/details/w2utils.getSize.html index b36cb0371..d09d2674a 100644 --- a/docs/details/w2utils.getSize.html +++ b/docs/details/w2utils.getSize.html @@ -1,34 +1,34 @@ Returns the size or absolute position of the element in px including padding, margin and border.
        - w2utils.getSize(el, type) + w2utils.getSize(el, type)
        - - - - - - - - - -
        elHTML Element, element to evaluate
        typestring, size type
        + + + + + + + + + +
        elHTML Element, element to evaluate
        typestring, size type
        The element does not need to be absolutely positioned, but it absolution position is calculated. First parameter el is the element to be inspected (it can also be a jQuery object). Second parameter type can be one of the following:
          -
        • width - the width of the element
        • -
        • height - the height of the element
        • -
        • +width - addition to width (padding, margin, border)
        • -
        • +height - addition to height (padding, margin, border)
        • -
        • left - the left coordinate of the element
        • -
        • right - the right coordinate of the element
        • -
        • top - the top coordinate of the element
        • -
        • bottom - the bottom coordinate of the element
        • +
        • width - the width of the element
        • +
        • height - the height of the element
        • +
        • +width - addition to width (padding, margin, border)
        • +
        • +height - addition to height (padding, margin, border)
        • +
        • left - the left coordinate of the element
        • +
        • right - the right coordinate of the element
        • +
        • top - the top coordinate of the element
        • +
        • bottom - the bottom coordinate of the element
        diff --git a/docs/details/w2utils.size.html b/docs/details/w2utils.size.html index f5b2af5bc..2a33ba09c 100644 --- a/docs/details/w2utils.size.html +++ b/docs/details/w2utils.size.html @@ -1,16 +1,16 @@ Returns human readable file size.
        - w2utils.size(int) + w2utils.size(int)
        - - - - - -
        typestring, file size
        + + + + + +
        typestring, file size
        The method will return file size in Bt, KB, MB, GB or TB diff --git a/docs/details/w2utils.stripTags.html b/docs/details/w2utils.stripTags.html index b742f32d5..1efc548a7 100644 --- a/docs/details/w2utils.stripTags.html +++ b/docs/details/w2utils.stripTags.html @@ -1,16 +1,16 @@ Removes all HTML tags.
        - w2utils.stripTags(str) + w2utils.stripTags(str)
        - - - - - -
        strstring, HTML string to clean
        + + + + + +
        strstring, HTML string to clean

        Preview

        - - int
        - - float
        - - date
        - - color + - int
        + - float
        + - date
        + - color
        @@ -57,124 +57,124 @@

        Supported Types

        - - - - - - - - - - - - - + + + + + + + + + + + + +
        clear removes any previous type
        int integer
        float float
        hex hexdecimal
        money number in money format
        alphaNumeric alpha-numeric text
        email email address
        date date picker
        list drop down list
        select drop down list
        color color picker
        enum multi-select
        upload file upload
        clear removes any previous type
        int integer
        float float
        hex hexdecimal
        money number in money format
        alphaNumeric alpha-numeric text
        email email address
        date date picker
        list drop down list
        select drop down list
        color color picker
        enum multi-select
        upload file upload

        - Most field types are simple and require no additional parameters, however date, list, enum, etc. take extra options. Below is the - list of options those fields take:

        - date: - - list or select: - + list or select: + + - enum: - - - upload: - + + upload: + + - To send this additional options, you need to pass an object with properties when you initiate field: + To send this additional options, you need to pass an object with properties when you initiate field: - +

        Custom Types

        If built-in types are not enough for you, there is a way you can create custom types. After you defined this type, you can apply it in the following way: diff --git a/docs/overview/form.html b/docs/overview/form.html index c72fd91fe..942713ed0 100644 --- a/docs/overview/form.html +++ b/docs/overview/form.html @@ -21,23 +21,23 @@

        Complete Example 1

        @@ -60,46 +60,46 @@

        Complete Example 2

        -
        -
        First Name:
        -
        - -
        -
        Last Name:
        -
        - -
        -
        Text Area:
        -
        - <textarea name="field_textarea" style="width: 385px; height: 80px;"></textarea> -
        -
        +
        +
        First Name:
        +
        + +
        +
        Last Name:
        +
        + +
        +
        Text Area:
        +
        + <textarea name="field_textarea" style="width: 385px; height: 80px;"></textarea> +
        +
        -
        - - -
        -
        +
        + + +
        +
      diff --git a/docs/overview/grid.html b/docs/overview/grid.html index cd7c23b63..a4d8ef012 100644 --- a/docs/overview/grid.html +++ b/docs/overview/grid.html @@ -23,24 +23,24 @@

      Complete Example 1

      @@ -63,14 +63,14 @@

      Complete Example 2

      @@ -83,19 +83,19 @@

      Data Structures

      @@ -128,13 +128,13 @@

      Data Structures

      @@ -145,8 +145,8 @@

      Data Structures

      If you want to return an error from the server side, you can return following JSON structure: @@ -158,25 +158,25 @@

      Delete Records

      It sends extra fields that are not directly related to the delete operation. If there was no errors, the grid expects back the response in the format And as soon as it is received, it will submit a second request to refresh records. If the server responds: -The grid will display the error and will not refresh records. +The grid will display the error and will not refresh records.

      Save Records

      @@ -184,22 +184,22 @@

      Save Records

      to the server: Where changed is an array of object with key value pairs of all changed records. If there was no errors, the grid expects back the response in the format If the server responds: The grid will display the error. \ No newline at end of file diff --git a/docs/overview/layout.html b/docs/overview/layout.html index 794bd36ab..dc13fd939 100644 --- a/docs/overview/layout.html +++ b/docs/overview/layout.html @@ -19,14 +19,14 @@

      Complete Example

      diff --git a/docs/overview/listview.html b/docs/overview/listview.html index d52d8c845..a6c8c8577 100644 --- a/docs/overview/listview.html +++ b/docs/overview/listview.html @@ -18,15 +18,15 @@

      Complete Example

      diff --git a/docs/overview/popup-overlays.html b/docs/overview/popup-overlays.html index 98e171e47..0c33c5d1e 100644 --- a/docs/overview/popup-overlays.html +++ b/docs/overview/popup-overlays.html @@ -19,19 +19,19 @@
      Preview
      In w2form tags are used to display validation errors. The second parameter is optional and defines css class to be added to the element -itself (not the tag). There can be many tags on the screen at the same time. If the element is moved, the tag will move with it. If it is +itself (not the tag). There can be many tags on the screen at the same time. If the element is moved, the tag will move with it. If it is destroyed, the tag will be destroyed. If you need to hide a tag, call w2tag again with empty text.
      Options can be one of the following: +

      $().w2overlay(html, [options])

      @@ -57,12 +57,12 @@
      Preview
      Options can be one of the following: \ No newline at end of file diff --git a/docs/overview/popup.html b/docs/overview/popup.html index 7b73c3724..43fac20cf 100644 --- a/docs/overview/popup.html +++ b/docs/overview/popup.html @@ -7,9 +7,9 @@

      Popup Overview

      @@ -30,27 +30,27 @@

      Options

      You can pass a map of following properties to the constructor of the popup (none of them are required): diff --git a/docs/overview/sidebar.html b/docs/overview/sidebar.html index 1b10b8351..e2e80475d 100644 --- a/docs/overview/sidebar.html +++ b/docs/overview/sidebar.html @@ -19,42 +19,42 @@

      Complete Example

      @@ -62,7 +62,7 @@

      Complete Example

      HTML

      Java Script

      @@ -73,26 +73,26 @@

      Java Script

      nodes: [ { id: 'level-1', text: 'Level 1', img: 'icon-folder', expanded: true, nodes: [ { id: 'level-1-1', text: 'Level 1.1', img: 'icon-page' }, - { id: 'level-1-2', text: 'Level 1.2', img: 'icon-page' }, - { id: 'level-1-3', text: 'Level 1.3', img: 'icon-page' } - ] + { id: 'level-1-2', text: 'Level 1.2', img: 'icon-page' }, + { id: 'level-1-3', text: 'Level 1.3', img: 'icon-page' } + ] }, { id: 'level-2', text: 'Level 2', img: 'icon-folder', nodes: [ { id: 'level-2-1', text: 'Level 2.1', img: 'icon-folder', - nodes: [ - { id: 'level-2-1-1', text: 'Level 2.1.1', img: 'icon-page' }, - { id: 'level-2-1-2', text: 'Level 2.1.2', img: 'icon-page' }, - { id: 'level-2-1-3', text: 'Level 2.1.3', img: 'icon-page' } - ]}, - { id: 'level-2-2', text: 'Level 2.2', img: 'icon-page' }, - { id: 'level-2-3', text: 'Level 2.3', img: 'icon-page' } - ] + nodes: [ + { id: 'level-2-1-1', text: 'Level 2.1.1', img: 'icon-page' }, + { id: 'level-2-1-2', text: 'Level 2.1.2', img: 'icon-page' }, + { id: 'level-2-1-3', text: 'Level 2.1.3', img: 'icon-page' } + ]}, + { id: 'level-2-2', text: 'Level 2.2', img: 'icon-page' }, + { id: 'level-2-3', text: 'Level 2.3', img: 'icon-page' } + ] }, { id: 'level-3', text: 'Level 3', img: 'icon-folder', nodes: [ { id: 'level-3-1', text: 'Level 3.1', img: 'icon-page' }, - { id: 'level-3-2', text: 'Level 3.2', img: 'icon-page' }, - { id: 'level-3-3', text: 'Level 3.3', img: 'icon-page' } - ] + { id: 'level-3-2', text: 'Level 3.2', img: 'icon-page' }, + { id: 'level-3-3', text: 'Level 3.3', img: 'icon-page' } + ] } ], onClick: function (id, data) { diff --git a/docs/overview/tabs.html b/docs/overview/tabs.html index 73e4d6eed..3f677c168 100644 --- a/docs/overview/tabs.html +++ b/docs/overview/tabs.html @@ -18,24 +18,24 @@

      Complete Example

      - tab1 + tab1
      diff --git a/docs/overview/toolbar.html b/docs/overview/toolbar.html index aa407eba4..f50d4023a 100644 --- a/docs/overview/toolbar.html +++ b/docs/overview/toolbar.html @@ -19,25 +19,25 @@

      Complete Example

      diff --git a/docs/overview/utils-events.html b/docs/overview/utils-events.html index 336289c0e..4eee65eaa 100644 --- a/docs/overview/utils-events.html +++ b/docs/overview/utils-events.html @@ -2,8 +2,8 @@

      Events

      All w2ui controls have the same event flow. There are two ways you can add/remove events:
        -
      1. using on"Event" properties
      2. -
      3. using .on() and .off() methods
      4. +
      5. using on"Event" properties
      6. +
      7. using .on() and .off() methods
      The first way is simple, can be done during object creation, but limits you to a single event listener per event. The second way lets you add multiple event listeners, but can only be used at run-time. It gives you a better control of the event flow. @@ -12,30 +12,30 @@

      Events

      Properties and Methods

      - handlers - array of objects + handlers - array of objects
      - Array of event handlers. + Array of event handlers.
      - on - function (type, handler) + on - function (type, handler)
      - Adds event listener to the w2ui object. + Adds event listener to the w2ui object.
      - off - function (type, [handler]) + off - function (type, [handler])
      - Removes event listener to the w2ui object. + Removes event listener to the w2ui object.
      - trigger - function (eventData) + trigger - function (eventData)
      - Executes all event listeners added with .on() method. + Executes all event listeners added with .on() method.

      Event Handler Function

      @@ -47,22 +47,22 @@

      Event Handler Function

      Event handler looks like: By default all event handlers are triggered before the default behavior. You can cancel event default behavior by: You can also define a function that will be executed after the default behavior is processed. For example: \ No newline at end of file diff --git a/docs/overview/utils-plugins.html b/docs/overview/utils-plugins.html index 9c4bd62a2..d12df6d9a 100644 --- a/docs/overview/utils-plugins.html +++ b/docs/overview/utils-plugins.html @@ -36,19 +36,19 @@

      $().w2menu(menu, [options])

      diff --git a/docs/overview/utils.html b/docs/overview/utils.html index 4b6cfd97d..50c2b2615 100644 --- a/docs/overview/utils.html +++ b/docs/overview/utils.html @@ -7,8 +7,8 @@

      w2ui

      Initially this variable is an empty object, but as soon as you start creating controls, they will become part of this object. This object serves two important purposes:
        -
      • It provides a common and uniform way for accessing created objects
      • -
      • It makes sure that you will not overwrite already created object (object name must be unique)
      • +
      • It provides a common and uniform way for accessing created objects
      • +
      • It makes sure that you will not overwrite already created object (object name must be unique)
      For example, if you created a grid with name myGrid then it can be accessed in the following manner: @@ -24,7 +24,7 @@

      w2obj

      diff --git a/docs/summary.css b/docs/summary.css index cb9980845..6b5abe272 100644 --- a/docs/summary.css +++ b/docs/summary.css @@ -1,6 +1,6 @@ body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; } h1 { @@ -28,108 +28,108 @@ h4 { } ul { - margin: 5px 10px 15px 40px; + margin: 5px 10px 15px 40px; } table.list { - margin: 20px 0px; - border-collapse: collapse; + margin: 20px 0px; + border-collapse: collapse; } table.list td { - border: 1px solid #d1d1d1; - padding: 3px 10px !important; + border: 1px solid #d1d1d1; + padding: 3px 10px !important; } /* Documentation */ .obj-property { - font-size: 16px; - font-weight: bold; - color: #176092; + font-size: 16px; + font-weight: bold; + color: #176092; } .obj-property > a { - color: #176092 !important; + color: #176092 !important; } .obj-property > span { - font-weight: normal; - color: #555; + font-weight: normal; + color: #555; } .obj-property-desc { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - margin: 5px 0px 10px 0px; - padding: 5px 0px 15px 20px; - border-bottom: 1px solid #efefef + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + margin: 5px 0px 10px 0px; + padding: 5px 0px 15px 20px; + border-bottom: 1px solid #efefef } .obj-desc { - padding: 10px 20px; - line-height: 150%; - width: 850px; + padding: 10px 20px; + line-height: 150%; + width: 850px; } .obj-desc h4 { - margin-top: 20px; + margin-top: 20px; } .obj-desc .definition { - background-color: #fafafa; - border: 1px solid silver; - padding: 5px; - border-radius: 4px; - margin: 15px 0px; - font-weight: bold; - color: #304E77; - font-family: Monaco, "Courier New"; + background-color: #fafafa; + border: 1px solid silver; + padding: 5px; + border-radius: 4px; + margin: 15px 0px; + font-weight: bold; + color: #304E77; + font-family: Monaco, "Courier New"; } .obj-desc .arguments { - border: 1px solid silver; - border-radius: 4px; - margin: 15px 0px; - padding: 1px; - margin-left: 50px; + border: 1px solid silver; + border-radius: 4px; + margin: 15px 0px; + padding: 1px; + margin-left: 50px; } .obj-desc .arguments table { - border-collapse: collapse; - width: 100%; - background-color: #fafafa; + border-collapse: collapse; + width: 100%; + background-color: #fafafa; } .obj-desc table td { - padding: 5px 10px; - border-radius: 4px; - border-bottom: 1px solid silver; - width: 80%; + padding: 5px 10px; + border-radius: 4px; + border-bottom: 1px solid silver; + width: 80%; } .obj-desc table tr td:first-child { - width: 15%; - color: #304E77; - border-right: 1px solid silver; - font-family: Monaco, "Courier New"; + width: 15%; + color: #304E77; + border-right: 1px solid silver; + font-family: Monaco, "Courier New"; } .obj-desc table tr:last-child td { - border-bottom: 0px; + border-bottom: 0px; } .method, .property, .argument { - display: inline-block; - background-color: #f1f1f1; - border-radius: 4px; - margin: 0px; - padding: 0px 5px; - min-height: 17px; - font-family: Courier; - color: #176092; + display: inline-block; + background-color: #f1f1f1; + border-radius: 4px; + margin: 0px; + padding: 0px 5px; + min-height: 17px; + font-family: Courier; + color: #176092; } a.method, a.property, a.argument { - color: blue; + color: blue; } \ No newline at end of file diff --git a/docs/summary/common-events.php b/docs/summary/common-events.php index d757dfe92..c5c11bba0 100644 --- a/docs/summary/common-events.php +++ b/docs/summary/common-events.php @@ -1,30 +1,30 @@
      - onDestroy - function (event) + onDestroy - function (event)
      - Called when object is destroyed. + Called when object is destroyed.
      - onRefresh - function (event) + onRefresh - function (event)
      - Called when object is refreshed. + Called when object is refreshed.
      - onRender - function (event) + onRender - function (event)
      - Called when object is rendered. + Called when object is rendered.
      - onResize - function (event) + onResize - function (event)
      - Called when object is resized. + Called when object is resized.
      \ No newline at end of file diff --git a/docs/summary/common-methods.php b/docs/summary/common-methods.php index cd63d14e7..a8616c0db 100644 --- a/docs/summary/common-methods.php +++ b/docs/summary/common-methods.php @@ -1,51 +1,51 @@
      - destroy - destroy() + destroy - destroy()
      - Destroys the object. + Destroys the object.
      - off - off(type, [handler]) + off - off(type, [handler])
      - Removes event listener from the object. + Removes event listener from the object.
      - on - on(type, handler) + on - on(type, handler)
      - Adds event listener to a object. + Adds event listener to a object.
      - refresh - refresh([id]) + refresh - refresh([id])
      - Refreshes the object without completely re-inserting it. + Refreshes the object without completely re-inserting it.
      - render - render([box]) + render - render([box])
      - Renders the object into box. + Renders the object into box.
      - resize - resize() + resize - resize()
      - Resizes the object to the width and height of its container. + Resizes the object to the width and height of its container.
      - trigger - trigger(eventData) + trigger - trigger(eventData)
      - Executes all event listeners added with on() method. + Executes all event listeners added with on() method.
      \ No newline at end of file diff --git a/docs/summary/common-props.php b/docs/summary/common-props.php index 860646122..321f29e91 100644 --- a/docs/summary/common-props.php +++ b/docs/summary/common-props.php @@ -1,30 +1,30 @@
      - box - DOM Element, default = null + box - DOM Element, default = null
      - The DOM element where to render the object. + The DOM element where to render the object.
      - handlers - Array, default = [] + handlers - Array, default = []
      - Array of event handlers. + Array of event handlers.
      - name - String, default = '' + name - String, default = ''
      - Unique name for the object. + Unique name for the object.
      - style - String, default = '' + style - String, default = ''
      - Additional style for the .box where the object is rendered. + Additional style for the .box where the object is rendered.
      \ No newline at end of file diff --git a/docs/summary/w2form-events.php b/docs/summary/w2form-events.php index 58f4cefee..90befcbeb 100644 --- a/docs/summary/w2form-events.php +++ b/docs/summary/w2form-events.php @@ -1,65 +1,65 @@
      - onAction - function (event) + onAction - function (event)
      - Called when user executes a form action. + Called when user executes a form action.
      - onChange - function (event) + onChange - function (event)
      - Called when user changes a form field. + Called when user changes a form field.
      - onError - function (event) + onError - function (event)
      - Called when server returns an error. + Called when server returns an error.
      - onLoad - function (event) + onLoad - function (event)
      - Called when server returns record data. + Called when server returns record data.
      - onRequest - function (event) + onRequest - function (event)
      - Called before form submits request for record data. + Called before form submits request for record data.
      - onSave - function (event) + onSave - function (event)
      - Called when server replies to save record request. + Called when server replies to save record request.
      - onSubmit - function (event) + onSubmit - function (event)
      - Called before form submits request to save record. + Called before form submits request to save record.
      - onToolbar - function (event) + onToolbar - function (event)
      - Called when user clicks on any toolbar button. + Called when user clicks on any toolbar button.
      - onValidate - function (event) + onValidate - function (event)
      - Called when validation of the form is needed. + Called when validation of the form is needed.
      \ No newline at end of file diff --git a/docs/summary/w2form-methods.php b/docs/summary/w2form-methods.php index 075281adc..9de28b275 100644 --- a/docs/summary/w2form-methods.php +++ b/docs/summary/w2form-methods.php @@ -1,100 +1,100 @@
      - action - action(action, [event]) + action - action(action, [event])
      - Called when user clicks form's button. + Called when user clicks form's button.
      - clear - clear() + clear - clear()
      - Resets the form. + Resets the form.
      - error - error(msg) + error - error(msg)
      - Display error message. + Display error message.
      - generateHTML - generateHTML() + generateHTML - generateHTML()
      - Generate HTML template for simple forms (Internal method). + Generate HTML template for simple forms (Internal method).
      - get - get(field, [returnIndex]) + get - get(field, [returnIndex])
      - Finds and returns the field object or its index. + Finds and returns the field object or its index.
      - goto - goto(page) + goto - goto(page)
      - Opens specified form page. + Opens specified form page.
      - lock - lock(message, [showSpinner]) + lock - lock(message, [showSpinner])
      - Locks the form and displays a status message. + Locks the form and displays a status message.
      - reload - reload([callBack]) + reload - reload([callBack])
      - Reloads record data and refreshes the form. + Reloads record data and refreshes the form.
      - request - request([postData], [callBack]) + request - request([postData], [callBack])
      - Reloads record data and refreshes the form. + Reloads record data and refreshes the form.
      - save - save([postData], [callBack]) + save - save([postData], [callBack])
      - Submits record data to remote data source for saving. + Submits record data to remote data source for saving.
      - set - set(field, obj) + set - set(field, obj)
      - Extends field object with obj. + Extends field object with obj.
      - submit - submit([postData], [callBack]) + submit - submit([postData], [callBack])
      - Submits record data to remote data source for saving. + Submits record data to remote data source for saving.
      - unlock - unlock() + unlock - unlock()
      - Unlocks the form. + Unlocks the form.
      - validate - validate([showErrors]) + validate - validate([showErrors])
      - Performs form validation. + Performs form validation.
      \ No newline at end of file diff --git a/docs/summary/w2form-props.php b/docs/summary/w2form-props.php index 384bbb712..d00cd3c44 100644 --- a/docs/summary/w2form-props.php +++ b/docs/summary/w2form-props.php @@ -1,135 +1,135 @@
      - actions - Object, default = {} + actions - Object, default = {}
      - Object of event handlers for form actions. + Object of event handlers for form actions.
      - fields - Object, default = [] + fields - Object, default = []
      - Array of field objects. + Array of field objects.
      - focus - Integer, default = 0 + focus - Integer, default = 0
      - Indicates what field to set focus on render. + Indicates what field to set focus on render.
      - formHTML - String, default = '' + formHTML - String, default = ''
      - Form HTML template. + Form HTML template.
      - formURL - String, default = '' + formURL - String, default = ''
      - URL of the form HTML template. + URL of the form HTML template.
      - header - String, default = '' + header - String, default = ''
      - The header of the form. + The header of the form.
      - isGenerated - Boolean, default = false. + isGenerated - Boolean, default = false.
      - Indicates if HTML template has been generated. + Indicates if HTML template has been generated.
      - last - Object, default see below + last - Object, default see below
      - Last state parameters + Last state parameters
      - msgNotJSON - String, default = 'Returned data is not in valid JSON format.' + msgNotJSON - String, default = 'Returned data is not in valid JSON format.'
      - Error message when server does not return JSON structure. + Error message when server does not return JSON structure.
      - msgRefresh - String, default = 'Refreshing...' + msgRefresh - String, default = 'Refreshing...'
      - Message that appears when form refreshes. + Message that appears when form refreshes.
      - msgSaving - String, default = 'Saving...' + msgSaving - String, default = 'Saving...'
      - Message that appears when form is being saved. + Message that appears when form is being saved.
      - original - Object, default = {} + original - Object, default = {}
      - Original fileds as they were loaded from data source. + Original fileds as they were loaded from data source.
      - page - Integer, default = 0 + page - Integer, default = 0
      - Current page. + Current page.
      - postData - Object, default = {} + postData - Object, default = {}
      - Map of additional parameter to submit to remote data source. + Map of additional parameter to submit to remote data source.
      - recid - Integer, default = null + recid - Integer, default = null
      - ID of the record. + ID of the record.
      - record - Object, default = {} + record - Object, default = {}
      - Map of field values. + Map of field values.
      - tabs - Object, default = {} + tabs - Object, default = {}
      - Tabs for the form. + Tabs for the form.
      - toolbar - Object, default = {} + toolbar - Object, default = {}
      - Toolbar for the form. + Toolbar for the form.
      - url - String or Object, default = '' + url - String or Object, default = ''
      - URL to the remote data source. + URL to the remote data source.
      \ No newline at end of file diff --git a/docs/summary/w2grid-events.php b/docs/summary/w2grid-events.php index 3aed3cdff..c72d3991d 100644 --- a/docs/summary/w2grid-events.php +++ b/docs/summary/w2grid-events.php @@ -1,198 +1,198 @@
      - onAdd - function (event) + onAdd - function (event)
      - Called when user clicks the Add New button on the toolbar. + Called when user clicks the Add New button on the toolbar.
      - onChange - function (event) + onChange - function (event)
      - Called when user changes any field in the editable row. + Called when user changes any field in the editable row.
      - onClick - function (event) + onClick - function (event)
      - Called when user clicks a record. + Called when user clicks a record.
      - onCollapse - function (event) + onCollapse - function (event)
      - Called when user collapses epxandable record. + Called when user collapses epxandable record.
      - onColumnClick - function (event) + onColumnClick - function (event)
      - Called when user clicks a column. + Called when user clicks a column.
      - onColumnOnOff - function (event) + onColumnOnOff - function (event)
      - Called when user shows or hides a column selecting it in the grid settings menu. + Called when user shows or hides a column selecting it in the grid settings menu.
      - onColumnResize - function (event) + onColumnResize - function (event)
      - Called when user resizes a column. + Called when user resizes a column.
      - onCopy - function (event) + onCopy - function (event)
      - Called when user copies selected records to clipboard (ctrl+c or cmd+c). + Called when user copies selected records to clipboard (ctrl+c or cmd+c).
      - onDblClick - function (event) + onDblClick - function (event)
      - Called when user double clicks a record. + Called when user double clicks a record.
      - onDelete - function (event) + onDelete - function (event)
      - Called when user clicks the Delete button on the toolbar. + Called when user clicks the Delete button on the toolbar.
      - onDeleted - function (event) + onDeleted - function (event)
      - Called when server responds back after delete request. + Called when server responds back after delete request.
      - onEdit - function (event) + onEdit - function (event)
      - Called when user clicks the Edit button on the toolbar. + Called when user clicks the Edit button on the toolbar.
      - onEditField - function (event) + onEditField - function (event)
      - Called when user enters into editable mode for the field. + Called when user enters into editable mode for the field.
      - onError - function (event) + onError - function (event)
      - Called when server returns an error. + Called when server returns an error.
      - onExpand - function (event) + onExpand - function (event)
      - Called when user expands expandable record. + Called when user expands expandable record.
      - onKeydown - function (event) + onKeydown - function (event)
      - Called when user presess a keyboard key and grid is active. + Called when user presess a keyboard key and grid is active.
      - onLoad - function (event) + onLoad - function (event)
      - Called when server responds to a get-records request. + Called when server responds to a get-records request.
      - onPaste - function (event) + onPaste - function (event)
      - Called when user pastes from clipboard (ctrl+v or cmd+v). + Called when user pastes from clipboard (ctrl+v or cmd+v).
      - onReload - function (event) + onReload - function (event)
      - Called when user clicks Reload button on the toolbar. + Called when user clicks Reload button on the toolbar.
      - onRequest - function (event) + onRequest - function (event)
      - Called on any server request. + Called on any server request.
      - onSave - function (event) + onSave - function (event)
      - Called when user clicks the Save button on the toolbar. + Called when user clicks the Save button on the toolbar.
      - onSaved - function (event) + onSaved - function (event)
      - Called when server responds back after save request. + Called when server responds back after save request.
      - onSearch - function (event) + onSearch - function (event)
      - Called when user applies a search. + Called when user applies a search.
      - onSelect - function (event) + onSelect - function (event)
      - Called when user selects a record. + Called when user selects a record.
      - onSelectionExtend - function (event) + onSelectionExtend - function (event)
      - Called when user extends selection by draggind small dot at the bottom right cornder of selection. + Called when user extends selection by draggind small dot at the bottom right cornder of selection.
      - onSort - function (event) + onSort - function (event)
      - Called when user applies a sort. + Called when user applies a sort.
      - onToolbar - function (event) + onToolbar - function (event)
      - Called when user clicks any button on the toolbar. + Called when user clicks any button on the toolbar.
      - onUnselect - function (event) + onUnselect - function (event)
      - Called when user unselects a record. + Called when user unselects a record.
      \ No newline at end of file diff --git a/docs/summary/w2grid-methods.php b/docs/summary/w2grid-methods.php index 70e394b66..606d9cd4a 100644 --- a/docs/summary/w2grid-methods.php +++ b/docs/summary/w2grid-methods.php @@ -1,541 +1,541 @@
      - add - add(record) + add - add(record)
      - Adds a record or records to the grid. + Adds a record or records to the grid.
      - addColumn - addColumn([before], column) + addColumn - addColumn([before], column)
      - Adds a column or columns to the grid. + Adds a column or columns to the grid.
      - addRange - addRange(range) + addRange - addRange(range)
      - Adds a visible range or ranges to the grid. + Adds a visible range or ranges to the grid.
      - addSearch - addSearch([before], search) + addSearch - addSearch([before], search)
      - Adds a search or searches to the grid. + Adds a search or searches to the grid.
      - clear - clear([noRefresh]) + clear - clear([noRefresh])
      - Removes all records from the grid. + Removes all records from the grid.
      - click - click(recid, [event]) + click - click(recid, [event])
      - Called when user clicks on a record. + Called when user clicks on a record.
      - collapse - collapse(recid) + collapse - collapse(recid)
      - Called when user clicks on the collapse record icon. + Called when user clicks on the collapse record icon.
      - columnClick - columnClick(field, [event]) + columnClick - columnClick(field, [event])
      - Called when user clicks on the column. + Called when user clicks on the column.
      - columnOnOff - columnOnOff(el, event, field, value) + columnOnOff - columnOnOff(el, event, field, value)
      - Called when user opens grid settings (on grids toolbar) and selects an item. + Called when user opens grid settings (on grids toolbar) and selects an item.
      - copy - copy() + copy - copy()
      - Returns selected records in tab-delimited text format. + Returns selected records in tab-delimited text format.
      - dblClick - dblClick(recid, [event]) + dblClick - dblClick(recid, [event])
      - Called when user double clicks on a record. + Called when user double clicks on a record.
      - delete - delete(force) + delete - delete(force)
      - Called when user deletes record(s). + Called when user deletes record(s).
      - editField - editField(recid, column, [value], [event]) + editField - editField(recid, column, [value], [event])
      - Enters edit mode for the specified record and field. + Enters edit mode for the specified record and field.
      - error - error(msg) + error - error(msg)
      - Display error message dialog. + Display error message dialog.
      - expand - expand(recid) + expand - expand(recid)
      - Called when user clicks on the expand record icon. + Called when user clicks on the expand record icon.
      - find - find(match, [returnIndex]) + find - find(match, [returnIndex])
      - Finds and returns matched records. + Finds and returns matched records.
      - get - get(recid, [returnIndex]) + get - get(recid, [returnIndex])
      - Finds the record and returns its object or index in records array. + Finds the record and returns its object or index in records array.
      - getCellHTML - getCellHTML(index, column_index, [summary]) + getCellHTML - getCellHTML(index, column_index, [summary])
      - Returns final HTML for the cell. + Returns final HTML for the cell.
      - getChanges - getChanges() + getChanges - getChanges()
      - Returns array of changed record objects. + Returns array of changed record objects.
      - getColumn - getColumn(field, [returnIndex]) + getColumn - getColumn(field, [returnIndex])
      - Finds the column and returns its object or index in columns array. + Finds the column and returns its object or index in columns array.
      - getColumnsHTML - getColumnsHTML() + getColumnsHTML - getColumnsHTML()
      - Returns HTML of grid columns. + Returns HTML of grid columns.
      - getFooterHTML - getFooterHTML() + getFooterHTML - getFooterHTML()
      - Returns HTML for grid footer. + Returns HTML for grid footer.
      - getRangeData - getRangeData(range, [extra]) + getRangeData - getRangeData(range, [extra])
      - Returns range data defined to the given range object. + Returns range data defined to the given range object.
      - getRecordHTML - getRecordHTML(index, line_number, [summary]) + getRecordHTML - getRecordHTML(index, line_number, [summary])
      - Returns final HTML for a record. + Returns final HTML for a record.
      - getRecordsHTML - getRecordsHTML() + getRecordsHTML - getRecordsHTML()
      - Returns HTML of grid records in the scroll view. + Returns HTML of grid records in the scroll view.
      - getSearch - getSearch(field, [returnIndex]) + getSearch - getSearch(field, [returnIndex])
      - Finds the search and returns its object or index in searches array. + Finds the search and returns its object or index in searches array.
      - getSearchData - getSearchData(field) + getSearchData - getSearchData(field)
      - Returns applied search object for specified field. + Returns applied search object for specified field.
      - getSearchesHTML - getSearchesHTML() + getSearchesHTML - getSearchesHTML()
      - Returns HTML of search fields. + Returns HTML of search fields.
      - getSelection - getSelection(returnIndex) + getSelection - getSelection(returnIndex)
      - Returns current grid selection. + Returns current grid selection.
      - getSummaryHTML - getSummaryHTML() + getSummaryHTML - getSummaryHTML()
      - Returns HTML of summary records. + Returns HTML of summary records.
      - hideColumn - hideColumn(field, [field], ...) + hideColumn - hideColumn(field, [field], ...)
      - Hides a column or columns. + Hides a column or columns.
      - hideSearch - hideSearch(field, [field], ...) + hideSearch - hideSearch(field, [field], ...)
      - Hides a search or searches. + Hides a search or searches.
      - initColumnOnOff - initColumnOnOff() + initColumnOnOff - initColumnOnOff()
      - Refreshes toolbar button that allows to show/hide columns. + Refreshes toolbar button that allows to show/hide columns.
      - initResize - initResize() + initResize - initResize()
      - Initializes column resize elements. + Initializes column resize elements.
      - initSearches - initSearches() + initSearches - initSearches()
      - Initializes search fields when user opens advanced search overlay. + Initializes search fields when user opens advanced search overlay.
      - initToolbar - initToolbar() + initToolbar - initToolbar()
      - Creates w2toolbar object based on grid.toolbar definition. + Creates w2toolbar object based on grid.toolbar definition.
      - keydown - keydown(event) + keydown - keydown(event)
      - Processes keydown events. + Processes keydown events.
      - load - load(url, [callBack]) + load - load(url, [callBack])
      - Loads records from specified url. + Loads records from specified url.
      - localSearch - localSearch([silent]) + localSearch - localSearch([silent])
      - Performs search on local data set. + Performs search on local data set.
      - localSort - localSort([silent]) + localSort - localSort([silent])
      - Performs sort on local data set. + Performs sort on local data set.
      - lock - lock(message, [showSpinner]) + lock - lock(message, [showSpinner])
      - Locks the grid. + Locks the grid.
      - mergeChanges - mergeChanges() + mergeChanges - mergeChanges()
      - Merges user changes into the records array. + Merges user changes into the records array.
      - parseField - parseField(obj, field) + parseField - parseField(obj, field)
      - Paste tab-delimmited text into the grid. + Paste tab-delimmited text into the grid.
      - paste - paste(text) + paste - paste(text)
      - Paste tab-delimmited text into the grid. + Paste tab-delimmited text into the grid.
      - refreshRanges - refreshRanges() + refreshRanges - refreshRanges()
      - Refreshes ranges defined for the grid. + Refreshes ranges defined for the grid.
      - reload - reload([callBack]) + reload - reload([callBack])
      - Reloads records from remote data source. + Reloads records from remote data source.
      - remove - remove(recid1, recid2, ...) + remove - remove(recid1, recid2, ...)
      - Removes records from the grid. + Removes records from the grid.
      - removeColumn - removeColumn(field, [field], ...) + removeColumn - removeColumn(field, [field], ...)
      - Removes a column or columns from the grid. + Removes a column or columns from the grid.
      - removeRange - removeRange(range_name, [range_name], ...) + removeRange - removeRange(range_name, [range_name], ...)
      - Removes a range or ranges from the grid. + Removes a range or ranges from the grid.
      - removeSearch - removeSearch(field, [field], ...) + removeSearch - removeSearch(field, [field], ...)
      - Removes a search or searches from the grid. + Removes a search or searches from the grid.
      - request - request(cmd, [params, [url, [callBack]]]) + request - request(cmd, [params, [url, [callBack]]])
      - Prepares and submits request to the server. + Prepares and submits request to the server.
      - requestComplete - requestComplete(status, cmd, [callBack]) + requestComplete - requestComplete(status, cmd, [callBack])
      - Called to process data that was returned from the server. + Called to process data that was returned from the server.
      - reset - reset([noRefresh]) + reset - reset([noRefresh])
      - Resets the grid to the initial state. + Resets the grid to the initial state.
      - save - save() + save - save()
      - Called when user saves inline editing changes. + Called when user saves inline editing changes.
      - scroll - scroll(event) + scroll - scroll(event)
      - Rebuilds grids records HTML based on scroll bar position. + Rebuilds grids records HTML based on scroll bar position.
      - scrollIntoView - scrollIntoView(ind) + scrollIntoView - scrollIntoView(ind)
      - Called when user saves inline editing changes. + Called when user saves inline editing changes.
      - search - search(field, value) + search - search(field, value)
      - Searches records in the grid. + Searches records in the grid.
      - searchClose - searchClose() + searchClose - searchClose()
      - Closes overlay with advanced search options (if it was open). + Closes overlay with advanced search options (if it was open).
      - searchOpen - searchOpen() + searchOpen - searchOpen()
      - Opens overlay with advanced search options. + Opens overlay with advanced search options.
      - searchReset - searchReset([noRefresh]) + searchReset - searchReset([noRefresh])
      - Resets previous search to the default values. + Resets previous search to the default values.
      - searchShowFields - searchShowFields() + searchShowFields - searchShowFields()
      - Resets previous search to the default values. + Resets previous search to the default values.
      - select - select(recid1, recid2, ...) + select - select(recid1, recid2, ...)
      - Selects records in the grid. + Selects records in the grid.
      - selectAll - selectAll() + selectAll - selectAll()
      - Selects all records in the grid. + Selects all records in the grid.
      - selectNone - selectNone() + selectNone - selectNone()
      - Unselects all selected records in the grid. + Unselects all selected records in the grid.
      - set - set([recid], record, [noRefresh]) + set - set([recid], record, [noRefresh])
      - Finds the record and extends it with provided object. + Finds the record and extends it with provided object.
      - showColumn - showColumn(field, [field], ...) + showColumn - showColumn(field, [field], ...)
      - Shows a column or columns. + Shows a column or columns.
      - showSearch - showSearch(field, [field], ...) + showSearch - showSearch(field, [field], ...)
      - Shows a search or searches. + Shows a search or searches.
      - skip - skip(offset) + skip - skip(offset)
      - Skips a number of records specified. + Skips a number of records specified.
      - sort - sort() + sort - sort()
      - Sorts records in the grid. + Sorts records in the grid.
      - status - status([msg]) + status - status([msg])
      - Displays status text. + Displays status text.
      - toggle - toggle(recid) + toggle - toggle(recid)
      - Toggles record between expand and collapse states. + Toggles record between expand and collapse states.
      - toggleColumn - toggleColumn(field, [field], ...) + toggleColumn - toggleColumn(field, [field], ...)
      - Toggles column between hidden and shown states. + Toggles column between hidden and shown states.
      - toggleSearch - toggleSearch(field, [field], ...) + toggleSearch - toggleSearch(field, [field], ...)
      - Toggles a search between hidden and shown states. + Toggles a search between hidden and shown states.
      - toolbarAdd - toolbarAdd() + toolbarAdd - toolbarAdd()
      - Called when user clicks the Add New button on the toolbar. + Called when user clicks the Add New button on the toolbar.
      - toolbarDelete - toolbarDelete([force]) + toolbarDelete - toolbarDelete([force])
      - Called when user clicks the Delete button on the toolbar. + Called when user clicks the Delete button on the toolbar.
      - unlock - unlock() + unlock - unlock()
      - Unlocks the grid. + Unlocks the grid.
      - unselect - unselect(recid1, recid2, ...) + unselect - unselect(recid1, recid2, ...)
      - Unselects records in the grid. + Unselects records in the grid.
      \ No newline at end of file diff --git a/docs/summary/w2grid-props.php b/docs/summary/w2grid-props.php index 49b87b45f..e424f9996 100644 --- a/docs/summary/w2grid-props.php +++ b/docs/summary/w2grid-props.php @@ -1,233 +1,233 @@
      - autoLoad - Boolean, default = true + autoLoad - Boolean, default = true
      - Indicates if the records should be loaded from the server automatically as user scrolls. + Indicates if the records should be loaded from the server automatically as user scrolls.
      - buffered - Integer, default = 0 + buffered - Integer, default = 0
      - Number of buffered records. + Number of buffered records.
      - buttons - Object, default see below + buttons - Object, default see below
      - Object that contains default toolbar items + Object that contains default toolbar items
      - columnGroups - Array, default = [] + columnGroups - Array, default = []
      - Array of column group objects. + Array of column group objects.
      - columns - Array, default = [] + columns - Array, default = []
      - Array of column objects. + Array of column objects.
      - fixedBody - Boolean, default = true + fixedBody - Boolean, default = true
      - Indicates if the body of the grid is of fixed height. + Indicates if the body of the grid is of fixed height.
      - header - String, default = '' + header - String, default = ''
      - The header of the grid. + The header of the grid.
      - keyboard - Boolean, default = true + keyboard - Boolean, default = true
      - Indicates if grid should listen to keyboard. + Indicates if grid should listen to keyboard.
      - last - Object, default see below + last - Object, default see below
      - Internal grid's vairables. + Internal grid's vairables.
      - limit - Integer, default = 100 + limit - Integer, default = 100
      - Number of records to return from remote data source per attempt. + Number of records to return from remote data source per attempt.
      - markSearchResults - Boolean, default = true + markSearchResults - Boolean, default = true
      - Indicates if result of the search should be highlighted. + Indicates if result of the search should be highlighted.
      - msgDelete - String, default = 'Are you sure you want to delete selected record(s)?' + msgDelete - String, default = 'Are you sure you want to delete selected record(s)?'
      - Confirmation message when user clicks the delete button. + Confirmation message when user clicks the delete button.
      - msgNotJSON - String, default = 'Returned data is not in valid JSON format.' + msgNotJSON - String, default = 'Returned data is not in valid JSON format.'
      - Error message when server does not return JSON structure. + Error message when server does not return JSON structure.
      - msgRefresh - String, default = 'Refreshing...' + msgRefresh - String, default = 'Refreshing...'
      - Message that appears when grid refreshes. + Message that appears when grid refreshes.
      - multiSearch - Boolean, default = true + multiSearch - Boolean, default = true
      - Indicates if multi field search is allowed. + Indicates if multi field search is allowed.
      - multiSelect - Boolean, default = true + multiSelect - Boolean, default = true
      - Indicates if record multi select is allowed. + Indicates if record multi select is allowed.
      - multiSort - Boolean, default = true + multiSort - Boolean, default = true
      - Indicates if column multi sort is allowed. + Indicates if column multi sort is allowed.
      - offset - Integer, default = 0 + offset - Integer, default = 0
      - Number of records to skip when retriving records from remote source. + Number of records to skip when retriving records from remote source.
      - postData - Object, default = {} + postData - Object, default = {}
      - Map of additional parameter to submit to remove data source. + Map of additional parameter to submit to remove data source.
      - ranges - Array, default = [] + ranges - Array, default = []
      - Array of all ranges defined for the grid. + Array of all ranges defined for the grid.
      - recordHeight - Integer, default = 24 + recordHeight - Integer, default = 24
      - Height of the record. + Height of the record.
      - records - Array, default = [] + records - Array, default = []
      - Array of record objects. + Array of record objects.
      - resizeBoxes - requestBoxes() + resizeBoxes - requestBoxes()
      - Called to resize grid's elements. + Called to resize grid's elements.
      - resizeRecords - requestRecords() + resizeRecords - requestRecords()
      - Called to resize grid's records. + Called to resize grid's records.
      - searchData - Array, default = [] + searchData - Array, default = []
      - Array of search objects (submitted to data source for record filtering). + Array of search objects (submitted to data source for record filtering).
      - searches - Array, default = [] + searches - Array, default = []
      - Array of search objects. + Array of search objects.
      - selectType - String, default = 'row' + selectType - String, default = 'row'
      - Defines selection type. + Defines selection type.
      - show - Object, default - see below + show - Object, default - see below
      - Map of indicators which elements of the grid are visible. + Map of indicators which elements of the grid are visible.
      - sortData - Array, default = [] + sortData - Array, default = []
      - Array of sort objects (submitted to data source for record sorting). + Array of sort objects (submitted to data source for record sorting).
      - summary - Array, default = [] + summary - Array, default = []
      - Summary records that displayed on the bottom + Summary records that displayed on the bottom
      - toolbar - Object, default = null + toolbar - Object, default = null
      - Toolbar for the grid. + Toolbar for the grid.
      - total - Integer, default = 0 + total - Integer, default = 0
      - Total number of records. + Total number of records.
      - url - String or Object, default = '' + url - String or Object, default = ''
      - URL to the remote data source. + URL to the remote data source.
      \ No newline at end of file diff --git a/docs/summary/w2layout-events.php b/docs/summary/w2layout-events.php index 834ee2d48..7dc82baf8 100644 --- a/docs/summary/w2layout-events.php +++ b/docs/summary/w2layout-events.php @@ -1,23 +1,23 @@
      - onHide - function (event) + onHide - function (event)
      - Called when a panel is hidden. + Called when a panel is hidden.
      - onResizing - function (event) + onResizing - function (event)
      - Called when panels are being resized by the user. + Called when panels are being resized by the user.
      - onShow - function (event) + onShow - function (event)
      - Called when a panel is shown. + Called when a panel is shown.
      \ No newline at end of file diff --git a/docs/summary/w2layout-methods.php b/docs/summary/w2layout-methods.php index 5e268bd6f..1d586709e 100644 --- a/docs/summary/w2layout-methods.php +++ b/docs/summary/w2layout-methods.php @@ -1,128 +1,128 @@
      - content - content(type, [content], [transition]) + content - content(type, [content], [transition])
      - Sets or retrieves panel content. + Sets or retrieves panel content.
      - el - el(type) + el - el(type)
      - Returns DOM element where content of the panel is rendered. + Returns DOM element where content of the panel is rendered.
      - get - get(type) + get - get(type)
      - Finds the panel and returns its object. + Finds the panel and returns its object.
      - hide - hide(type, [immediate]) + hide - hide(type, [immediate])
      - Hides the panel. + Hides the panel.
      - hideTabs - hideTabs(type) + hideTabs - hideTabs(type)
      - Hides the panel's tabs. + Hides the panel's tabs.
      - hideToolbar - hideToolbar(type) + hideToolbar - hideToolbar(type)
      - Hides the panel's toolbar. + Hides the panel's toolbar.
      - html - html(type, [content], [transition]) + html - html(type, [content], [transition])
      - Sets or retrieves panel content. + Sets or retrieves panel content.
      - load - load(type, url, [transtion], [onLoad]) + load - load(type, url, [transtion], [onLoad])
      - Loads content and renders it inside the panel. + Loads content and renders it inside the panel.
      - lock - lock(panel, message, [showSpinner]) + lock - lock(panel, message, [showSpinner])
      - Locks layout panel. + Locks layout panel.
      - set - set(type, panel) + set - set(type, panel)
      - Finds the panel and extends it with provided object. + Finds the panel and extends it with provided object.
      - show - show(type, [immediate]) + show - show(type, [immediate])
      - Shows the panel. + Shows the panel.
      - showTabs - showTabs(type) + showTabs - showTabs(type)
      - Shows the panel's tabs. + Shows the panel's tabs.
      - showToolbar - showToolbar(type) + showToolbar - showToolbar(type)
      - Shows the panel's toolbar. + Shows the panel's toolbar.
      - sizeTo - sizeTo(type, size) + sizeTo - sizeTo(type, size)
      - Resizes the panel with animation + Resizes the panel with animation
      - toggle - toggle(type, [immediate]) + toggle - toggle(type, [immediate])
      - Toggles the panel. + Toggles the panel.
      - toggleTabs - toggleTabs(type) + toggleTabs - toggleTabs(type)
      - Toggles the panel's tabs. + Toggles the panel's tabs.
      - toggleToolbar - toggleToolbar(type) + toggleToolbar - toggleToolbar(type)
      - Toggles the panel's toolbar. + Toggles the panel's toolbar.
      - unlock - unlock(panel) + unlock - unlock(panel)
      - Unlocks layout panel. + Unlocks layout panel.
      \ No newline at end of file diff --git a/docs/summary/w2layout-props.php b/docs/summary/w2layout-props.php index dccfd0458..941e8191a 100644 --- a/docs/summary/w2layout-props.php +++ b/docs/summary/w2layout-props.php @@ -1,23 +1,23 @@
      - padding - Integer, default = 1 + padding - Integer, default = 1
      - Padding between panels in px. + Padding between panels in px.
      - panels - Array, default = [] + panels - Array, default = []
      - Array of panel objects. + Array of panel objects.
      - resizer - Integer, default = 4 + resizer - Integer, default = 4
      - The size of draggable resizer between panels. + The size of draggable resizer between panels.
      \ No newline at end of file diff --git a/docs/summary/w2listview-events.php b/docs/summary/w2listview-events.php index 9a9b930c0..56f1eda40 100644 --- a/docs/summary/w2listview-events.php +++ b/docs/summary/w2listview-events.php @@ -1,37 +1,37 @@
      - onClick - function (event) + onClick - function (event)
      - Called when item is clicked. + Called when item is clicked.
      - onContextMenu - function (event) + onContextMenu - function (event)
      - Called when user clicks right mouse button on the item. + Called when user clicks right mouse button on the item.
      - onDblClick - function (event) + onDblClick - function (event)
      - Called when user double clicks the item. + Called when user double clicks the item.
      - onKeydown - function (event) + onKeydown - function (event)
      - Called when user clicks a keyboard key and listview is active. + Called when user clicks a keyboard key and listview is active.
      - onMenuClick - function (event) + onMenuClick - function (event)
      - Called when user selects and item from the context menu. + Called when user selects and item from the context menu.
      \ No newline at end of file diff --git a/docs/summary/w2listview-methods.php b/docs/summary/w2listview-methods.php index b4d696c96..d23d6ad19 100644 --- a/docs/summary/w2listview-methods.php +++ b/docs/summary/w2listview-methods.php @@ -1,107 +1,107 @@
      - add - add(items) + add - add(items)
      - Adds a item or items. + Adds a item or items.
      - click - click(id, [event]) + click - click(id, [event])
      - Called when user clicks the item. + Called when user clicks the item.
      - contextMenu - contextMenu(id, [event]) + contextMenu - contextMenu(id, [event])
      - Called when user right clicks the item. + Called when user right clicks the item.
      - dblClick - dblClick(id, [event]) + dblClick - dblClick(id, [event])
      - Called when user double clicks the item. + Called when user double clicks the item.
      - get - get(id, [returnIndex]) + get - get(id, [returnIndex])
      - Finds and returns specified item. + Finds and returns specified item.
      - insert - insert(before, items) + insert - insert(before, items)
      - Inserts a item or items before item with id=before + Inserts a item or items before item with id=before
      - keydown - keydown(event) + keydown - keydown(event)
      - Processes keydown events. + Processes keydown events.
      - menuClick - menuClick(id, index, [event]) + menuClick - menuClick(id, index, [event])
      - Called when user select item from context menu. + Called when user select item from context menu.
      - remove - remove(id1, [id2], ...) + remove - remove(id1, [id2], ...)
      - Removes an items. + Removes an items.
      - scrollIntoView - scrollIntoView(id) + scrollIntoView - scrollIntoView(id)
      - Scroll items into view + Scroll items into view
      - select - select(id, addSelection) + select - select(id, addSelection)
      - Selects listview item with id. + Selects listview item with id.
      - set - set(id, item) + set - set(id, item)
      - Finds listview item with id and extends it with item object. + Finds listview item with id and extends it with item object.
      - unselect - unselect(id1, [id2], ...) + unselect - unselect(id1, [id2], ...)
      - Unselects listview item with id. + Unselects listview item with id.
      - userSelect - userSelect(id, event, isMouse) + userSelect - userSelect(id, event, isMouse)
      - Processes the user select of item with id. + Processes the user select of item with id.
      - viewType - viewType([value]) + viewType - viewType([value])
      - Returns current view type or sets a new one. + Returns current view type or sets a new one.
      \ No newline at end of file diff --git a/docs/summary/w2listview-props.php b/docs/summary/w2listview-props.php index df537bc70..26040189b 100644 --- a/docs/summary/w2listview-props.php +++ b/docs/summary/w2listview-props.php @@ -1,58 +1,58 @@
      - curFocused - String, default = '' + curFocused - String, default = ''
      - The id of the currently focused item. Read Only. + The id of the currently focused item. Read Only.
      - extraCols - Array, default = [] + extraCols - Array, default = []
      - Array of extra columns in "table" view type. + Array of extra columns in "table" view type.
      - getFocused - getFocus([returnIndex]) + getFocused - getFocus([returnIndex])
      - Finds and returns item with input focus. + Finds and returns item with input focus.
      - items - Array, default = [] + items - Array, default = []
      - Array of item objects. + Array of item objects.
      - keyboard - Boolean, default = true + keyboard - Boolean, default = true
      - Indicates if listview should listen to keyboard. + Indicates if listview should listen to keyboard.
      - menu - Array, default = [] + menu - Array, default = []
      - Context menu for the listview. + Context menu for the listview.
      - multiselect - Boolean, default = true + multiselect - Boolean, default = true
      - Indicates if listview should support selecting of multiple items. + Indicates if listview should support selecting of multiple items.
      - selStart - String, default = '' + selStart - String, default = ''
      - The id of the item, from which "shift selection" starts. Read Only. + The id of the item, from which "shift selection" starts. Read Only.
      \ No newline at end of file diff --git a/docs/summary/w2popup-events.php b/docs/summary/w2popup-events.php index 092efe439..6f630e607 100644 --- a/docs/summary/w2popup-events.php +++ b/docs/summary/w2popup-events.php @@ -1,37 +1,37 @@
      - onClose - function (event) + onClose - function (event)
      - Called when popup is closed. + Called when popup is closed.
      - onKeydown - function (event) + onKeydown - function (event)
      - Called when user presses a keyboard key and popup is open. + Called when user presses a keyboard key and popup is open.
      - onMax - function (event) + onMax - function (event)
      - Called when popup is minimized. + Called when popup is minimized.
      - onMin - function (event) + onMin - function (event)
      - Called when popup is minimized. + Called when popup is minimized.
      - onOpen - function (event) + onOpen - function (event)
      - Called when popup is opened or transitions to the new content. + Called when popup is opened or transitions to the new content.
      \ No newline at end of file diff --git a/docs/summary/w2popup-methods.php b/docs/summary/w2popup-methods.php index 7e4141bfb..25b01cb37 100644 --- a/docs/summary/w2popup-methods.php +++ b/docs/summary/w2popup-methods.php @@ -1,121 +1,121 @@
      - clear - clear() + clear - clear()
      - Clears title, body, buttons of the popup. + Clears title, body, buttons of the popup.
      - close - close() + close - close()
      - Closes popup. + Closes popup.
      - get - get() + get - get()
      - Returns current popup options. + Returns current popup options.
      - keydown - keydown(event) + keydown - keydown(event)
      - Processes keyboard actions + Processes keyboard actions
      - load - load(options) + load - load(options)
      - Loads new content for the popup from the server. + Loads new content for the popup from the server.
      - lock - lock(message, [showSpinner]) + lock - lock(message, [showSpinner])
      - Locks popup window. + Locks popup window.
      - lockScreen - lockScreen([options]) + lockScreen - lockScreen([options])
      - Locks screen behind the popup + Locks screen behind the popup
      - max - max() + max - max()
      - Maximizes popup. + Maximizes popup.
      - message - message(msgOptions); + message - message(msgOptions);
      - Displays a message at the top of current popup. + Displays a message at the top of current popup.
      - min - min() + min - min()
      - Minimizes popup. + Minimizes popup.
      - open - open(options); + open - open(options);
      - Opens new popup or transitions to new content. + Opens new popup or transitions to new content.
      - reset - reset() + reset - reset()
      - Resets popup to default options. + Resets popup to default options.
      - resize - resize(width, height, [callBack]) + resize - resize(width, height, [callBack])
      - Resizes existing popup. + Resizes existing popup.
      - set - set(options) + set - set(options)
      - Transitions popup to the new state. + Transitions popup to the new state.
      - toggle - toggle() + toggle - toggle()
      - Toggles popup between maximized and normal states. + Toggles popup between maximized and normal states.
      - unlock - unlock() + unlock - unlock()
      - Unlocks popup window. + Unlocks popup window.
      - unlockScreen - unlockScreen() + unlockScreen - unlockScreen()
      - Unlocks screen behind popup. + Unlocks screen behind popup.
      \ No newline at end of file diff --git a/docs/summary/w2popup-props.php b/docs/summary/w2popup-props.php index f1dc406bc..a316eda3c 100644 --- a/docs/summary/w2popup-props.php +++ b/docs/summary/w2popup-props.php @@ -1,9 +1,9 @@
      - defaults - Array, default - see below + defaults - Array, default - see below
      - Array of default settings for the popup. + Array of default settings for the popup.
      \ No newline at end of file diff --git a/docs/summary/w2sidebar-events.php b/docs/summary/w2sidebar-events.php index c7982bd28..273b5cf32 100644 --- a/docs/summary/w2sidebar-events.php +++ b/docs/summary/w2sidebar-events.php @@ -1,51 +1,51 @@
      - onClick - function (event) + onClick - function (event)
      - Called when user clicks the node. + Called when user clicks the node.
      - onCollapse - function (event) + onCollapse - function (event)
      - Called when user collapses sub-nodes of the node. + Called when user collapses sub-nodes of the node.
      - onContextMenu - function (event) + onContextMenu - function (event)
      - Called when user clicks right mouse button on the node. + Called when user clicks right mouse button on the node.
      - onDblClick - function (event) + onDblClick - function (event)
      - Called when user double clicks the node. + Called when user double clicks the node.
      - onExpand - function (event) + onExpand - function (event)
      - Called when user expands sub-nodes of the node. + Called when user expands sub-nodes of the node.
      - onKeydown - function (event) + onKeydown - function (event)
      - Called when user clicks a keyboard key and sidebar is active. + Called when user clicks a keyboard key and sidebar is active.
      - onMenuClick - function (event) + onMenuClick - function (event)
      - Called when user selects and item from the context menu. + Called when user selects and item from the context menu.
      \ No newline at end of file diff --git a/docs/summary/w2sidebar-methods.php b/docs/summary/w2sidebar-methods.php index 494cfa45c..048a45f19 100644 --- a/docs/summary/w2sidebar-methods.php +++ b/docs/summary/w2sidebar-methods.php @@ -1,177 +1,177 @@
      - add - add([parent], nodes) + add - add([parent], nodes)
      - Adds a sidebar node or nodes. + Adds a sidebar node or nodes.
      - click - click(id, [event]) + click - click(id, [event])
      - Called when user clicks the node. + Called when user clicks the node.
      - collapse - collapse(id) + collapse - collapse(id)
      - Collapses node with id. + Collapses node with id.
      - collapseAll - collapseAll([parent]) + collapseAll - collapseAll([parent])
      - Collapses all expanded children of specified node. + Collapses all expanded children of specified node.
      - contextMenu - contextMenu(id, [event]) + contextMenu - contextMenu(id, [event])
      - Called when user right clicks the node. + Called when user right clicks the node.
      - dblClick - dblClick(id, [event]) + dblClick - dblClick(id, [event])
      - Called when user double clicks the node. + Called when user double clicks the node.
      - disable - disable(id1, [id2], ...) + disable - disable(id1, [id2], ...)
      - Disables sidebar node or nodes with id. + Disables sidebar node or nodes with id.
      - enable - enable(id1, [id2], ...) + enable - enable(id1, [id2], ...)
      - Enables sidebar node or nodes with id. + Enables sidebar node or nodes with id.
      - expand - expand(id) + expand - expand(id)
      - Expands sidebar node with id. + Expands sidebar node with id.
      - expandAll - expandAll([parent]) + expandAll - expandAll([parent])
      - Expands all collapsed children of specified node. + Expands all collapsed children of specified node.
      - expandParents - expandParents(id) + expandParents - expandParents(id)
      - Expands each parent of the specified node. + Expands each parent of the specified node.
      - get - get([parent], id, [returnIndex]) + get - get([parent], id, [returnIndex])
      - Finds sidebar node with id and returns it or its index. + Finds sidebar node with id and returns it or its index.
      - hide - hide(id1, [id2], ...) + hide - hide(id1, [id2], ...)
      - Hides sidebar node or nodes with id. + Hides sidebar node or nodes with id.
      - insert - insert([parent], before, nodes) + insert - insert([parent], before, nodes)
      - Inserts a node or nodes before node before. + Inserts a node or nodes before node before.
      - keydown - keydown(event) + keydown - keydown(event)
      - Processes keydown events. + Processes keydown events.
      - lock - lock(message, [showSpinner]) + lock - lock(message, [showSpinner])
      - Locks the sidebar. + Locks the sidebar.
      - menuClick - menuClick(id, index, [event]) + menuClick - menuClick(id, index, [event])
      - Called when user select item from context menu. + Called when user select item from context menu.
      - remove - remove(id1, id2, ...) + remove - remove(id1, id2, ...)
      - Removes nodes from the sidebar. + Removes nodes from the sidebar.
      - scrollIntoView - scrollIntoView([id]) + scrollIntoView - scrollIntoView([id])
      - Scroll nodes into view + Scroll nodes into view
      - select - select(id) + select - select(id)
      - Selects sidebar node with id. + Selects sidebar node with id.
      - set - set([parent], id, node) + set - set([parent], id, node)
      - Finds sidebar node with id and extends it with node object. + Finds sidebar node with id and extends it with node object.
      - show - show(id1, [id2], ...) + show - show(id1, [id2], ...)
      - Shows sidebar node or nodes with id. + Shows sidebar node or nodes with id.
      - toggle - toggle(id) + toggle - toggle(id)
      - Toggles sidebar node with id. + Toggles sidebar node with id.
      - unlock - unlock() + unlock - unlock()
      - Unlocks the sidebar. + Unlocks the sidebar.
      - unselect - unselect(id) + unselect - unselect(id)
      - Unselects sidebar node with id. + Unselects sidebar node with id.
      \ No newline at end of file diff --git a/docs/summary/w2sidebar-props.php b/docs/summary/w2sidebar-props.php index da22591f0..52d54de64 100644 --- a/docs/summary/w2sidebar-props.php +++ b/docs/summary/w2sidebar-props.php @@ -1,72 +1,72 @@
      - bottomHTML - String, default = '' + bottomHTML - String, default = ''
      - Defines HTML on the bottom of the sidebar. + Defines HTML on the bottom of the sidebar.
      - icon - String, default = '' + icon - String, default = ''
      - Default node icon. + Default node icon.
      - img - String, default = '' + img - String, default = ''
      - Default node image. + Default node image.
      - keyboard - Boolean, default = true + keyboard - Boolean, default = true
      - Indicates if sidebar should listen to keyboard. + Indicates if sidebar should listen to keyboard.
      - menu - Array, default = [] + menu - Array, default = []
      - Context menu for the sidebar. + Context menu for the sidebar.
      - nodes - Array, default = [] + nodes - Array, default = []
      - Array of node objects. + Array of node objects.
      - parent - null + parent - null
      - Reference to parent node. Read Only. + Reference to parent node. Read Only.
      - selected - String, default = '' + selected - String, default = ''
      - The id of the selected node. Read Only. + The id of the selected node. Read Only.
      - sidebar - Object + sidebar - Object
      - Reference to itself. Read Only. + Reference to itself. Read Only.
      - topHTML - String, default = '' + topHTML - String, default = ''
      - Defines HTML on the top of the sidebar. + Defines HTML on the top of the sidebar.
      \ No newline at end of file diff --git a/docs/summary/w2tabs-events.php b/docs/summary/w2tabs-events.php index 21a73dbaa..4607dfc5d 100644 --- a/docs/summary/w2tabs-events.php +++ b/docs/summary/w2tabs-events.php @@ -1,16 +1,16 @@
      - onClick - function (event) + onClick - function (event)
      - Called when tab is clicked. + Called when tab is clicked.
      - onClose - function (event) + onClose - function (event)
      - Called when tab is closed. + Called when tab is closed.
      \ No newline at end of file diff --git a/docs/summary/w2tabs-methods.php b/docs/summary/w2tabs-methods.php index bebfb24d1..750b94ad0 100644 --- a/docs/summary/w2tabs-methods.php +++ b/docs/summary/w2tabs-methods.php @@ -1,93 +1,93 @@
      - add - add(tabs) + add - add(tabs)
      - Adds a tab or tabs. + Adds a tab or tabs.
      - animateClose - animateClose(id, [event]) + animateClose - animateClose(id, [event])
      - Removes and animates closing of the tab. + Removes and animates closing of the tab.
      - animateInsert - animateInsert(before, tabs) + animateInsert - animateInsert(before, tabs)
      - Add and animates insertion a tab or tabs. + Add and animates insertion a tab or tabs.
      - click - click(id, [event]) + click - click(id, [event])
      - Called when user clicks the tab. + Called when user clicks the tab.
      - disable - disable(id1, [id2], ...) + disable - disable(id1, [id2], ...)
      - Disables a tab or tabs. + Disables a tab or tabs.
      - enable - enable(id1, [id2], ...) + enable - enable(id1, [id2], ...)
      - Enables a tab or tabs. + Enables a tab or tabs.
      - get - get(id, [returnIndex]) + get - get(id, [returnIndex])
      - Finds and returns specified tab. + Finds and returns specified tab.
      - hide - hide(id1, [id2], ...) + hide - hide(id1, [id2], ...)
      - Hides tab or tabs with id. + Hides tab or tabs with id.
      - insert - insert(before, tabs) + insert - insert(before, tabs)
      - Inserts a tab or tabs before tab with id=before + Inserts a tab or tabs before tab with id=before
      - remove - remove(id1, [id2], ...) + remove - remove(id1, [id2], ...)
      - Removes tabs. + Removes tabs.
      - select - select(id) + select - select(id)
      - Finds tab with id and makes it active. + Finds tab with id and makes it active.
      - set - set(id, tab) + set - set(id, tab)
      - Finds tab with id and extends it with tab object. + Finds tab with id and extends it with tab object.
      - show - show(id1, [id2], ...) + show - show(id1, [id2], ...)
      - Shows tab or tabs with id. + Shows tab or tabs with id.
      \ No newline at end of file diff --git a/docs/summary/w2tabs-props.php b/docs/summary/w2tabs-props.php index d84c11643..4016de903 100644 --- a/docs/summary/w2tabs-props.php +++ b/docs/summary/w2tabs-props.php @@ -1,23 +1,23 @@
      - active - String, default = '' + active - String, default = ''
      - Id of the active tab. + Id of the active tab.
      - right - String, default = '' + right - String, default = ''
      - Defines HTML in the right corner of the tabs. + Defines HTML in the right corner of the tabs.
      - tabs - Array, default = [] + tabs - Array, default = []
      - Array of tab objects. + Array of tab objects.
      \ No newline at end of file diff --git a/docs/summary/w2toolbar-events.php b/docs/summary/w2toolbar-events.php index 6cc8b020d..b475d31f6 100644 --- a/docs/summary/w2toolbar-events.php +++ b/docs/summary/w2toolbar-events.php @@ -1,9 +1,9 @@
      - onClick - function (event) + onClick - function (event)
      - Called when toolbar item is clicked. + Called when toolbar item is clicked.
      \ No newline at end of file diff --git a/docs/summary/w2toolbar-methods.php b/docs/summary/w2toolbar-methods.php index 12bea7ffa..839a49928 100644 --- a/docs/summary/w2toolbar-methods.php +++ b/docs/summary/w2toolbar-methods.php @@ -1,100 +1,100 @@
      - add - add(items) + add - add(items)
      - Adds a toolbar item or items. + Adds a toolbar item or items.
      - check - check(id1, [id2], ...) + check - check(id1, [id2], ...)
      - Checks toolbar item or items with id (visually looks like pressed button). + Checks toolbar item or items with id (visually looks like pressed button).
      - click - click(id, [event]) + click - click(id, [event])
      - Called when user clicks on a toolbar item. + Called when user clicks on a toolbar item.
      - disable - disable(id1, [id2], ...) + disable - disable(id1, [id2], ...)
      - Disables toolbar item or items with id. + Disables toolbar item or items with id.
      - enable - enable(id1, [id2], ...) + enable - enable(id1, [id2], ...)
      - Enables toolbar item or items with id. + Enables toolbar item or items with id.
      - get - get(id, [returnIndex]) + get - get(id, [returnIndex])
      - Finds toolbar item with id and returns it or its index. + Finds toolbar item with id and returns it or its index.
      - getItemHTML - getItemHTML(item) + getItemHTML - getItemHTML(item)
      - Generates HTML for the toolbar item. + Generates HTML for the toolbar item.
      - hide - hide(id1, [id2], ...) + hide - hide(id1, [id2], ...)
      - Hides toolbar item or items with id. + Hides toolbar item or items with id.
      - insert - insert(before, items) + insert - insert(before, items)
      - Inserts a toolbar item or items before item with id=before. + Inserts a toolbar item or items before item with id=before.
      - menuClick - menuClick(id, menu_index, [event]) + menuClick - menuClick(id, menu_index, [event])
      - Called when user selects an item from a drop down menu. + Called when user selects an item from a drop down menu.
      - remove - remove(id1, [id2], ...) + remove - remove(id1, [id2], ...)
      - Removes items from the toolbar. + Removes items from the toolbar.
      - set - set(id, item) + set - set(id, item)
      - Finds toolbar item with id and extends it with item object. + Finds toolbar item with id and extends it with item object.
      - show - show(id1, [id2], ...) + show - show(id1, [id2], ...)
      - Shows toolbar item or items with id. + Shows toolbar item or items with id.
      - uncheck - uncheck(id1, [id2], ...) + uncheck - uncheck(id1, [id2], ...)
      - Unchecks toolbar item or items with id (visually looks like pressed button). + Unchecks toolbar item or items with id (visually looks like pressed button).
      \ No newline at end of file diff --git a/docs/summary/w2toolbar-props.php b/docs/summary/w2toolbar-props.php index b2a53d876..79fa14f3d 100644 --- a/docs/summary/w2toolbar-props.php +++ b/docs/summary/w2toolbar-props.php @@ -1,16 +1,16 @@
      - items - Array, default = [] + items - Array, default = []
      - Array of the item objects. + Array of the item objects.
      - right - String, default = '' + right - String, default = ''
      - Defines HTML in the right corner of the toolbar. + Defines HTML in the right corner of the toolbar.
      \ No newline at end of file diff --git a/docs/summary/w2utils-methods.php b/docs/summary/w2utils-methods.php index 6093a014f..bbd2f524f 100644 --- a/docs/summary/w2utils-methods.php +++ b/docs/summary/w2utils-methods.php @@ -1,191 +1,191 @@
      - age - w2utils.age(dateStr) + age - w2utils.age(dateStr)
      - Returns age in human readable format. + Returns age in human readable format.
      - base64decode - w2utils.base64decode(str) + base64decode - w2utils.base64decode(str)
      - Decodes string using base64 method. + Decodes string using base64 method.
      - base64encode - w2utils.base64encode(str) + base64encode - w2utils.base64encode(str)
      - Encodes string using base64 method. + Encodes string using base64 method.
      - date - w2utils.date(dateStr) + date - w2utils.date(dateStr)
      - Returns date in human readable format. + Returns date in human readable format.
      - encodeTags - w2utils.encodeTags(str) + encodeTags - w2utils.encodeTags(str)
      - Encodes HTML tags. + Encodes HTML tags.
      - escapeId - w2utils.escapeId(id) + escapeId - w2utils.escapeId(id)
      - Escapes id for the use in jQuery. + Escapes id for the use in jQuery.
      - formatDate - w2utils.formatDate(dateStr, format) + formatDate - w2utils.formatDate(dateStr, format)
      - Returns date in requested format. + Returns date in requested format.
      - formatDateTime - w2utils.formatDateTime(dateStr, format) + formatDateTime - w2utils.formatDateTime(dateStr, format)
      - Returns date and time in requested format. + Returns date and time in requested format.
      - formatNumber - w2utils.formatNumber(val) + formatNumber - w2utils.formatNumber(val)
      - Formats a number adding commas. + Formats a number adding commas.
      - formatTime - w2utils.formatTime(dateStr, format) + formatTime - w2utils.formatTime(dateStr, format)
      - Returns time in requested format. + Returns time in requested format.
      - getSize - w2utils.getSize(el, type) + getSize - w2utils.getSize(el, type)
      - Returns the size or absolute position of the element in px including padding, margin and border. + Returns the size or absolute position of the element in px including padding, margin and border.
      - isAlphaNumeric - w2utils.isAlphaNumeric(str) + isAlphaNumeric - w2utils.isAlphaNumeric(str)
      - Returns true if str is alpha-numeric. + Returns true if str is alpha-numeric.
      - isDate - w2utils.isDate(str, [format]) + isDate - w2utils.isDate(str, [format])
      - Returns true if str is a date. + Returns true if str is a date.
      - isEmail - w2utils.isEmail(str) + isEmail - w2utils.isEmail(str)
      - Returns true if str is a valid email address. + Returns true if str is a valid email address.
      - isFloat - w2utils.isFloat(str) + isFloat - w2utils.isFloat(str)
      - Returns true if str is a float number. + Returns true if str is a float number.
      - isHex - w2utils.isHex(str) + isHex - w2utils.isHex(str)
      - Returns true if str is a hex number. + Returns true if str is a hex number.
      - isInt - w2utils.isInt(str) + isInt - w2utils.isInt(str)
      - Returns true if str is a integer number. + Returns true if str is a integer number.
      - isMoney - w2utils.isMoney(str) + isMoney - w2utils.isMoney(str)
      - Returns true if str is in money format. + Returns true if str is in money format.
      - isTime - w2utils.isTime(str) + isTime - w2utils.isTime(str)
      - Returns true if str is a valid time. + Returns true if str is a valid time.
      - lang - w2utils.lang(phrase); + lang - w2utils.lang(phrase);
      - Returns translation for the phrase. + Returns translation for the phrase.
      - locale - w2utils.locale(locale); + locale - w2utils.locale(locale);
      - Loads new locale + Loads new locale
      - lock - w2utils.lock(box, message, showSpinner) + lock - w2utils.lock(box, message, showSpinner)
      - Locks HTML element. + Locks HTML element.
      - scrollBarSize - w2utils.scrollBarSize() + scrollBarSize - w2utils.scrollBarSize()
      - Returns width of a scrollbar + Returns width of a scrollbar
      - size - w2utils.size(int) + size - w2utils.size(int)
      - Returns human readable file size. + Returns human readable file size.
      - stripTags - w2utils.stripTags(str) + stripTags - w2utils.stripTags(str)
      - Removes all HTML tags. + Removes all HTML tags.
      - transition - w2utils.transition(div_old, div_new, type, [callBack]) + transition - w2utils.transition(div_old, div_new, type, [callBack])
      - Transitions two absolute divs. + Transitions two absolute divs.
      - unlock - w2utils.unlock(box) + unlock - w2utils.unlock(box)
      - Unlocks HTML element. + Unlocks HTML element.
      \ No newline at end of file diff --git a/docs/summary/w2utils-props.php b/docs/summary/w2utils-props.php index 4cb9d97e2..95093737f 100644 --- a/docs/summary/w2utils-props.php +++ b/docs/summary/w2utils-props.php @@ -1,23 +1,23 @@
      - event - w2utils.event - object + event - w2utils.event - object
      - An object to work with custom events. + An object to work with custom events.
      - keyboard - w2utils.keyboard - object + keyboard - w2utils.keyboard - object
      - A common object to work with keyboard events + A common object to work with keyboard events
      - settings - w2utils.settings, default see below + settings - w2utils.settings, default see below
      - Global settings for w2ui + Global settings for w2ui
      \ No newline at end of file diff --git a/libs/CodeMirror/mode/apl/index.html b/libs/CodeMirror/mode/apl/index.html index 119ff17f1..15ec3e7ee 100644 --- a/libs/CodeMirror/mode/apl/index.html +++ b/libs/CodeMirror/mode/apl/index.html @@ -9,7 +9,7 @@ diff --git a/libs/CodeMirror/mode/asterisk/index.html b/libs/CodeMirror/mode/asterisk/index.html index 0a796a011..c44be5dcb 100644 --- a/libs/CodeMirror/mode/asterisk/index.html +++ b/libs/CodeMirror/mode/asterisk/index.html @@ -52,66 +52,66 @@

      CodeMirror: Asterisk dialplan mode

      ; ; We start with what to do when a call first comes in. ; -exten => s,1,Wait(1) ; Wait a second, just for fun -same => n,Answer ; Answer the line -same => n,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds -same => n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds -same => n(restart),BackGround(demo-congrats) ; Play a congratulatory message -same => n(instruct),BackGround(demo-instruct) ; Play some instructions -same => n,WaitExten ; Wait for an extension to be dialed. - -exten => 2,1,BackGround(demo-moreinfo) ; Give some more information. +exten => s,1,Wait(1) ; Wait a second, just for fun +same => n,Answer ; Answer the line +same => n,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds +same => n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds +same => n(restart),BackGround(demo-congrats) ; Play a congratulatory message +same => n(instruct),BackGround(demo-instruct) ; Play some instructions +same => n,WaitExten ; Wait for an extension to be dialed. + +exten => 2,1,BackGround(demo-moreinfo) ; Give some more information. exten => 2,n,Goto(s,instruct) -exten => 3,1,Set(LANGUAGE()=fr) ; Set language to french -exten => 3,n,Goto(s,restart) ; Start with the congratulations +exten => 3,1,Set(LANGUAGE()=fr) ; Set language to french +exten => 3,n,Goto(s,restart) ; Start with the congratulations exten => 1000,1,Goto(default,s,1) ; ; We also create an example user, 1234, who is on the console and has ; voicemail, etc. ; -exten => 1234,1,Playback(transfer,skip) ; "Please hold while..." - ; (but skip if channel is not up) +exten => 1234,1,Playback(transfer,skip) ; "Please hold while..." + ; (but skip if channel is not up) exten => 1234,n,Gosub(${EXTEN},stdexten(${GLOBAL(CONSOLE)})) -exten => 1234,n,Goto(default,s,1) ; exited Voicemail +exten => 1234,n,Goto(default,s,1) ; exited Voicemail -exten => 1235,1,Voicemail(1234,u) ; Right to voicemail +exten => 1235,1,Voicemail(1234,u) ; Right to voicemail -exten => 1236,1,Dial(Console/dsp) ; Ring forever -exten => 1236,n,Voicemail(1234,b) ; Unless busy +exten => 1236,1,Dial(Console/dsp) ; Ring forever +exten => 1236,n,Voicemail(1234,b) ; Unless busy ; ; # for when they're done with the demo ; -exten => #,1,Playback(demo-thanks) ; "Thanks for trying the demo" -exten => #,n,Hangup ; Hang them up. +exten => #,1,Playback(demo-thanks) ; "Thanks for trying the demo" +exten => #,n,Hangup ; Hang them up. ; ; A timeout and "invalid extension rule" ; -exten => t,1,Goto(#,1) ; If they take too long, give up -exten => i,1,Playback(invalid) ; "That's not valid, try again" +exten => t,1,Goto(#,1) ; If they take too long, give up +exten => i,1,Playback(invalid) ; "That's not valid, try again" ; ; Create an extension, 500, for dialing the ; Asterisk demo. ; exten => 500,1,Playback(demo-abouttotry); Let them know what's going on -exten => 500,n,Dial(IAX2/guest@pbx.digium.com/s@default) ; Call the Asterisk demo -exten => 500,n,Playback(demo-nogo) ; Couldn't connect to the demo site -exten => 500,n,Goto(s,6) ; Return to the start over message. +exten => 500,n,Dial(IAX2/guest@pbx.digium.com/s@default) ; Call the Asterisk demo +exten => 500,n,Playback(demo-nogo) ; Couldn't connect to the demo site +exten => 500,n,Goto(s,6) ; Return to the start over message. ; ; Create an extension, 600, for evaluating echo latency. ; -exten => 600,1,Playback(demo-echotest) ; Let them know what's going on -exten => 600,n,Echo ; Do the echo test -exten => 600,n,Playback(demo-echodone) ; Let them know it's over -exten => 600,n,Goto(s,6) ; Start over +exten => 600,1,Playback(demo-echotest) ; Let them know what's going on +exten => 600,n,Echo ; Do the echo test +exten => 600,n,Playback(demo-echodone) ; Let them know it's over +exten => 600,n,Goto(s,6) ; Start over ; -; You can use the Macro Page to intercom a individual user +; You can use the Macro Page to intercom a individual user exten => 76245,1,Macro(page,SIP/Grandstream1) ; or if your peernames are the same as extensions exten => _7XXX,1,Macro(page,SIP/${EXTEN}) diff --git a/libs/CodeMirror/mode/go/index.html b/libs/CodeMirror/mode/go/index.html index 8a6aafca2..1405c9ad4 100644 --- a/libs/CodeMirror/mode/go/index.html +++ b/libs/CodeMirror/mode/go/index.html @@ -25,36 +25,36 @@

      CodeMirror: Go mode

      // Send the sequence 2, 3, 4, ... to channel 'ch'. func generate(ch chan<- int) { - for i := 2; ; i++ { - ch <- i // Send 'i' to channel 'ch' - } + for i := 2; ; i++ { + ch <- i // Send 'i' to channel 'ch' + } } // Copy the values from channel 'src' to channel 'dst', // removing those divisible by 'prime'. func filter(src <-chan int, dst chan<- int, prime int) { - for i := range src { // Loop over values received from 'src'. - if i%prime != 0 { - dst <- i // Send 'i' to channel 'dst'. - } - } + for i := range src { // Loop over values received from 'src'. + if i%prime != 0 { + dst <- i // Send 'i' to channel 'dst'. + } + } } // The prime sieve: Daisy-chain filter processes together. func sieve() { - ch := make(chan int) // Create a new channel. - go generate(ch) // Start generate() as a subprocess. - for { - prime := <-ch - fmt.Print(prime, "\n") - ch1 := make(chan int) - go filter(ch, ch1, prime) - ch = ch1 - } + ch := make(chan int) // Create a new channel. + go generate(ch) // Start generate() as a subprocess. + for { + prime := <-ch + fmt.Print(prime, "\n") + ch1 := make(chan int) + go filter(ch, ch1, prime) + ch = ch1 + } } func main() { - sieve() + sieve() } diff --git a/libs/CodeMirror/mode/haxe/index.html b/libs/CodeMirror/mode/haxe/index.html index 1125741ad..cec934db0 100644 --- a/libs/CodeMirror/mode/haxe/index.html +++ b/libs/CodeMirror/mode/haxe/index.html @@ -18,62 +18,62 @@

      CodeMirror: Haxe mode

      @attr("test") class Foo<T> extends Three { - public function new() - { - noFoo = 12; - } - - public static inline function doFoo(obj:{k:Int, l:Float}):Int - { - for(i in 0...10) - { - obj.k++; - trace(i); - var var1 = new Array(); - if(var1.length > 1) - throw "Error"; - } - // The following line should not be colored, the variable is scoped out - var1; - /* Multi line - * Comment test - */ - return obj.k; - } - private function bar():Void - { - #if flash - var t1:String = "1.21"; - #end - try { - doFoo({k:3, l:1.2}); - } - catch (e : String) { - trace(e); - } - var t2:Float = cast(3.2); - var t3:haxe.Timer = new haxe.Timer(); - var t4 = {k:Std.int(t2), l:Std.parseFloat(t1)}; - var t5 = ~/123+.*$/i; - doFoo(t4); - untyped t1 = 4; - bob = new Foo<Int> - } - public var okFoo(default, never):Float; - var noFoo(getFoo, null):Int; - function getFoo():Int { - return noFoo; - } - - public var three:Int; + public function new() + { + noFoo = 12; + } + + public static inline function doFoo(obj:{k:Int, l:Float}):Int + { + for(i in 0...10) + { + obj.k++; + trace(i); + var var1 = new Array(); + if(var1.length > 1) + throw "Error"; + } + // The following line should not be colored, the variable is scoped out + var1; + /* Multi line + * Comment test + */ + return obj.k; + } + private function bar():Void + { + #if flash + var t1:String = "1.21"; + #end + try { + doFoo({k:3, l:1.2}); + } + catch (e : String) { + trace(e); + } + var t2:Float = cast(3.2); + var t3:haxe.Timer = new haxe.Timer(); + var t4 = {k:Std.int(t2), l:Std.parseFloat(t1)}; + var t5 = ~/123+.*$/i; + doFoo(t4); + untyped t1 = 4; + bob = new Foo<Int> + } + public var okFoo(default, never):Float; + var noFoo(getFoo, null):Int; + function getFoo():Int { + return noFoo; + } + + public var three:Int; } enum Color { - red; - green; - blue; - grey( v : Int ); - rgb (r:Int,g:Int,b:Int); + red; + green; + blue; + grey( v : Int ); + rgb (r:Int,g:Int,b:Int); }
      diff --git a/libs/CodeMirror/mode/htmlembedded/index.html b/libs/CodeMirror/mode/htmlembedded/index.html index 5a37dd637..b7c85526a 100644 --- a/libs/CodeMirror/mode/htmlembedded/index.html +++ b/libs/CodeMirror/mode/htmlembedded/index.html @@ -19,13 +19,13 @@

      CodeMirror: Html Embedded Scripts mode

      diff --git a/libs/CodeMirror/mode/http/index.html b/libs/CodeMirror/mode/http/index.html index 124eb84f9..b86d71f4f 100644 --- a/libs/CodeMirror/mode/http/index.html +++ b/libs/CodeMirror/mode/http/index.html @@ -17,7 +17,7 @@

      CodeMirror: HTTP mode

      Host: example.com If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT Content-Type: application/x-www-form-urlencoded; - charset=utf-8 + charset=utf-8 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Ubuntu/12.04 Chromium/20.0.1132.47 Chrome/20.0.1132.47 Safari/536.11 This is the request body! diff --git a/libs/CodeMirror/mode/javascript/typescript.html b/libs/CodeMirror/mode/javascript/typescript.html index 58315e7ac..764e20595 100644 --- a/libs/CodeMirror/mode/javascript/typescript.html +++ b/libs/CodeMirror/mode/javascript/typescript.html @@ -14,13 +14,13 @@

      CodeMirror: TypeScript mode

      diff --git a/libs/CodeMirror/mode/q/index.html b/libs/CodeMirror/mode/q/index.html index 303ec1d3a..64f5bc9cb 100644 --- a/libs/CodeMirror/mode/q/index.html +++ b/libs/CodeMirror/mode/q/index.html @@ -20,14 +20,14 @@

      CodeMirror: Q mode

      / .csv.colhdrs[file] - return a list of colhdrs from file / info:.csv.info[file] - return a table of information about the file / columns are: -/ c - column name; ci - column index; t - load type; mw - max width; -/ dchar - distinct characters in values; rule - rule that caught the type -/ maybe - needs checking, _could_ be say a date, but perhaps just a float? +/ c - column name; ci - column index; t - load type; mw - max width; +/ dchar - distinct characters in values; rule - rule that caught the type +/ maybe - needs checking, _could_ be say a date, but perhaps just a float? / .csv.info0[file;onlycols] - like .csv.info except that it only analyses / example: -/ info:.csv.info0[file;(.csv.colhdrs file)like"*price"] -/ info:.csv.infolike[file;"*price"] -/ show delete from info where t=" " +/ info:.csv.info0[file;(.csv.colhdrs file)like"*price"] +/ info:.csv.infolike[file;"*price"] +/ show delete from info where t=" " / .csv.data[file;info] - use the info from .csv.info to read the data / .csv.data10[file;info] - like .csv.data but only returns the first 10 rows / bulkload[file;info] - bulk loads file into table DATA (which must be already defined :: DATA:() ) @@ -53,69 +53,69 @@

      CodeMirror: Q mode

      read10:{[file]data10[file;info[file]]} colhdrs:{[file] - `$nameltrim DELIM vs cleanhdrs first read0(file;0;1+first where 0xa=read1(file;0;WIDTHHDR))} + `$nameltrim DELIM vs cleanhdrs first read0(file;0;1+first where 0xa=read1(file;0;WIDTHHDR))} data:{[file;info] - (exec c from info where not t=" ")xcol(exec t from info;enlist DELIM)0:file} + (exec c from info where not t=" ")xcol(exec t from info;enlist DELIM)0:file} data10:{[file;info] - data[;info](file;0;1+last 11#where 0xa=read1(file;0;15*WIDTHHDR))} + data[;info](file;0;1+last 11#where 0xa=read1(file;0;15*WIDTHHDR))} info0:{[file;onlycols] - colhdrs:`$nameltrim DELIM vs cleanhdrs first head:read0(file;0;1+last where 0xa=read1(file;0;WIDTHHDR)); - loadfmts:(count colhdrs)#"S";if[count onlycols;loadfmts[where not colhdrs in onlycols]:"C"]; - breaks:where 0xa=read1(file;0;floor(10+READLINES)*WIDTHHDR%count head); - nas:count as:colhdrs xcol(loadfmts;enlist DELIM)0:(file;0;1+last((1+READLINES)&count breaks)#breaks); - info:([]c:key flip as;v:value flip as);as:(); - reserved:key`.q;reserved,:.Q.res;reserved,:`i; - info:update res:c in reserved from info; - info:update ci:i,t:"?",ipa:0b,mdot:0,mw:0,rule:0,gr:0,ndv:0,maybe:0b,empty:0b,j10:0b,j12:0b from info; - info:update ci:`s#ci from info; - if[count onlycols;info:update t:" ",rule:10 from info where not c in onlycols]; - info:update sdv:{string(distinct x)except`}peach v from info; - info:update ndv:count each sdv from info; - info:update gr:floor 0.5+100*ndv%nas,mw:{max count each x}peach sdv from info where 0.csv.FORCECHARWIDTH; / long values - info:update t:"C "[.csv.DISCARDEMPTY],rule:30,empty:1b from info where t="?",mw=0; / empty columns - info:update dchar:{asc distinct raze x}peach sdv from info where t="?"; - info:update mdot:{max sum each"."=x}peach sdv from info where t="?",{"."in x}each dchar; - info:update t:"n",rule:40 from info where t="?",{any x in"0123456789"}each dchar; / vaguely numeric.. - info:update t:"I",rule:50,ipa:1b from info where t="n",mw within 7 15,mdot=3,{all x in".0123456789"}each dchar,.csv.cancast["I"]peach sdv; / ip-address - info:update t:"J",rule:60 from info where t="n",mdot=0,{all x in"+-0123456789"}each dchar,.csv.cancast["J"]peach sdv; - info:update t:"I",rule:70 from info where t="J",mw<12,.csv.cancast["I"]peach sdv; - info:update t:"H",rule:80 from info where t="I",mw<7,.csv.cancast["H"]peach sdv; - info:update t:"F",rule:90 from info where t="n",mdot<2,mw>1,.csv.cancast["F"]peach sdv; - info:update t:"E",rule:100,maybe:1b from info where t="F",mw<9; - info:update t:"M",rule:110,maybe:1b from info where t in"nIHEF",mdot<2,mw within 4 7,.csv.cancast["M"]peach sdv; - info:update t:"D",rule:120,maybe:1b from info where t in"nI",mdot in 0 2,mw within 6 11,.csv.cancast["D"]peach sdv; - info:update t:"V",rule:130,maybe:1b from info where t="I",mw in 5 6,71,gr<.csv.SYMMAXGR; / symbols (max width permitting) - info:update t:"*",rule:280,maybe:0b from info where t="?"; / the rest as strings - / flag those S/* columns which could be encoded to integers (.Q.j10/x10/j12/x12) to avoid symbols - info:update j12:1b from info where t in"S*",mw<13,{all x in .Q.nA}each dchar; - info:update j10:1b from info where t in"S*",mw<11,{all x in .Q.b6}each dchar; - select c,ci,t,maybe,empty,res,j10,j12,ipa,mw,mdot,rule,gr,ndv,dchar from info} + colhdrs:`$nameltrim DELIM vs cleanhdrs first head:read0(file;0;1+last where 0xa=read1(file;0;WIDTHHDR)); + loadfmts:(count colhdrs)#"S";if[count onlycols;loadfmts[where not colhdrs in onlycols]:"C"]; + breaks:where 0xa=read1(file;0;floor(10+READLINES)*WIDTHHDR%count head); + nas:count as:colhdrs xcol(loadfmts;enlist DELIM)0:(file;0;1+last((1+READLINES)&count breaks)#breaks); + info:([]c:key flip as;v:value flip as);as:(); + reserved:key`.q;reserved,:.Q.res;reserved,:`i; + info:update res:c in reserved from info; + info:update ci:i,t:"?",ipa:0b,mdot:0,mw:0,rule:0,gr:0,ndv:0,maybe:0b,empty:0b,j10:0b,j12:0b from info; + info:update ci:`s#ci from info; + if[count onlycols;info:update t:" ",rule:10 from info where not c in onlycols]; + info:update sdv:{string(distinct x)except`}peach v from info; + info:update ndv:count each sdv from info; + info:update gr:floor 0.5+100*ndv%nas,mw:{max count each x}peach sdv from info where 0.csv.FORCECHARWIDTH; / long values + info:update t:"C "[.csv.DISCARDEMPTY],rule:30,empty:1b from info where t="?",mw=0; / empty columns + info:update dchar:{asc distinct raze x}peach sdv from info where t="?"; + info:update mdot:{max sum each"."=x}peach sdv from info where t="?",{"."in x}each dchar; + info:update t:"n",rule:40 from info where t="?",{any x in"0123456789"}each dchar; / vaguely numeric.. + info:update t:"I",rule:50,ipa:1b from info where t="n",mw within 7 15,mdot=3,{all x in".0123456789"}each dchar,.csv.cancast["I"]peach sdv; / ip-address + info:update t:"J",rule:60 from info where t="n",mdot=0,{all x in"+-0123456789"}each dchar,.csv.cancast["J"]peach sdv; + info:update t:"I",rule:70 from info where t="J",mw<12,.csv.cancast["I"]peach sdv; + info:update t:"H",rule:80 from info where t="I",mw<7,.csv.cancast["H"]peach sdv; + info:update t:"F",rule:90 from info where t="n",mdot<2,mw>1,.csv.cancast["F"]peach sdv; + info:update t:"E",rule:100,maybe:1b from info where t="F",mw<9; + info:update t:"M",rule:110,maybe:1b from info where t in"nIHEF",mdot<2,mw within 4 7,.csv.cancast["M"]peach sdv; + info:update t:"D",rule:120,maybe:1b from info where t in"nI",mdot in 0 2,mw within 6 11,.csv.cancast["D"]peach sdv; + info:update t:"V",rule:130,maybe:1b from info where t="I",mw in 5 6,71,gr<.csv.SYMMAXGR; / symbols (max width permitting) + info:update t:"*",rule:280,maybe:0b from info where t="?"; / the rest as strings + / flag those S/* columns which could be encoded to integers (.Q.j10/x10/j12/x12) to avoid symbols + info:update j12:1b from info where t in"S*",mw<13,{all x in .Q.nA}each dchar; + info:update j10:1b from info where t in"S*",mw<11,{all x in .Q.b6}each dchar; + select c,ci,t,maybe,empty,res,j10,j12,ipa,mw,mdot,rule,gr,ndv,dchar from info} info:info0[;()] / by default don't restrict columns infolike:{[file;pattern] info0[file;{x where x like y}[lower colhdrs[file];pattern]]} / .csv.infolike[file;"*time"] \d . / DATA:() bulkload:{[file;info] - if[not`DATA in system"v";'`DATA.not.defined]; - if[count DATA;'`DATA.not.empty]; - loadhdrs:exec c from info where not t=" ";loadfmts:exec t from info; - .csv.fs2[{[file;loadhdrs;loadfmts] `DATA insert $[count DATA;flip loadhdrs!(loadfmts;.csv.DELIM)0:file;loadhdrs xcol(loadfmts;enlist .csv.DELIM)0:file]}[file;loadhdrs;loadfmts]]; - count DATA} + if[not`DATA in system"v";'`DATA.not.defined]; + if[count DATA;'`DATA.not.empty]; + loadhdrs:exec c from info where not t=" ";loadfmts:exec t from info; + .csv.fs2[{[file;loadhdrs;loadfmts] `DATA insert $[count DATA;flip loadhdrs!(loadfmts;.csv.DELIM)0:file;loadhdrs xcol(loadfmts;enlist .csv.DELIM)0:file]}[file;loadhdrs;loadfmts]]; + count DATA} @[.:;"\\l csvutil.custom.q";::]; / save your custom settings in csvutil.custom.q to override those set at the beginning of the file
      diff --git a/libs/CodeMirror/mode/scheme/index.html b/libs/CodeMirror/mode/scheme/index.html index 5936a0241..63c7bef74 100644 --- a/libs/CodeMirror/mode/scheme/index.html +++ b/libs/CodeMirror/mode/scheme/index.html @@ -15,21 +15,21 @@

      CodeMirror: Scheme mode

      ; See if the input starts with a given symbol. (define (match-symbol input pattern) (cond ((null? (remain input)) #f) - ((eqv? (car (remain input)) pattern) (r-cdr input)) - (else #f))) + ((eqv? (car (remain input)) pattern) (r-cdr input)) + (else #f))) ; Allow the input to start with one of a list of patterns. (define (match-or input pattern) (cond ((null? pattern) #f) - ((match-pattern input (car pattern))) - (else (match-or input (cdr pattern))))) + ((match-pattern input (car pattern))) + (else (match-or input (cdr pattern))))) ; Allow a sequence of patterns. (define (match-seq input pattern) (if (null? pattern) input (let ((match (match-pattern input (car pattern)))) - (if match (match-seq match (cdr pattern)) #f)))) + (if match (match-seq match (cdr pattern)) #f)))) ; Match with the pattern but no problem if it does not match. (define (match-opt input pattern) @@ -42,18 +42,18 @@

      CodeMirror: Scheme mode

      ; of the sentence. (define (match-any input pattern) (cond ((null? (remain input)) #f) - ((null? pattern) (f-cons (remain input) (clear-remain input))) - (else - (let ((accum-any (collector))) - (define (match-pattern-any input pattern) - (cond ((null? (remain input)) #f) - (else (accum-any (car (remain input))) - (cond ((match-pattern (r-cdr input) pattern)) - (else (match-pattern-any (r-cdr input) pattern)))))) - (let ((retval (match-pattern-any input (car pattern)))) - (if retval - (f-cons (accum-any) retval) - #f)))))) + ((null? pattern) (f-cons (remain input) (clear-remain input))) + (else + (let ((accum-any (collector))) + (define (match-pattern-any input pattern) + (cond ((null? (remain input)) #f) + (else (accum-any (car (remain input))) + (cond ((match-pattern (r-cdr input) pattern)) + (else (match-pattern-any (r-cdr input) pattern)))))) + (let ((retval (match-pattern-any input (car pattern)))) + (if retval + (f-cons (accum-any) retval) + #f)))))) -
      +
      -

      Smarty 3

      +

      Smarty 3

      - - +

      A plain text/Smarty version 2 or 3 mode, which allows for custom delimiter tags.

      diff --git a/libs/CodeMirror/mode/sql/index.html b/libs/CodeMirror/mode/sql/index.html index acf60b88c..f377dcf73 100644 --- a/libs/CodeMirror/mode/sql/index.html +++ b/libs/CodeMirror/mode/sql/index.html @@ -38,18 +38,18 @@

      SQL Mode for CodeMirror

      MIME types defined: diff --git a/libs/CodeMirror/mode/stex/index.html b/libs/CodeMirror/mode/stex/index.html index 2dafe6981..8bdd28d33 100644 --- a/libs/CodeMirror/mode/stex/index.html +++ b/libs/CodeMirror/mode/stex/index.html @@ -58,7 +58,7 @@

      CodeMirror: sTeX mode

      \end{spfcases} \end{sproof} \item - \begin{assertion}[id=fbbt,type=corollary] + \begin{assertion}[id=fbbt,type=corollary] A fully balanced tree of depth $d$ has $\power2{d+1}-1$ nodes. \end{assertion} \item diff --git a/libs/CodeMirror/mode/tcl/index.html b/libs/CodeMirror/mode/tcl/index.html index e2e42a04b..485c91ff3 100644 --- a/libs/CodeMirror/mode/tcl/index.html +++ b/libs/CodeMirror/mode/tcl/index.html @@ -63,13 +63,13 @@

      CodeMirror: Tcl mode

      proc whois::311 {from key text} { if {[regexp -- {^[^\s]+\s(.+?)\s(.+?)\s(.+?)\s\*\s\:(.+)$} $text wholematch nick ident host realname]} { putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Host:${whois::textf} \ - $nick \(${ident}@${host}\) ${whois::tagf}Realname:${whois::textf} $realname" + $nick \(${ident}@${host}\) ${whois::tagf}Realname:${whois::textf} $realname" } } proc whois::multi {from key text} { if {[regexp {\:(.*)$} $text match $key]} { putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Note:${whois::textf} [subst $$key]" - return 1 + return 1 } } proc whois::312 {from key text} { @@ -84,7 +84,7 @@

      CodeMirror: Tcl mode

      proc whois::317 {from key text} { if {[regexp -- {.*\s(\d+)\s(\d+)\s\:} $text wholematch idle signon]} { putserv "PRIVMSG $whois::channel :${whois::logo} ${whois::tagf}Connected:${whois::textf} \ - [ctime $signon] ${whois::tagf}Idle:${whois::textf} [duration $idle]" + [ctime $signon] ${whois::tagf}Idle:${whois::textf} [duration $idle]" } } proc whois::301 {from key text} { @@ -94,7 +94,7 @@

      CodeMirror: Tcl mode

      } proc whois::318 {from key text} { namespace eval whois { - variable channel "" + variable channel "" } variable whois::channel "" } @@ -104,8 +104,8 @@

      CodeMirror: Tcl mode

      proc whois::list {nick host hand chan text} { if {[lsearch -exact [channel info $chan] "+${whois::command}"] != -1} { namespace eval whois { - variable channel "" - } + variable channel "" + } variable whois::channel $chan putserv "WHOIS $text" } @@ -116,7 +116,7 @@

      CodeMirror: Tcl mode

      diff --git a/libs/CodeMirror/mode/vbscript/index.html b/libs/CodeMirror/mode/vbscript/index.html index 9ae46676b..8d2cb1bf8 100644 --- a/libs/CodeMirror/mode/vbscript/index.html +++ b/libs/CodeMirror/mode/vbscript/index.html @@ -23,10 +23,10 @@

      CodeMirror: VBScript mode

      Call Sub020_PostBroadcastToUrbanAirship(strUserName, strPassword, intTransmitID, strResponse) If Not IsNull(strResponse) AND Len(strResponse) = 0 Then - boolTransmitOkYN = False + boolTransmitOkYN = False Else - ' WScript.Echo "Oh Happy Day! Oh Happy DAY!" - boolTransmitOkYN = True + ' WScript.Echo "Oh Happy Day! Oh Happy DAY!" + boolTransmitOkYN = True End If
      diff --git a/libs/CodeMirror/mode/xquery/index.html b/libs/CodeMirror/mode/xquery/index.html index 27acb8978..1e9ec8a6e 100644 --- a/libs/CodeMirror/mode/xquery/index.html +++ b/libs/CodeMirror/mode/xquery/index.html @@ -33,17 +33,17 @@

      CodeMirror: XQuery mode

      - '; - html += '\n
      '+ field.html.caption +':
      '+ - '\n
      '+ - input + field.html.text + - '
      '; - if (typeof pages[field.html.page] == 'undefined') pages[field.html.page] = '
      '; - pages[field.html.page] += html; - } - for (var p in pages) pages[p] += '\n
      '; - // buttons if any - var buttons = ''; - if (!$.isEmptyObject(this.actions)) { - buttons += '\n
      '; - for (var a in this.actions) { - buttons += '\n '; - } - buttons += '\n
      '; - } - return pages.join('') + buttons; - }, - - action: function (action, event) { - // event before - var eventData = this.trigger({ phase: 'before', target: action, type: 'action', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default actions - if (typeof (this.actions[action]) == 'function') { - this.actions[action].call(this, event); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - resize: function () { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'resize' }); - if (eventData.isCancelled === true) return; - // default behaviour - var main = $(this.box).find('> div'); - var header = $(this.box).find('> div .w2ui-form-header'); - var toolbar = $(this.box).find('> div .w2ui-form-toolbar'); - var tabs = $(this.box).find('> div .w2ui-form-tabs'); - var page = $(this.box).find('> div .w2ui-page'); - var cpage = $(this.box).find('> div .w2ui-page.page-'+ this.page); - var dpage = $(this.box).find('> div .w2ui-page.page-'+ this.page + ' > div'); - var buttons = $(this.box).find('> div .w2ui-buttons'); - // if no height, calculate it - resizeElements(); - if (parseInt($(this.box).height()) == 0 || $(this.box).data('auto-size') === true) { - $(this.box).height( - (header.length > 0 ? w2utils.getSize(header, 'height') : 0) + - ((typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') : 0) + - ((typeof this.toolbar == 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0) + - (page.length > 0 ? w2utils.getSize(dpage, 'height') + w2utils.getSize(cpage, '+height') + 12 : 0) + // why 12 ??? - (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) - ); - $(this.box).data('auto-size', true); - } - resizeElements(); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - - function resizeElements() { - // resize elements - main.width($(obj.box).width()).height($(obj.box).height()); - toolbar.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0)); - tabs.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0) - + ((typeof obj.toolbar == 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0)); - page.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0) - + ((typeof obj.toolbar == 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') + 5 : 0) - + ((typeof obj.tabs === 'object' && $.isArray(obj.tabs.tabs) && obj.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') + 5 : 0)); - page.css('bottom', (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0)); - } - }, - - refresh: function () { - var time = (new Date()).getTime(); - var obj = this; - if (!this.box) return; - if (!this.isGenerated || typeof $(this.box).html() == 'undefined') return; - // update what page field belongs - $(this.box).find('input, textarea, select').each(function (index, el) { - var name = (typeof $(el).attr('name') != 'undefined' ? $(el).attr('name') : $(el).attr('id')); - var field = obj.get(name); - if (field) { - // find page - var div = $(el).parents('.w2ui-page'); - if (div.length > 0) { - for (var i = 0; i < 100; i++) { - if (div.hasClass('page-'+i)) { field.page = i; break; } - } - } - } - }); - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'refresh', page: this.page }) - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('.w2ui-page').hide(); - $(this.box).find('.w2ui-page.page-' + this.page).show(); - $(this.box).find('.w2ui-form-header').html(this.header); - // refresh tabs if needed - if (typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) { - $('#form_'+ this.name +'_tabs').show(); - this.tabs.active = this.tabs.tabs[this.page].id; - this.tabs.refresh(); - } else { - $('#form_'+ this.name +'_tabs').hide(); - } - // refresh tabs if needed - if (typeof this.toolbar == 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) { - $('#form_'+ this.name +'_toolbar').show(); - this.toolbar.refresh(); - } else { - $('#form_'+ this.name +'_toolbar').hide(); - } - // refresh values of all fields - for (var f in this.fields) { - var field = this.fields[f]; - field.$el = $(this.box).find('[name="'+ String(field.name).replace(/\\/g, '\\\\') +'"]'); - field.el = field.$el[0]; - if (typeof field.el == 'undefined') { - console.log('ERROR: Cannot associate field "'+ field.name + '" with html control. Make sure html control exists with the same name.'); - //return; - } - if (field.el) field.el.id = field.name; - var tmp = $(field).data('w2field'); - if (tmp) tmp.clear(); - $(field.$el).off('change').on('change', function () { - var value_new = this.value; - var value_previous = obj.record[this.name] ? obj.record[this.name] : ''; - var field = obj.get(this.name); - if (['list', 'enum', 'file'].indexOf(field.type) != -1 && $(this).data('selected')) { - var nv = $(this).data('selected'); - var cv = obj.record[this.name]; - if ($.isArray(nv)) { - value_new = []; - for (var i in nv) value_new[i] = $.extend(true, {}, nv[i]); // clone array - } - if ($.isPlainObject(nv)) { - value_new = $.extend(true, {}, nv); // clone object - } - if ($.isArray(cv)) { - value_previous = []; - for (var i in cv) value_previous[i] = $.extend(true, {}, cv[i]); // clone array - } - if ($.isPlainObject(cv)) { - value_previous = $.extend(true, {}, cv); // clone object - } - } - // clean extra chars - if (['int', 'float', 'percent', 'money', 'currency'].indexOf(field.type) != -1) { - value_new = $(this).data('w2field').clean(value_new); - } - if (value_new === value_previous) return; - // event before - var eventData = obj.trigger({ phase: 'before', target: this.name, type: 'change', value_new: value_new, value_previous: value_previous }); - if (eventData.isCancelled === true) { - $(this).val(obj.record[this.name]); // return previous value - return; - } - // default action - var val = this.value; - if (this.type == 'select') val = this.value; - if (this.type == 'checkbox') val = this.checked ? true : false; - if (this.type == 'radio') { - field.$el.each(function (index, el) { - if (el.checked) val = el.value; - }); - } - if (['int', 'float', 'percent', 'money', 'currency', 'list', 'combo', 'enum', 'file'].indexOf(field.type) != -1) { - val = value_new; - } - if (['enum', 'file'].indexOf(field.type) != -1) { - if (val.length > 0) { - var fld = $(field.el).data('w2field').helpers.multi; - $(fld).removeClass('w2ui-error'); - } - } - obj.record[this.name] = val; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }); - if (field.required) { - $(field.el).parent().addClass('w2ui-required'); - } else { - $(field.el).parent().removeClass('w2ui-required'); - } - } - // attach actions on buttons - $(this.box).find('button, input[type=button]').each(function (index, el) { - $(el).off('click').on('click', function (event) { - var action = this.value; - if (this.name) action = this.name; - if (this.id) action = this.id; - obj.action(action, event); - }); - }); - // init controls with record - for (var f in this.fields) { - var field = this.fields[f]; - var value = (typeof this.record[field.name] != 'undefined' ? this.record[field.name] : ''); - if (!field.el) continue; - field.type = String(field.type).toLowerCase(); - if (!field.options) field.options = {}; - switch (field.type) { - case 'text': - case 'textarea': - case 'email': - case 'password': - field.el.value = value; - break; - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'hex': - case 'alphanumeric': - case 'color': - case 'date': - case 'time': - field.el.value = value; - $(field.el).w2field($.extend({}, field.options, { type: field.type })); - break; - - // enums - case 'list': - case 'combo': - if (field.type == 'list' && !$.isPlainObject(value)) { - // find value from items - for (var i in field.options.items) { - var item = field.options.items[i]; - if (item && item.id == value) { - value = $.extend(true, {}, item); - obj.record[field.name] = value; - break; - } - } - } else if (field.type == 'combo' && !$.isPlainObject(value)) { - field.el.value = value; - } else if ($.isPlainObject(value) && typeof value.text != 'undefined') { - field.el.value = value.text; - } else { - field.el.value = ''; - } - if (!$.isPlainObject(value)) value = {}; - $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); - break; - case 'enum': - case 'file': - if (!$.isArray(value)) value = []; - $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); - break; - - // standard HTML - case 'select': - // generate options - var items = field.options.items; - if (typeof items != 'undefined' && items.length > 0) { - items = w2obj.field.prototype.normMenu(items); - $(field.el).html(''); - for (var it in items) { - $(field.el).append(''; - } - el.addClass('w2ui-editable') - .html('' + edit.outTag); - el.find('select').focus() - .on('change', function (event) { - delete obj.last.move; - }) - .on('blur', function (event) { - obj.editChange.call(obj, this, index, column, event); - }); - } else { - el.addClass('w2ui-editable') - .html('' + edit.outTag); - if (value == null) el.find('input').val(val != 'object' ? val : ''); - // init w2field - var input = el.find('input').get(0); - $(input).w2field(edit.type, $.extend(edit, { selected: val })) - // add blur listener - setTimeout(function () { - var tmp = input; - if (edit.type == 'list') { - tmp = $($(input).data('w2field').helpers.focus).find('input'); - if (val != 'object' && val != '') tmp.val(val).css({ opacity: 1 }).prev().css({ opacity: 1 }); - } - $(tmp).on('blur', function (event) { - obj.editChange.call(obj, input, index, column, event); - }); - }, 10); - if (value != null) $(input).val(val != 'object' ? val : ''); - } - setTimeout(function () { - el.find('input, select') - .on('click', function (event) { - event.stopPropagation(); - }) - .on('keydown', function (event) { - var cancel = false; - switch (event.keyCode) { - case 9: // tab - cancel = true; - var next_rec = recid; - var next_col = event.shiftKey ? obj.prevCell(column, true) : obj.nextCell(column, true); - // next or prev row - if (next_col === false) { - var tmp = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); - if (tmp != null && tmp != index) { - next_rec = obj.records[tmp].recid; - // find first editable row - for (var c in obj.columns) { - var tmp = obj.columns[c].editable; - if (typeof tmp != 'undefined' && ['checkbox', 'check'].indexOf(tmp.type) == -1) { - next_col = parseInt(c); - if (!event.shiftKey) break; - } - } - } - - } - if (next_rec === false) next_rec = recid; - if (next_col === false) next_col = column; - // init new or same record - this.blur(); - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: next_rec, column: next_col }); - } else { - obj.editField(next_rec, next_col, null, event); - } - }, 1); - break; - - case 13: // enter - this.blur(); - var next = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); - if (next != null && next != index) { - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: obj.records[next].recid, column: column }); - } else { - obj.editField(obj.records[next].recid, column, null, event); - } - }, 100); - } - break; - - case 38: // up arrow - if (!event.shiftKey) break; - cancel = true; - var next = obj.prevRow(index); - if (next != index) { - this.blur(); - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: obj.records[next].recid, column: column }); - } else { - obj.editField(obj.records[next].recid, column, null, event); - } - }, 1); - } - break; - - case 40: // down arrow - if (!event.shiftKey) break; - cancel = true; - var next = obj.nextRow(index); - if (next != null && next != index) { - this.blur(); - setTimeout(function () { - if (obj.selectType != 'row') { - obj.selectNone(); - obj.select({ recid: obj.records[next].recid, column: column }); - } else { - obj.editField(obj.records[next].recid, column, null, event); - } - }, 1); - } - break; - - case 27: // escape - var old = obj.parseField(rec, col.field); - if (rec.changes && typeof rec.changes[col.field] != 'undefined') old = rec.changes[col.field]; - this.value = typeof old != 'undefined' ? old : ''; - this.blur(); - setTimeout(function () { obj.select({ recid: recid, column: column }) }, 1); - break; - } - if (cancel) if (event.preventDefault) event.preventDefault(); - }); - // focus and select - var tmp = el.find('input').focus(); - if (value != null) { - // set cursor to the end - tmp[0].setSelectionRange(tmp.val().length, tmp.val().length); - } else { - tmp.select(); - } - - }, 1); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - editChange: function (el, index, column, event) { - // all other fields - var summary = index < 0; - index = index < 0 ? -index - 1 : index; - var records = summary ? this.summary : this.records; - var rec = records[index]; - var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)); - var col = this.columns[column]; - var new_val = el.value; - var old_val = this.parseField(rec, col.field); - var tmp = $(el).data('w2field'); - if (tmp) { - new_val = tmp.clean(new_val); - if (tmp.type == 'list' && new_val != '') new_val = $(el).data('selected'); - } - if (el.type == 'checkbox') new_val = el.checked; - // change/restore event - var eventData = { - phase: 'before', type: 'change', target: this.name, input_id: el.id, recid: rec.recid, index: index, column: column, - value_new: new_val, value_previous: (rec.changes && rec.changes.hasOwnProperty(col.field) ? rec.changes[col.field]: old_val), value_original: old_val - }; - while (true) { - new_val = eventData.value_new; - if (( typeof old_val == 'undefined' || old_val === null ? '' : String(old_val)) !== String(new_val)) { - // change event - eventData = this.trigger($.extend(eventData, { type: 'change', phase: 'before' })); - if (eventData.isCancelled !== true) { - if (new_val !== eventData.value_new) { - // re-evaluate the type of change to be made - continue; - } - // default action - rec.changes = rec.changes || {}; - rec.changes[col.field] = eventData.value_new; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - } else { - // restore event - eventData = this.trigger($.extend(eventData, { type: 'restore', phase: 'before' })); - if (eventData.isCancelled !== true) { - if (new_val !== eventData.value_new) { - // re-evaluate the type of change to be made - continue; - } - // default action - if (rec.changes) delete rec.changes[col.field]; - if ($.isEmptyObject(rec.changes)) delete rec.changes; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - } - break; - } - // refresh cell - var cell = this.getCellHTML(index, column, summary); - if (!summary) { - if (rec.changes && typeof rec.changes[col.field] != 'undefined') { - $(tr).find('[col='+ column +']').addClass('w2ui-changed').html(cell); - } else { - $(tr).find('[col='+ column +']').removeClass('w2ui-changed').html(cell); - } - } - }, - - delete: function (force) { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'delete', force: force }); - if (eventData.isCancelled === true) return; - force = eventData.force; - // default action - var recs = this.getSelection(); - if (recs.length == 0) return; - if (this.msgDelete != '' && !force) { - w2confirm({ - title : w2utils.lang('Delete Confirmation'), - msg : obj.msgDelete, - callBack: function (result) { - console.log('result', result); - if (result == 'Yes') w2ui[obj.name].delete(true); - } - }); - return; - } - // call delete script - var url = (typeof this.url != 'object' ? this.url : this.url.remove); - if (url) { - this.request('delete-records'); - } else { - this.selectNone(); - if (typeof recs[0] != 'object') { - this.remove.apply(this, recs); - } else { - // clear cells - for (var r in recs) { - var fld = this.columns[recs[r].column].field; - var ind = this.get(recs[r].recid, true); - if (ind != null && fld != 'recid') { - this.records[ind][fld] = ''; - if (this.records[ind].changes) delete this.records[ind].changes[fld]; - } - } - this.refresh(); - } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - click: function (recid, event) { - var time = (new Date()).getTime(); - var column = null; - if (this.last.cancelClick == true) return; - if (typeof recid == 'object') { - column = recid.column; - recid = recid.recid; - } - if (typeof event == 'undefined') event = {}; - // check for double click - if (time - parseInt(this.last.click_time) < 250 && event.type == 'click') { - this.dblClick(recid, event); - return; - } - this.last.click_time = time; - // column user clicked on - if (column == null && event.target) { - var tmp = event.target; - if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; - if (typeof $(tmp).attr('col') != 'undefined') column = parseInt($(tmp).attr('col')); - } - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'click', recid: recid, column: column, originalEvent: event }); - if (eventData.isCancelled === true) return; - // if it is subgrid unselect top grid - var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)).parents('tr'); - if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var grid = parent.parents('.w2ui-grid').attr('name'); - w2ui[grid].selectNone(); - // all subgrids - parent.parents('.w2ui-grid').find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { - var grid = $(el).attr('name'); - if (w2ui[grid]) w2ui[grid].selectNone(); - }); - } - // unselect all subgrids - $(this.box).find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { - var grid = $(el).attr('name'); - if (w2ui[grid]) w2ui[grid].selectNone(); - }); - // default action - var obj = this; - var sel = this.getSelection(); - $('#grid_'+ this.name +'_check_all').prop("checked", false); - var ind = this.get(recid, true); - var record = this.records[ind]; - var selectColumns = []; - obj.last.sel_ind = ind; - obj.last.sel_col = column; - obj.last.sel_recid = recid; - obj.last.sel_type = 'click'; - // multi select with shif key - if (event.shiftKey && sel.length > 0 && obj.multiSelect) { - if (sel[0].recid) { - var start = this.get(sel[0].recid, true); - var end = this.get(recid, true); - if (column > sel[0].column) { - var t1 = sel[0].column; - var t2 = column; - } else { - var t1 = column; - var t2 = sel[0].column; - } - for (var c = t1; c <= t2; c++) selectColumns.push(c); - } else { - var start = this.get(sel[0], true); - var end = this.get(recid, true); - } - var sel_add = [] - if (start > end) { var tmp = start; start = end; end = tmp; } - var url = (typeof this.url != 'object' ? this.url : this.url.get); - for (var i = start; i <= end; i++) { - if (this.searchData.length > 0 && !url && $.inArray(i, this.last.searchIds) == -1) continue; - if (this.selectType == 'row') { - sel_add.push(this.records[i].recid); - } else { - for (var sc in selectColumns) sel_add.push({ recid: this.records[i].recid, column: selectColumns[sc] }); - } - //sel.push(this.records[i].recid); - } - this.select.apply(this, sel_add); - } else { - var last = this.last.selection; - var flag = (last.indexes.indexOf(ind) != -1 ? true : false); - // clear other if necessary - if (((!event.ctrlKey && !event.shiftKey && !event.metaKey) || !this.multiSelect) && !this.showSelectColumn) { - if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; - if (sel.length > 300) this.selectNone(); else this.unselect.apply(this, sel); - if (flag === true) { - this.unselect({ recid: recid, column: column }); - } else { - this.select({ recid: recid, column: column }); - } - } else { - if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; - if (flag === true) { - this.unselect({ recid: recid, column: column }); - } else { - this.select({ recid: recid, column: column }); - } - } - } - this.status(); - obj.initResize(); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - columnClick: function (field, event) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'columnClick', target: this.name, field: field, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behaviour - var column = this.getColumn(field); - if (column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false) ); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - keydown: function (event) { - // this method is called from w2utils - var obj = this; - if (obj.keyboard !== true) return; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behavior - var empty = false; - var records = $('#grid_'+ obj.name +'_records'); - var sel = obj.getSelection(); - if (sel.length == 0) empty = true; - var recid = sel[0] || null; - var columns = []; - var recid2 = sel[sel.length-1]; - if (typeof recid == 'object' && recid != null) { - recid = sel[0].recid; - columns = []; - var ii = 0; - while (true) { - if (!sel[ii] || sel[ii].recid != recid) break; - columns.push(sel[ii].column); - ii++; - } - recid2 = sel[sel.length-1].recid; - } - var ind = obj.get(recid, true); - var ind2 = obj.get(recid2, true); - var rec = obj.get(recid); - var recEL = $('#grid_'+ obj.name +'_rec_'+ (ind !== null ? w2utils.escapeId(obj.records[ind].recid) : 'none')); - var cancel = false; - var key = event.keyCode; - var shiftKey= event.shiftKey; - if (key == 9) { // tab key - if (event.shiftKey) key = 37; else key = 39; // replace with arrows - shiftKey = false; - cancel = true; - } - switch (key) { - case 8: // backspace - case 46: // delete - obj.delete(); - cancel = true; - event.stopPropagation(); - break; - - case 27: // escape - obj.selectNone(); - if (sel.length > 0 && typeof sel[0] == 'object') { - obj.select({ recid: sel[0].recid, column: sel[0].column }); - } - cancel = true; - break; - - case 65: // cmd + A - if (!event.metaKey && !event.ctrlKey) break; - obj.selectAll(); - cancel = true; - break; - - case 70: // cmd + F - if (!event.metaKey && !event.ctrlKey) break; - $('#grid_'+ obj.name + '_search_all').focus(); - cancel = true; - break; - - case 13: // enter - // if expandable columns - expand it - if (this.selectType == 'row' && obj.show.expandColumn === true) { - if (recEL.length <= 0) break; - obj.toggle(recid, event); - cancel = true; - } else { // or enter edit - for (var c in this.columns) { - if (this.columns[c].editable) { - columns.push(parseInt(c)); - break; - } - } - // edit last column that was edited - if (this.selectType == 'row' && this.last.edit_col) columns = [this.last.edit_col]; - if (columns.length > 0) { - obj.editField(recid, columns[0], null, event); - cancel = true; - } - } - break; - - case 37: // left - if (empty) break; - // check if this is subgrid - var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind].recid)).parents('tr'); - if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var recid = parent.prev().attr('recid'); - var grid = parent.parents('.w2ui-grid').attr('name'); - obj.selectNone(); - w2utils.keyboard.active(grid); - w2ui[grid].set(recid, { expanded: false }); - w2ui[grid].collapse(recid); - w2ui[grid].click(recid); - cancel = true; - break; - } - if (this.selectType == 'row') { - if (recEL.length <= 0 || rec.expanded !== true ) break; - obj.set(recid, { expanded: false }, true); - obj.collapse(recid, event); - } else { - var prev = obj.prevCell(columns[0]); - if (prev !== false) { - if (shiftKey && obj.multiSelect) { - if (tmpUnselect()) return; - var tmp = []; - var newSel = []; - var unSel = []; - if (columns.indexOf(this.last.sel_col) == 0 && columns.length > 1) { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - unSel.push({ recid: sel[i].recid, column: columns[columns.length-1] }); - } - } else { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - newSel.push({ recid: sel[i].recid, column: prev }); - } - } - obj.unselect.apply(obj, unSel); - obj.select.apply(obj, newSel); - } else { - event.shiftKey = false; - obj.click({ recid: recid, column: prev }, event); - } - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=1; s 1) { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - unSel.push({ recid: sel[i].recid, column: columns[0] }); - } - } else { - for (var i in sel) { - if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); - newSel.push({ recid: sel[i].recid, column: next }); - } - } - obj.unselect.apply(obj, unSel); - obj.select.apply(obj, newSel); - } else { - obj.click({ recid: recid, column: next }, event); - } - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=0; s 0 && w2ui[subgrid.attr('name')]) { - obj.selectNone(); - var grid = subgrid.attr('name'); - var recs = w2ui[grid].records; - w2utils.keyboard.active(grid); - w2ui[grid].click(recs[recs.length-1].recid); - cancel = true; - break; - } - } - if (shiftKey && obj.multiSelect) { // expand selection - if (tmpUnselect()) return; - if (obj.selectType == 'row') { - if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { - obj.unselect(obj.records[ind2].recid); - } else { - obj.select(obj.records[prev].recid); - } - } else { - if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { - prev = ind2; - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); - obj.unselect.apply(obj, tmp); - } else { - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); - obj.select.apply(obj, tmp); - } - } - } else { // move selected record - obj.selectNone(); - obj.click({ recid: obj.records[prev].recid, column: columns[0] }, event); - } - obj.scrollIntoView(prev); - if (event.preventDefault) event.preventDefault(); - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=1; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var recid = parent.prev().attr('recid'); - var grid = parent.parents('.w2ui-grid').attr('name'); - obj.selectNone(); - w2utils.keyboard.active(grid); - w2ui[grid].click(recid); - cancel = true; - break; - } - } - break; - - case 40: // down - if (empty) selectTopRecord(); - if (recEL.length <= 0) break; - // jump into subgrid - if (obj.records[ind2].expanded) { - var subgrid = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind2].recid) +'_expanded_row').find('.w2ui-grid'); - if (subgrid.length > 0 && w2ui[subgrid.attr('name')]) { - obj.selectNone(); - var grid = subgrid.attr('name'); - var recs = w2ui[grid].records; - w2utils.keyboard.active(grid); - w2ui[grid].click(recs[0].recid); - cancel = true; - break; - } - } - // move to the next record - var next = obj.nextRow(ind2); - if (next != null) { - if (shiftKey && obj.multiSelect) { // expand selection - if (tmpUnselect()) return; - if (obj.selectType == 'row') { - if (this.last.sel_ind < next && this.last.sel_ind != ind) { - obj.unselect(obj.records[ind].recid); - } else { - obj.select(obj.records[next].recid); - } - } else { - if (this.last.sel_ind < next && this.last.sel_ind != ind) { - next = ind; - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); - obj.unselect.apply(obj, tmp); - } else { - var tmp = []; - for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); - obj.select.apply(obj, tmp); - } - } - } else { // move selected record - obj.selectNone(); - obj.click({ recid: obj.records[next].recid, column: columns[0] }, event); - } - obj.scrollIntoView(next); - cancel = true; - } else { - // if selected more then one, then select first - if (!shiftKey) { - for (var s=0; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { - var recid = parent.next().attr('recid'); - var grid = parent.parents('.w2ui-grid').attr('name'); - obj.selectNone(); - w2utils.keyboard.active(grid); - w2ui[grid].click(recid); - cancel = true; - break; - } - } - break; - - case 86: // v - paste - if (empty) break; - if (event.ctrlKey || event.metaKey) { - $('body').append(''); - $('#_tmp_copy_data').focus(); - setTimeout(function () { - obj.paste($('#_tmp_copy_data').val()); - $('#_tmp_copy_data').remove(); - }, 50); // need timer to allow paste - } - break; - - case 88: // x - cut - if (empty) break; - if (event.ctrlKey || event.metaKey) { - setTimeout(function () { obj.delete(true); }, 100); - } - case 67: // c - copy - if (empty) break; - if (event.ctrlKey || event.metaKey) { - var text = obj.copy(); - $('body').append(''); - $('#_tmp_copy_data').focus().select(); - setTimeout(function () { $('#_tmp_copy_data').remove(); }, 50); - } - break; - } - var tmp = [187, 189, 32]; // =-spacebar - for (var i=48; i<=90; i++) tmp.push(i); // 0-9,a-z,A-Z - if (tmp.indexOf(key) != -1 && !event.ctrlKey && !event.metaKey && !cancel) { - if (columns.length == 0) columns.push(0); - var tmp = String.fromCharCode(key); - if (key == 187) tmp = '='; - if (key == 189) tmp = '-'; - if (!shiftKey) tmp = tmp.toLowerCase(); - obj.editField(recid, columns[0], tmp, event); - cancel = true; - } - if (cancel) { // cancel default behaviour - if (event.preventDefault) event.preventDefault(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - - function selectTopRecord() { - var ind = Math.floor((records[0].scrollTop + (records.height() / 2.1)) / obj.recordHeight); - if (!obj.records[ind]) ind = 0; - obj.select({ recid: obj.records[ind].recid, column: 0}); - } - - function tmpUnselect () { - if (obj.last.sel_type != 'click') return false; - if (obj.selectType != 'row') { - obj.last.sel_type = 'key'; - if (sel.length > 1) { - for (var s in sel) { - if (sel[s].recid == obj.last.sel_recid && sel[s].column == obj.last.sel_col) { - sel.splice(s, 1); - break; - } - } - obj.unselect.apply(obj, sel); - return true; - } - return false; - } else { - obj.last.sel_type = 'key'; - if (sel.length > 1) { - sel.splice(sel.indexOf(obj.records[obj.last.sel_ind].recid), 1); - obj.unselect.apply(obj, sel); - return true; - } - return false; - } - } - }, - - scrollIntoView: function (ind) { - if (typeof ind == 'undefined') { - var sel = this.getSelection(); - if (sel.length == 0) return; - ind = this.get(sel[0], true); - } - var records = $('#grid_'+ this.name +'_records'); - if (records.length == 0) return; - // if all records in view - var len = this.last.searchIds.length; - if (records.height() > this.recordHeight * (len > 0 ? len : this.records.length)) return; - if (len > 0) ind = this.last.searchIds.indexOf(ind); // if seach is applied - // scroll to correct one - var t1 = Math.floor(records[0].scrollTop / this.recordHeight); - var t2 = t1 + Math.floor(records.height() / this.recordHeight); - if (ind == t1) records.animate({ 'scrollTop': records.scrollTop() - records.height() / 1.3 }, 250, 'linear'); - if (ind == t2) records.animate({ 'scrollTop': records.scrollTop() + records.height() / 1.3 }, 250, 'linear'); - if (ind < t1 || ind > t2) records.animate({ 'scrollTop': (ind - 1) * this.recordHeight }); - }, - - dblClick: function (recid, event) { - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // find columns - var column = null; - if (typeof recid == 'object') { - column = recid.column; - recid = recid.recid; - } - if (typeof event == 'undefined') event = {}; - // column user clicked on - if (column == null && event.target) { - var tmp = event.target; - if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; - column = parseInt($(tmp).attr('col')); - } - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'dblClick', recid: recid, column: column, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - this.selectNone(); - var col = this.columns[column]; - if (col && $.isPlainObject(col.editable)) { - this.editField(recid, column, null, event); - } else { - this.select({ recid: recid, column: column }); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - contextMenu: function (recid, event) { - var obj = this; - if (typeof event.offsetX === 'undefined') { - event.offsetX = event.layerX - event.target.offsetLeft; - event.offsetY = event.layerY - event.target.offsetTop; - } - if (w2utils.isFloat(recid)) recid = parseFloat(recid); - if (this.getSelection().indexOf(recid) == -1) obj.click(recid); - // need timeout to allow click to finish first - setTimeout(function () { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: obj.name, originalEvent: event, recid: recid }); - if (eventData.isCancelled === true) return; - // default action - if (obj.menu.length > 0) { - $(obj.box).find(event.target) - .w2menu(obj.menu, { - left : event.offsetX, - onSelect: function (event) { - obj.menuClick(recid, parseInt(event.index), event.originalEvent); - } - } - ); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 150); // need timer 150 for FF - }, - - menuClick: function (recid, index, event) { - var obj = this; - // event before - var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: obj.name, originalEvent: event, - recid: recid, menuIndex: index, menuItem: obj.menu[index] }); - if (eventData.isCancelled === true) return; - // default action - // -- empty - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - toggle: function (recid) { - var rec = this.get(recid); - if (rec.expanded === true) return this.collapse(recid); else return this.expand(recid); - }, - - expand: function (recid) { - var rec = this.get(recid); - var obj = this; - var id = w2utils.escapeId(recid); - if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length > 0) return false; - if (rec.expanded == 'none') return false; - // insert expand row - var tmp = 1 + (this.show.selectColumn ? 1 : 0); - var addClass = ''; // ($('#grid_'+this.name +'_rec_'+ w2utils.escapeId(recid)).hasClass('w2ui-odd') ? 'w2ui-odd' : 'w2ui-even'); - $('#grid_'+ this.name +'_rec_'+ id).after( - ''+ - (this.show.lineNumbers ? '' : '') + - '
      '+ - ' '+ - '
      '+ - ' '+ - ''); - // event before - var eventData = this.trigger({ phase: 'before', type: 'expand', target: this.name, recid: recid, - box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded', ready: ready }); - if (eventData.isCancelled === true) { - $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove(); - return; - } - // default action - $('#grid_'+ this.name +'_rec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded'); - $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').show(); - $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('
      '); - rec.expanded = true; - // check if height of expanded row > 5 then remove spinner - setTimeout(ready, 300); - function ready() { - var div1 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded'); - var div2 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row .w2ui-expanded1 > div'); - if (div1.height() < 5) return; - div1.css('opacity', 1); - div2.show().css('opacity', 1); - $('#grid_'+ obj.name +'_cell_'+ obj.get(recid, true) +'_expand div').html('-'); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.resizeRecords(); - return true; - }, - - collapse: function (recid) { - var rec = this.get(recid); - var obj = this; - var id = w2utils.escapeId(recid); - if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length == 0) return false; - // event before - var eventData = this.trigger({ phase: 'before', type: 'collapse', target: this.name, recid: recid, - box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded' }); - if (eventData.isCancelled === true) return; - // default action - $('#grid_'+ this.name +'_rec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded'); - $('#grid_'+ this.name +'_rec_'+ id +'_expanded').css('opacity', 0); - $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('+'); - setTimeout(function () { - $('#grid_'+ obj.name +'_rec_'+ id +'_expanded').height('0px'); - setTimeout(function () { - $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row').remove(); - delete rec.expanded; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resizeRecords(); - }, 300); - }, 200); - return true; - }, - - sort: function (field, direction, multiField) { // if no params - clears sort - // event before - var eventData = this.trigger({ phase: 'before', type: 'sort', target: this.name, field: field, direction: direction, multiField: multiField }); - if (eventData.isCancelled === true) return; - // check if needed to quit - if (typeof field != 'undefined') { - // default action - var sortIndex = this.sortData.length; - for (var s in this.sortData) { - if (this.sortData[s].field == field) { sortIndex = s; break; } - } - if (typeof direction == 'undefined' || direction == null) { - if (typeof this.sortData[sortIndex] == 'undefined') { - direction = 'asc'; - } else { - switch (String(this.sortData[sortIndex].direction)) { - case 'asc' : direction = 'desc'; break; - case 'desc' : direction = 'asc'; break; - default : direction = 'asc'; break; - } - } - } - if (this.multiSort === false) { this.sortData = []; sortIndex = 0; } - if (multiField != true) { this.sortData = []; sortIndex = 0; } - // set new sort - if (typeof this.sortData[sortIndex] == 'undefined') this.sortData[sortIndex] = {}; - this.sortData[sortIndex].field = field; - this.sortData[sortIndex].direction = direction; - } else { - this.sortData = []; - } - this.selectNone(); - // if local - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (!url) { - this.localSort(); - if (this.searchData.length > 0) this.localSearch(true); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(); - } else { - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.last.xhr_offset = 0; - this.reload(); - } - }, - - copy: function () { - var sel = this.getSelection(); - if (sel.length == 0) return ''; - var text = ''; - if (typeof sel[0] == 'object') { // cell copy - // find min/max column - var minCol = sel[0].column; - var maxCol = sel[0].column; - var recs = []; - for (var s in sel) { - if (sel[s].column < minCol) minCol = sel[s].column; - if (sel[s].column > maxCol) maxCol = sel[s].column; - if (recs.indexOf(sel[s].index) == -1) recs.push(sel[s].index); - } - recs.sort(); - for (var r in recs) { - var ind = recs[r]; - for (var c = minCol; c <= maxCol; c++) { - var col = this.columns[c]; - if (col.hidden === true) continue; - text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; - } - text = text.substr(0, text.length-1); // remove last \t - text += '\n'; - } - } else { // row copy - for (var s in sel) { - var ind = this.get(sel[s], true); - for (var c in this.columns) { - var col = this.columns[c]; - if (col.hidden === true) continue; - text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; - } - text = text.substr(0, text.length-1); // remove last \t - text += '\n'; - } - } - text = text.substr(0, text.length - 1); - // before event - var eventData = this.trigger({ phase: 'before', type: 'copy', target: this.name, text: text }); - if (eventData.isCancelled === true) return ''; - text = eventData.text; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return text; - }, - - paste: function (text) { - var sel = this.getSelection(); - var ind = this.get(sel[0].recid, true); - var col = sel[0].column; - // before event - var eventData = this.trigger({ phase: 'before', type: 'paste', target: this.name, text: text, index: ind, column: col }); - if (eventData.isCancelled === true) return; - text = eventData.text; - // default action - if (this.selectType == 'row' || sel.length == 0) { - console.log('ERROR: You can paste only if grid.selectType = \'cell\' and when at least one cell selected.'); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return; - } - var newSel = []; - var text = text.split('\n'); - for (var t in text) { - var tmp = text[t].split('\t'); - var cnt = 0; - var rec = this.records[ind]; - var cols = []; - for (var dt in tmp) { - if (!this.columns[col + cnt]) continue; - var field = this.columns[col + cnt].field; - rec.changes = rec.changes || {}; - rec.changes[field] = tmp[dt]; - cols.push(col + cnt); - cnt++; - } - for (var c in cols) newSel.push({ recid: rec.recid, column: cols[c] }); - ind++; - } - this.selectNone(); - this.select.apply(this, newSel); - this.refresh(); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - // ================================================== - // --- Common functions - - resize: function () { - var obj = this; - var time = (new Date()).getTime(); - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // make sure the box is right - if (!this.box || $(this.box).attr('name') != this.name) return; - // determine new width and height - $(this.box).find('> div') - .css('width', $(this.box).width()) - .css('height', $(this.box).height()); - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; - // resize - obj.resizeBoxes(); - obj.resizeRecords(); - // init editable - // $('#grid_'+ obj.name + '_records .w2ui-editable input').each(function (index, el) { - // var column = obj.columns[$(el).attr('column')]; - // if (column && column.editable) $(el).w2field(column.editable); - // }); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - refreshCell: function (recid, field) { - var index = this.get(recid, true); - var col_ind = this.getColumn(field, true); - var rec = this.records[index]; - var col = this.columns[col_ind]; - var cell = $('#grid_'+ this.name + '_rec_'+ recid +' [col='+ col_ind +']'); - // set cell html and changed flag - cell.html(this.getCellHTML(index, col_ind)); - if (rec.changes && typeof rec.changes[col.field] != 'undefined') { - cell.addClass('w2ui-changed'); - } else { - cell.removeClass('w2ui-changed'); - } - }, - - refreshRow: function (recid) { - var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); - if (tr.length != 0) { - var ind = this.get(recid, true); - var line = tr.attr('line'); - // if it is searched, find index in search array - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (this.searchData.length > 0 && !url) for (var s in this.last.searchIds) if (this.last.searchIds[s] == ind) ind = s; - $(tr).replaceWith(this.getRecordHTML(ind, line)); - } - - }, - - refresh: function () { - var obj = this; - var time = (new Date()).getTime(); - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (this.total <= 0 && !url && this.searchData.length == 0) { - this.total = this.records.length; - this.buffered = this.total; - } - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - this.toolbar.disable('w2ui-edit', 'w2ui-delete'); - if (!this.box) return; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'refresh' }); - if (eventData.isCancelled === true) return; - // -- header - if (this.show.header) { - $('#grid_'+ this.name +'_header').html(this.header +' ').show(); - } else { - $('#grid_'+ this.name +'_header').hide(); - } - // -- toolbar - if (this.show.toolbar) { - // if select-collumn is checked - no toolbar refresh - if (this.toolbar && this.toolbar.get('w2ui-column-on-off') && this.toolbar.get('w2ui-column-on-off').checked) { - // no action - } else { - $('#grid_'+ this.name +'_toolbar').show(); - // refresh toolbar all but search field - if (typeof this.toolbar == 'object') { - var tmp = this.toolbar.items; - for (var t in tmp) { - if (tmp[t].id == 'w2ui-search' || tmp[t].type == 'break') continue; - this.toolbar.refresh(tmp[t].id); - } - } - } - } else { - $('#grid_'+ this.name +'_toolbar').hide(); - } - // -- make sure search is closed - this.searchClose(); - // search placeholder - var el = $('#grid_'+ obj.name +'_search_all'); - if (!this.multiSearch && this.last.field == 'all' && this.searches.length > 0) { - this.last.field = this.searches[0].field; - this.last.caption = this.searches[0].caption; - } - for (var s in this.searches) { - if (this.searches[s].field == this.last.field) this.last.caption = this.searches[s].caption; - } - if (this.last.multi) { - el.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']'); - } else { - el.attr('placeholder', this.last.caption); - } - if (el.val() != this.last.search) { - var val = this.last.search; - var tmp = el.data('w2field'); - if (tmp) val = tmp.format(val); - el.val(val); - } - - // -- separate summary - var tmp = this.find({ summary: true }, true); - if (tmp.length > 0) { - for (var t in tmp) this.summary.push(this.records[tmp[t]]); - for (var t=tmp.length-1; t>=0; t--) this.records.splice(tmp[t], 1); - this.total = this.total - tmp.length; - this.buffered = this.buffered - tmp.length; - } - - // -- body - var bodyHTML = ''; - bodyHTML += '
      '+ - this.getRecordsHTML() + - '
      '+ - '
      '+ - ' '+ this.getColumnsHTML() +'
      '+ - '
      '; // Columns need to be after to be able to overlap - $('#grid_'+ this.name +'_body').html(bodyHTML); - // show summary records - if (this.summary.length > 0) { - $('#grid_'+ this.name +'_summary').html(this.getSummaryHTML()).show(); - } else { - $('#grid_'+ this.name +'_summary').hide(); - } - // -- footer - if (this.show.footer) { - $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()).show(); - } else { - $('#grid_'+ this.name +'_footer').hide(); - } - // show/hide clear search link - if (this.searchData.length > 0) { - $('#grid_'+ this.name +'_searchClear').show(); - } else { - $('#grid_'+ this.name +'_searchClear').hide(); - } - // all selected? - var sel = this.last.selection; - if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { - $('#grid_'+ this.name +'_check_all').prop('checked', true); - } else { - $('#grid_'+ this.name +'_check_all').prop('checked', false); - } - // show number of selected - this.status(); - // collapse all records - var rows = obj.find({ expanded: true }, true); - for (var r in rows) obj.records[rows[r]].expanded = false; - // mark selection - setTimeout(function () { - var str = $.trim($('#grid_'+ obj.name +'_search_all').val()); - if (str != '') $(obj.box).find('.w2ui-grid-data > div').w2marker(str); - }, 50); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - obj.addRange('selection'); - setTimeout(function () { obj.resize(); obj.scroll(); }, 1); // allow to render first - - if ( obj.reorderColumns && !obj.last.columnDrag ) { - obj.last.columnDrag = obj.initColumnDrag(); - } else if ( !obj.reorderColumns && obj.last.columnDrag ) { - obj.last.columnDrag.remove(); - } - - return (new Date()).getTime() - time; - }, - - render: function (box) { - var obj = this; - var time = (new Date()).getTime(); - //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (typeof box != 'undefined' && box != null) { - if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-grid') - .html(''); - } - this.box = box; - } - if (!this.box) return; - if (this.last.sortData == null) this.last.sortData = this.sortData; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'render', box: box }); - if (eventData.isCancelled === true) return; - // insert Elements - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-grid') - .html('
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - ' '+ - '
      '); - if (this.selectType != 'row') $(this.box).addClass('w2ui-ss'); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // init toolbar - this.initToolbar(); - if (this.toolbar != null) this.toolbar.render($('#grid_'+ this.name +'_toolbar')[0]); - // reinit search_all - if (this.last.field && this.last.field != 'all') { - var sd = this.searchData; - this.initAllField(this.last.field, (sd.length == 1 ? sd[0].value : null)); - } - // init footer - $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()); - // refresh - if (this.url) this.refresh(); // show empty grid (need it) - should it be only for remote data source - this.reload(); - - // init mouse events for mouse selection - $(this.box).on('mousedown', mouseStart); - $(this.box).on('selectstart', function () { return false; }); // fixes chrome cursor bug - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - // attach to resize event - if ($('.w2ui-layout').length == 0) { // if there is layout, it will send a resize event - this.tmp_resize = function (event) { w2ui[obj.name].resize(); } - $(window).off('resize', this.tmp_resize).on('resize', this.tmp_resize); - } - return (new Date()).getTime() - time; - - function mouseStart (event) { - if ($(event.target).parents().hasClass('w2ui-head') || $(event.target).hasClass('w2ui-head')) return; - if (obj.last.move && obj.last.move.type == 'expand') return; - if (!obj.multiSelect) return; - obj.last.move = { - x : event.screenX, - y : event.screenY, - divX : 0, - divY : 0, - recid : $(event.target).parents('tr').attr('recid'), - column : (event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')), - type : 'select', - ghost : false, - start : true - }; - $(document).on('mousemove', mouseMove); - $(document).on('mouseup', mouseStop); - } - - function mouseMove (event) { - var mv = obj.last.move; - if (!mv || mv.type != 'select') return; - mv.divX = (event.screenX - mv.x); - mv.divY = (event.screenY - mv.y); - if (Math.abs(mv.divX) <= 1 && Math.abs(mv.divY) <= 1) return; // only if moved more then 1px - obj.last.cancelClick = true; - if (obj.reorderRows == true) { - if (!mv.ghost) { - var row = $('#grid_'+ obj.name + '_rec_'+ mv.recid); - var tmp = row.parents('table').find('tr:first-child').clone(); - mv.offsetY = event.offsetY; - mv.from = mv.recid; - mv.pos = row.position(); - mv.ghost = $(row).clone(true); - mv.ghost.removeAttr('id'); - row.find('td:first-child').replaceWith(''); - var recs = $(obj.box).find('.w2ui-grid-records'); - recs.append('
      '); - $('#grid_'+ obj.name + '_ghost').append(tmp).append(mv.ghost); - } - var recid = $(event.target).parents('tr').attr('recid'); - if (recid != mv.from) { - var row1 = $('#grid_'+ obj.name + '_rec_'+ mv.recid); - var row2 = $('#grid_'+ obj.name + '_rec_'+ recid); - if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); - mv.lastY = event.screenY; - mv.to = recid; - } - var ghost = $('#grid_'+ obj.name + '_ghost'); - var recs = $(obj.box).find('.w2ui-grid-records'); - ghost.css({ - top : mv.pos.top + mv.divY + recs.scrollTop(), // + mv.offsetY - obj.recordHeight / 2, - left : mv.pos.left - }); - return; - } - if (mv.start && mv.recid) { - obj.selectNone(); - mv.start = false; - } - var newSel= []; - var recid = (event.target.tagName == 'TR' ? $(event.target).attr('recid') : $(event.target).parents('tr').attr('recid')); - if (typeof recid == 'undefined') return; - var ind1 = obj.get(mv.recid, true); - // |:wolfmanx:| this happens when selection is started on summary row - if (ind1 === null) return; - var ind2 = obj.get(recid, true); - // this happens when selection is extended into summary row (a good place to implement scrolling) - if (ind2 === null) return; - var col1 = parseInt(mv.column); - var col2 = parseInt(event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')); - if (ind1 > ind2) { var tmp = ind1; ind1 = ind2; ind2 = tmp; } - // check if need to refresh - var tmp = 'ind1:'+ ind1 +',ind2;'+ ind2 +',col1:'+ col1 +',col2:'+ col2; - if (mv.range == tmp) return; - mv.range = tmp; - for (var i = ind1; i <= ind2; i++) { - if (obj.last.searchIds.length > 0 && obj.last.searchIds.indexOf(i) == -1) continue; - if (obj.selectType != 'row') { - if (col1 > col2) { var tmp = col1; col1 = col2; col2 = tmp; } - var tmp = []; - for (var c = col1; c <= col2; c++) { - if (obj.columns[c].hidden) continue; - newSel.push({ recid: obj.records[i].recid, column: parseInt(c) }); - } - } else { - newSel.push(obj.records[i].recid); - } - } - if (obj.selectType != 'row') { - var sel = obj.getSelection(); - // add more items - var tmp = []; - for (var ns in newSel) { - var flag = false; - for (var s in sel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; - if (!flag) tmp.push({ recid: newSel[ns].recid, column: newSel[ns].column }); - } - obj.select.apply(obj, tmp); - // remove items - var tmp = []; - for (var s in sel) { - var flag = false; - for (var ns in newSel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; - if (!flag) tmp.push({ recid: sel[s].recid, column: sel[s].column }); - } - obj.unselect.apply(obj, tmp); - } else { - if (obj.multiSelect) { - var sel = obj.getSelection(); - for (var ns in newSel) if (sel.indexOf(newSel[ns]) == -1) obj.select(newSel[ns]); // add more items - for (var s in sel) if (newSel.indexOf(sel[s]) == -1) obj.unselect(sel[s]); // remove items - } - } - } - - function mouseStop (event) { - var mv = obj.last.move; - setTimeout(function () { delete obj.last.cancelClick; }, 1); - if ($(event.target).parents().hasClass('.w2ui-head') || $(event.target).hasClass('.w2ui-head')) return; - if (!mv || mv.type != 'select') return; - if (obj.reorderRows == true) { - var ind1 = obj.get(mv.from, true); - var tmp = obj.records[ind1]; - obj.records.splice(ind1, 1); - var ind2 = obj.get(mv.to, true); - if (ind1 > ind2) obj.records.splice(ind2, 0, tmp); else obj.records.splice(ind2+1, 0, tmp); - $('#grid_'+ obj.name + '_ghost').remove(); - obj.refresh(); - } - delete obj.last.move; - $(document).off('mousemove', mouseMove); - $(document).off('mouseup', mouseStop); - } - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'destroy' }); - if (eventData.isCancelled === true) return; - // remove events - $(window).off('resize', this.tmp_resize); - // clean up - if (typeof this.toolbar == 'object' && this.toolbar.destroy) this.toolbar.destroy(); - if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-grid') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - // =========================================== - // --- Internal Functions - - initColumnOnOff: function () { - if (!this.show.toolbarColumns) return; - var obj = this; - var col_html = '
      '+ - ''; - for (var c in this.columns) { - var col = this.columns[c]; - var tmp = this.columns[c].caption; - if (!tmp && this.columns[c].hint) tmp = this.columns[c].hint; - if (!tmp) tmp = '- column '+ (parseInt(c) + 1) +' -'; - col_html += ''+ - ''+ - ''+ - ''; - } - col_html += ''; - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (url) { - col_html += - ''; - } - col_html += ''+ - ''; - col_html += "
      '+ - ' '+ - ''+ - ' '+ - '
      '+ - '
      '+ w2utils.lang('Skip') + - ' '+ w2utils.lang('Records')+ - '
      '+ - '
      '+ - '
      '+ w2utils.lang('Toggle Line Numbers') +'
      '+ - '
      '+ - '
      '+ w2utils.lang('Reset Column Size') + '
      '+ - '
      "; - this.toolbar.get('w2ui-column-on-off').html = col_html; - }, - - /** - * - * @param box, grid object - * @returns {{remove: Function}} contains a closure around all events to ensure they are removed from the dom - */ - initColumnDrag: function( box ){ - //throw error if using column groups - if ( this.columnGroups && this.columnGroups.length ) throw 'Draggable columns are not currently supported with column groups.'; - - var obj = this, - _dragData = {}; - _dragData.lastInt = null; - _dragData.pressed = false; - _dragData.timeout = null;_dragData.columnHead = null; - - //attach orginal event listener - $( obj.box).on( 'mousedown', dragColStart ); - $( obj.box ).on( 'mouseup', catchMouseup ); - - function catchMouseup(){ - _dragData.pressed = false; - clearTimeout( _dragData.timeout ); - } - /** - * - * @param event, mousedown - * @returns {boolean} false, preventsDefault - */ - function dragColStart ( event ) { - if ( _dragData.timeout ) clearTimeout( _dragData.timeout ); - var self = this; - _dragData.pressed = true; - - _dragData.timeout = setTimeout(function(){ - if ( !_dragData.pressed ) return; - - var eventData, - columns, - selectedCol, - origColumn, - origColumnNumber, - invalidPreColumns = [ 'w2ui-col-number', 'w2ui-col-expand', 'w2ui-col-select' ], - invalidPostColumns = [ 'w2ui-head-last' ], - invalidColumns = invalidPreColumns.concat( invalidPostColumns ), - preColumnsSelector = '.w2ui-col-number, .w2ui-col-expand, .w2ui-col-select', - preColHeadersSelector = '.w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select'; - - // do nothing if it is not a header - if ( !$( event.originalEvent.target ).parents().hasClass( 'w2ui-head' ) ) return; - - // do nothing if it is an invalid column - for ( var i = 0, l = invalidColumns.length; i < l; i++ ){ - if ( $( event.originalEvent.target ).parents().hasClass( invalidColumns[ i ] ) ) return; - } - - _dragData.numberPreColumnsPresent = $( obj.box ).find( preColHeadersSelector ).length; - - //start event for drag start - _dragData.columnHead = origColumn = $( event.originalEvent.target ).parents( '.w2ui-head' ); - origColumnNumber = parseInt( origColumn.attr( 'col' ), 10); - eventData = obj.trigger({ type: 'columnDragStart', phase: 'before', originalEvent: event, origColumnNumber: origColumnNumber, target: origColumn[0] }); - if ( eventData.isCancelled === true ) return false; - - columns = _dragData.columns = $( obj.box ).find( '.w2ui-head:not(.w2ui-head-last)' ); - - //add events - $( document ).on( 'mouseup', dragColEnd ); - $( document ).on( 'mousemove', dragColOver ); - - _dragData.originalPos = parseInt( $( event.originalEvent.target ).parent( '.w2ui-head' ).attr( 'col' ), 10 ); - //_dragData.columns.css({ overflow: 'visible' }).children( 'div' ).css({ overflow: 'visible' }); - - //configure and style ghost image - _dragData.ghost = $( self ).clone( true ); - - //hide other elements on ghost except the grid body - $( _dragData.ghost ).find( '[col]:not([col="' + _dragData.originalPos + '"]), .w2ui-toolbar, .w2ui-grid-header' ).remove(); - $( _dragData.ghost ).find( preColumnsSelector ).remove(); - $( _dragData.ghost ).find( '.w2ui-grid-body' ).css({ top: 0 }); - - selectedCol = $( _dragData.ghost ).find( '[col="' + _dragData.originalPos + '"]' ); - $( document.body ).append( _dragData.ghost ); - - $( _dragData.ghost ).css({ - width: 0, - height: 0, - margin: 0, - position: 'fixed', - zIndex: 999999, - opacity: 0 - }).addClass( '.w2ui-grid-ghost' ).animate({ - width: selectedCol.width(), - height: $(obj.box).find('.w2ui-grid-body:first').height(), - left : event.pageX, - top : event.pageY, - opacity: .8 - }, 0 ); - - //establish current offsets - _dragData.offsets = []; - for ( var i = 0, l = columns.length; i < l; i++ ) { - _dragData.offsets.push( $( columns[ i ] ).offset().left ); - } - - //conclude event - obj.trigger( $.extend( eventData, { phase: 'after' } ) ); - }, 150 );//end timeout wrapper - } - - function dragColOver ( event ) { - if ( !_dragData.pressed ) return; - - var cursorX = event.originalEvent.pageX, - cursorY = event.originalEvent.pageY, - offsets = _dragData.offsets, - lastWidth = $( '.w2ui-head:not(.w2ui-head-last)' ).width(); - - _dragData.targetInt = targetIntersection( cursorX, offsets, lastWidth ); - markIntersection( _dragData.targetInt ); - trackGhost( cursorX, cursorY ); - } - - function dragColEnd ( event ) { - _dragData.pressed = false; - - var eventData, - target, - selected, - columnConfig, - columnNum, - targetColumn, - ghosts = $( '.w2ui-grid-ghost' ); - - //start event for drag start - eventData = obj.trigger({ type: 'columnDragEnd', phase: 'before', originalEvent: event, target: _dragData.columnHead[0] }); - if ( eventData.isCancelled === true ) return false; - - selected = obj.columns[ _dragData.originalPos ]; - columnConfig = obj.columns; - columnNum = ( _dragData.targetInt >= obj.columns.length ) ? obj.columns.length - 1 : - ( _dragData.targetInt < _dragData.originalPos ) ? _dragData.targetInt : _dragData.targetInt - 1; - target = ( _dragData.numberPreColumnsPresent ) ? - ( _dragData.targetInt - _dragData.numberPreColumnsPresent < 0 ) ? 0 : _dragData.targetInt - _dragData.numberPreColumnsPresent : - _dragData.targetInt; - targetColumn = $( '.w2ui-head[col="' + columnNum + '"]' ); - - if ( target !== _dragData.originalPos + 1 && target !== _dragData.originalPos && targetColumn && targetColumn.length ) { - $( _dragData.ghost ).animate({ - top: $( obj.box ).offset().top, - left: targetColumn.offset().left, - width: 0, - height: 0, - opacity:.2 - }, 300, function(){ - $( this ).remove(); - ghosts.remove(); - }); - - columnConfig.splice( target, 0, $.extend( {}, selected ) ); - columnConfig.splice( columnConfig.indexOf( selected ), 1); - } else { - $( _dragData.ghost ).remove(); - ghosts.remove(); - } - - //_dragData.columns.css({ overflow: '' }).children( 'div' ).css({ overflow: '' }); - - $( document ).off( 'mouseup', dragColEnd ); - $( document ).off( 'mousemove', dragColOver ); - if ( _dragData.marker ) _dragData.marker.remove(); - _dragData = {}; - - obj.refresh(); - - //conclude event - obj.trigger( $.extend( eventData, { phase: 'after', targetColumnNumber: target - 1 } ) ); - } - - function markIntersection( intersection ){ - if ( !_dragData.marker && !_dragData.markerLeft ) { - _dragData.marker = $('
      ' + - '
      ' + - '
      ' + - '
      '); - _dragData.markerLeft = $('
      ' + - '
      ' + - '
      ' + - '
      '); - } - - if ( !_dragData.lastInt || _dragData.lastInt !== intersection ){ - _dragData.lastInt = intersection; - _dragData.marker.remove(); - _dragData.markerLeft.remove(); - $('.w2ui-head').removeClass('w2ui-col-intersection'); - - //if the current intersection is greater than the number of columns add the marker to the end of the last column only - if ( intersection >= _dragData.columns.length ) { - $( _dragData.columns[ _dragData.columns.length - 1 ] ).children( 'div:last' ).append( _dragData.marker.addClass( 'right' ).removeClass( 'left' ) ); - $( _dragData.columns[ _dragData.columns.length - 1 ] ).addClass('w2ui-col-intersection'); - } else if ( intersection <= _dragData.numberPreColumnsPresent ) { - //if the current intersection is on the column numbers place marker on first available column only - $( '.w2ui-head[col="0"]' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ).css({ position: 'relative' }); - $( '.w2ui-head[col="0"]').prev().addClass('w2ui-col-intersection'); - } else { - //otherwise prepend the marker to the targeted column and append it to the previous column - $( _dragData.columns[intersection] ).children( 'div:last' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ); - $( _dragData.columns[intersection] ).prev().children( 'div:last' ).append( _dragData.markerLeft.addClass( 'right' ).removeClass( 'left' ) ).css({ position: 'relative' }); - $( _dragData.columns[intersection - 1] ).addClass('w2ui-col-intersection'); - } - } - } - - function targetIntersection( cursorX, offsets, lastWidth ){ - if ( cursorX <= offsets[0] ) { - return 0; - } else if ( cursorX >= offsets[offsets.length - 1] + lastWidth ) { - return offsets.length; - } else { - for ( var i = 0, l = offsets.length; i < l; i++ ) { - var thisOffset = offsets[ i ]; - var nextOffset = offsets[ i + 1 ] || offsets[ i ] + lastWidth; - var midpoint = ( nextOffset - offsets[ i ]) / 2 + offsets[ i ]; - - if ( cursorX > thisOffset && cursorX <= midpoint ) { - return i; - } else if ( cursorX > midpoint && cursorX <= nextOffset ) { - return i + 1; - } - } - return intersection; - } - } - - function trackGhost( cursorX, cursorY ){ - $( _dragData.ghost ).css({ - left: cursorX - 10, - top: cursorY - 10 - }); - } - - //return an object to remove drag if it has ever been enabled - return { - remove: function(){ - $( obj.box ).off( 'mousedown', dragColStart ); - $( obj.box ).off( 'mouseup', catchMouseup ); - $( obj.box ).find( '.w2ui-head' ).removeAttr( 'draggable' ); - obj.last.columnDrag = false; - } - } - }, - - columnOnOff: function (el, event, field, value) { - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'columnOnOff', checkbox: el, field: field, originalEvent: event }); - if (eventData.isCancelled === true) return; - // regular processing - var obj = this; - // collapse expanded rows - for (var r in this.records) { - if (this.records[r].expanded === true) this.records[r].expanded = false - } - // show/hide - var hide = true; - if (field == 'line-numbers') { - this.show.lineNumbers = !this.show.lineNumbers; - this.refresh(); - } else if (field == 'skip') { - if (!w2utils.isInt(value)) value = 0; - obj.skip(value); - } else if (field == 'resize') { - // restore sizes - for (var c in this.columns) { - if (typeof this.columns[c].sizeOriginal != 'undefined') { - this.columns[c].size = this.columns[c].sizeOriginal; - } - } - this.initResize(); - this.resize(); - } else { - var col = this.getColumn(field); - if (col.hidden) { - $(el).prop('checked', true); - this.showColumn(col.field); - } else { - $(el).prop('checked', false); - this.hideColumn(col.field); - } - hide = false; - } - this.initColumnOnOff(); - if (hide) { - setTimeout(function () { - $().w2overlay('', { name: 'searches-'+ this.name }); - obj.toolbar.uncheck('column-on-off'); - }, 100); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - initToolbar: function () { - // -- if toolbar is true - if (typeof this.toolbar['render'] == 'undefined') { - var tmp_items = this.toolbar.items; - this.toolbar.items = []; - this.toolbar = $().w2toolbar($.extend(true, {}, this.toolbar, { name: this.name +'_toolbar', owner: this })); - - // ============================================= - // ------ Toolbar Generic buttons - - if (this.show.toolbarReload) { - this.toolbar.items.push($.extend(true, {}, this.buttons['reload'])); - } - if (this.show.toolbarColumns) { - this.toolbar.items.push($.extend(true, {}, this.buttons['columns'])); - this.initColumnOnOff(); - } - if (this.show.toolbarReload || this.show.toolbarColumn) { - this.toolbar.items.push({ type: 'break', id: 'w2ui-break0' }); - } - if (this.show.toolbarSearch) { - var html = - ''; - this.toolbar.items.push({ type: 'html', id: 'w2ui-search', html: html }); - if (this.multiSearch && this.searches.length > 0) { - this.toolbar.items.push($.extend(true, {}, this.buttons['search-go'])); - } - } - if (this.show.toolbarSearch && (this.show.toolbarAdd || this.show.toolbarEdit || this.show.toolbarDelete || this.show.toolbarSave)) { - this.toolbar.items.push({ type: 'break', id: 'w2ui-break1' }); - } - if (this.show.toolbarAdd) { - this.toolbar.items.push($.extend(true, {}, this.buttons['add'])); - } - if (this.show.toolbarEdit) { - this.toolbar.items.push($.extend(true, {}, this.buttons['edit'])); - } - if (this.show.toolbarDelete) { - this.toolbar.items.push($.extend(true, {}, this.buttons['delete'])); - } - if (this.show.toolbarSave) { - if (this.show.toolbarAdd || this.show.toolbarDelete || this.show.toolbarEdit) { - this.toolbar.items.push({ type: 'break', id: 'w2ui-break2' }); - } - this.toolbar.items.push($.extend(true, {}, this.buttons['save'])); - } - // add original buttons - for (var i in tmp_items) this.toolbar.items.push(tmp_items[i]); - - // ============================================= - // ------ Toolbar onClick processing - - var obj = this; - this.toolbar.on('click', function (event) { - var eventData = obj.trigger({ phase: 'before', type: 'toolbar', target: event.target, originalEvent: event }); - if (eventData.isCancelled === true) return; - var id = event.target; - switch (id) { - case 'w2ui-reload': - var eventData2 = obj.trigger({ phase: 'before', type: 'reload', target: obj.name }); - if (eventData2.isCancelled === true) return false; - obj.reload(); - obj.trigger($.extend(eventData2, { phase: 'after' })); - break; - case 'w2ui-column-on-off': - for (var c in obj.columns) { - if (obj.columns[c].hidden) { - $("#grid_"+ obj.name +"_column_"+ c + "_check").prop("checked", false); - } else { - $("#grid_"+ obj.name +"_column_"+ c + "_check").prop('checked', true); - } - } - obj.initResize(); - obj.resize(); - break; - case 'w2ui-search-advanced': - var tb = this; - var it = this.get(id); - if (it.checked) { - obj.searchClose(); - setTimeout(function () { tb.uncheck(id); }, 1); - } else { - obj.searchOpen(); - event.originalEvent.stopPropagation(); - function tmp_close() { - if ($('#w2ui-overlay-searches-'+ obj.name).data('keepOpen') === true) return; - tb.uncheck(id); - $(document).off('click', 'body', tmp_close); - } - $(document).on('click', 'body', tmp_close); - } - break; - case 'w2ui-add': - // events - var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'add', recid: null }); - obj.trigger($.extend(eventData, { phase: 'after' })); - break; - case 'w2ui-edit': - var sel = obj.getSelection(); - var recid = null; - if (sel.length == 1) recid = sel[0]; - // events - var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'edit', recid: recid }); - obj.trigger($.extend(eventData, { phase: 'after' })); - break; - case 'w2ui-delete': - obj.delete(); - break; - case 'w2ui-save': - obj.save(); - break; - } - // no default action - obj.trigger($.extend(eventData, { phase: 'after' })); - }); - } - return; - }, - - initResize: function () { - var obj = this; - //if (obj.resizing === true) return; - $(this.box).find('.w2ui-resizer') - .off('click') - .on('click', function (event) { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - if (event.preventDefault) event.preventDefault(); - }) - .off('mousedown') - .on('mousedown', function (event) { - if (!event) event = window.event; - if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } - obj.resizing = true; - obj.last.tmp = { - x : event.screenX, - y : event.screenY, - gx : event.screenX, - gy : event.screenY, - col : parseInt($(this).attr('name')) - }; - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - if (event.preventDefault) event.preventDefault(); - // fix sizes - for (var c in obj.columns) { - if (typeof obj.columns[c].sizeOriginal == 'undefined') obj.columns[c].sizeOriginal = obj.columns[c].size; - obj.columns[c].size = obj.columns[c].sizeCalculated; - } - var eventData = { phase: 'before', type: 'columnResize', target: obj.name, column: obj.last.tmp.col, field: obj.columns[obj.last.tmp.col].field }; - eventData = obj.trigger($.extend(eventData, { resizeBy: 0, originalEvent: event })); - // set move event - var mouseMove = function (event) { - if (obj.resizing != true) return; - if (!event) event = window.event; - // event before - eventData = obj.trigger($.extend(eventData, { resizeBy: (event.screenX - obj.last.tmp.gx), originalEvent: event })); - if (eventData.isCancelled === true) { eventData.isCancelled = false; return; } - // default action - obj.last.tmp.x = (event.screenX - obj.last.tmp.x); - obj.last.tmp.y = (event.screenY - obj.last.tmp.y); - obj.columns[obj.last.tmp.col].size = (parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px'; - obj.resizeRecords(); - // reset - obj.last.tmp.x = event.screenX; - obj.last.tmp.y = event.screenY; - } - var mouseUp = function (event) { - delete obj.resizing; - $(document).off('mousemove', 'body'); - $(document).off('mouseup', 'body'); - obj.resizeRecords(); - // event before - obj.trigger($.extend(eventData, { phase: 'after', originalEvent: event })); - } - $(document).on('mousemove', 'body', mouseMove); - $(document).on('mouseup', 'body', mouseUp); - }) - .each(function (index, el) { - var td = $(el).parent(); - $(el).css({ - "height" : '25px', - "margin-left" : (td.width() - 3) + 'px' - }) - }); - }, - - resizeBoxes: function () { - // elements - var main = $(this.box).find('> div'); - var header = $('#grid_'+ this.name +'_header'); - var toolbar = $('#grid_'+ this.name +'_toolbar'); - var summary = $('#grid_'+ this.name +'_summary'); - var footer = $('#grid_'+ this.name +'_footer'); - var body = $('#grid_'+ this.name +'_body'); - var columns = $('#grid_'+ this.name +'_columns'); - var records = $('#grid_'+ this.name +'_records'); - - if (this.show.header) { - header.css({ - top: '0px', - left: '0px', - right: '0px' - }); - } - - if (this.show.toolbar) { - toolbar.css({ - top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) ) + 'px', - left: '0px', - right: '0px' - }); - } - if (this.show.footer) { - footer.css({ - bottom: '0px', - left: '0px', - right: '0px' - }); - } - if (this.summary.length > 0) { - summary.css({ - bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) ) + 'px', - left: '0px', - right: '0px' - }); - } - body.css({ - top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) ) + 'px', - bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + (this.summary.length > 0 ? w2utils.getSize(summary, 'height') : 0) ) + 'px', - left: '0px', - right: '0px' - }); - }, - - resizeRecords: function () { - var obj = this; - // remove empty records - $(this.box).find('.w2ui-empty-record').remove(); - // -- Calculate Column size in PX - var box = $(this.box); - var grid = $(this.box).find('> div'); - var header = $('#grid_'+ this.name +'_header'); - var toolbar = $('#grid_'+ this.name +'_toolbar'); - var summary = $('#grid_'+ this.name +'_summary'); - var footer = $('#grid_'+ this.name +'_footer'); - var body = $('#grid_'+ this.name +'_body'); - var columns = $('#grid_'+ this.name +'_columns'); - var records = $('#grid_'+ this.name +'_records'); - - // body might be expanded by data - if (!this.fixedBody) { - // allow it to render records, then resize - var calculatedHeight = w2utils.getSize(columns, 'height') - + w2utils.getSize($('#grid_'+ obj.name +'_records table'), 'height'); - obj.height = calculatedHeight - + w2utils.getSize(grid, '+height') - + (obj.show.header ? w2utils.getSize(header, 'height') : 0) - + (obj.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) - + (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) - + (obj.show.footer ? w2utils.getSize(footer, 'height') : 0); - grid.css('height', obj.height); - body.css('height', calculatedHeight); - box.css('height', w2utils.getSize(grid, 'height') + w2utils.getSize(box, '+height')); - } else { - // fixed body height - var calculatedHeight = grid.height() - - (this.show.header ? w2utils.getSize(header, 'height') : 0) - - (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) - - (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) - - (this.show.footer ? w2utils.getSize(footer, 'height') : 0); - body.css('height', calculatedHeight); - } - - // check overflow - var bodyOverflowX = false; - var bodyOverflowY = false; - if (body.width() < $(records).find('>table').width()) bodyOverflowX = true; - if (body.height() - columns.height() < $(records).find('>table').height() + (bodyOverflowX ? w2utils.scrollBarSize() : 0)) bodyOverflowY = true; - if (!this.fixedBody) { bodyOverflowY = false; bodyOverflowX = false; } - if (bodyOverflowX || bodyOverflowY) { - columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); - records.css({ - top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', - "-webkit-overflow-scrolling": "touch", - "overflow-x": (bodyOverflowX ? 'auto' : 'hidden'), - "overflow-y": (bodyOverflowY ? 'auto' : 'hidden') }); - } else { - columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').hide(); - records.css({ - top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', - overflow: 'hidden' - }); - if (records.length > 0) { this.last.scrollTop = 0; this.last.scrollLeft = 0; } // if no scrollbars, always show top - } - if (this.show.emptyRecords && !bodyOverflowY) { - var max = Math.floor(records.height() / this.recordHeight) + 1; - if (this.fixedBody) { - for (var di = this.buffered; di <= max; di++) { - var html = ''; - html += ''; - if (this.show.lineNumbers) html += ''; - if (this.show.selectColumn) html += ''; - if (this.show.expandColumn) html += ''; - var j = 0; - while (true && this.columns.length > 0) { - var col = this.columns[j]; - if (col.hidden) { j++; if (typeof this.columns[j] == 'undefined') break; else continue; } - html += ''; - j++; - if (typeof this.columns[j] == 'undefined') break; - } - html += ''; - html += ''; - $('#grid_'+ this.name +'_records > table').append(html); - } - } - } - if (body.length > 0) { - var width_max = parseInt(body.width()) - - (bodyOverflowY ? w2utils.scrollBarSize() : 0) - - (this.show.lineNumbers ? 34 : 0) - - (this.show.selectColumn ? 26 : 0) - - (this.show.expandColumn ? 26 : 0); - var width_box = width_max; - var percent = 0; - // gridMinWidth processiong - var restart = false; - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (typeof col.gridMinWidth != 'undefined') { - if (col.gridMinWidth > width_box && col.hidden !== true) { - col.hidden = true; - restart = true; - } - if (col.gridMinWidth < width_box && col.hidden === true) { - col.hidden = false; - restart = true; - } - } - } - if (restart === true) { - this.refresh(); - return; - } - // assign PX column s - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (String(col.size).substr(String(col.size).length-2).toLowerCase() == 'px') { - width_max -= parseFloat(col.size); - this.columns[i].sizeCalculated = col.size; - this.columns[i].sizeType = 'px'; - } else { - percent += parseFloat(col.size); - this.columns[i].sizeType = '%'; - delete col.sizeCorrected; - } - } - // if sum != 100% -- reassign proportionally - if (percent != 100 && percent > 0) { - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (col.sizeType == '%') { - col.sizeCorrected = Math.round(parseFloat(col.size) * 100 * 100 / percent) / 100 + '%'; - } - } - } - // calculate % columns - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (col.sizeType == '%') { - if (typeof this.columns[i].sizeCorrected != 'undefined') { - // make it 1px smaller, so margin of error can be calculated correctly - this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.sizeCorrected) / 100) - 1 + 'px'; - } else { - // make it 1px smaller, so margin of error can be calculated correctly - this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.size) / 100) - 1 + 'px'; - } - } - } - } - // fix margin of error that is due percentage calculations - var width_cols = 0; - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - if (col.hidden) continue; - if (typeof col.min == 'undefined') col.min = 20; - if (parseInt(col.sizeCalculated) < parseInt(col.min)) col.sizeCalculated = col.min + 'px'; - if (parseInt(col.sizeCalculated) > parseInt(col.max)) col.sizeCalculated = col.max + 'px'; - width_cols += parseInt(col.sizeCalculated); - } - var width_diff = parseInt(width_box) - parseInt(width_cols); - if (width_diff > 0 && percent > 0) { - var i = 0; - while (true) { - var col = this.columns[i]; - if (typeof col == 'undefined') { i = 0; continue; } - if (col.hidden || col.sizeType == 'px') { i++; continue; } - col.sizeCalculated = (parseInt(col.sizeCalculated) + 1) + 'px'; - width_diff--; - if (width_diff == 0) break; - i++; - } - } else if (width_diff > 0) { - columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); - } - // resize columns - columns.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { - var ind = $(el).attr('col'); - if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); - // last column - if ($(el).hasClass('w2ui-head-last')) { - $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); - } - }); - // if there are column groups - hide first row (needed for sizing) - if (columns.find('> table > tbody > tr').length == 3) { - columns.find('> table > tbody > tr:nth-child(1) td').html('').css({ - 'height' : '0px', - 'border' : '0px', - 'padding' : '0px', - 'margin' : '0px' - }); - } - // resize records - records.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { - var ind = $(el).attr('col'); - if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); - // last column - if ($(el).hasClass('w2ui-grid-data-last')) { - $(el).css('width', (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); - } - }); - // resize summary - summary.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { - var ind = $(el).attr('col'); - if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); - // last column - if ($(el).hasClass('w2ui-grid-data-last')) { - $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); - } - }); - this.initResize(); - this.refreshRanges(); - // apply last scroll if any - if (this.last.scrollTop != '' && records.length > 0) { - columns.prop('scrollLeft', this.last.scrollLeft); - records.prop('scrollTop', this.last.scrollTop); - records.prop('scrollLeft', this.last.scrollLeft); - } - }, - - getSearchesHTML: function () { - var html = ''; - var showBtn = false; - for (var i = 0; i < this.searches.length; i++) { - var s = this.searches[i]; - s.type = String(s.type).toLowerCase(); - if (s.hidden) continue; - var btn = ''; - if (showBtn == false) { - btn = ''+ - ' ' + - ' ' + - ' '+ - ' ' + - ''; - } - html += ''+ - ' '+ - '
      '+ btn +''+ s.caption +''+ operator + - '
      '+ - '
      '; - - switch (s.type) { - case 'text': - case 'alphanumeric': - case 'hex': - case 'list': - case 'combo': - case 'enum': - html += ''; - break; - - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'date': - case 'time': - html += ''+ - ''; - break; - - case 'select': - html += ''; - break; - - } - html += s.outTag + - '
      '+ - '
      '+ - ' '+ - ' '+ - '
      '+ - '
      '; - return html; - }, - - initOperator: function (el, search_ind) { - var obj = this; - var search = obj.searches[search_ind]; - var range = $('#grid_'+ obj.name + '_range_'+ search_ind); - var fld1 = $('#grid_'+ obj.name +'_field_'+ search_ind); - var fld2 = fld1.parent().find('span input'); - if ($(el).val() == 'in') { fld1.w2field('clear'); } else { fld1.w2field(search.type); } - if ($(el).val() == 'between') { range.show(); fld2.w2field(search.type); } else { range.hide(); } - }, - - initSearches: function () { - var obj = this; - // init searches - for (var s in this.searches) { - var search = this.searches[s]; - var sdata = this.getSearchData(search.field); - search.type = String(search.type).toLowerCase(); - if (typeof search.options != 'object') search.options = {}; - // init types - switch (search.type) { - case 'text': - case 'alphanumeric': - $('#grid_'+ this.name +'_operator_'+s).val('begins'); - if (['alphanumeric', 'hex'].indexOf(search.type) != -1) { - $('#grid_'+ this.name +'_field_' + s).w2field(search.type, search.options); - } - break; - - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'date': - case 'time': - if (sdata && sdata.type == 'int' && sdata.operator == 'in') break; - $('#grid_'+ this.name +'_field_'+s).w2field(search.type, search.options); - $('#grid_'+ this.name +'_field2_'+s).w2field(search.type, search.options); - setTimeout(function () { // convert to date if it is number - $('#grid_'+ obj.name +'_field_'+s).keydown(); - $('#grid_'+ obj.name +'_field2_'+s).keydown(); - }, 1); - break; - - case 'hex': - break; - - case 'list': - case 'combo': - case 'enum': - var options = search.options; - if (search.type == 'list') options.selected = {}; - if (search.type == 'enum') options.selected = []; - if (sdata) options.selected = sdata.value; - $('#grid_'+ this.name +'_field_'+s).w2field(search.type, options); - if (search.type == 'combo') { - $('#grid_'+ this.name +'_operator_'+s).val('begins'); - } - break; - - case 'select': - // build options - var options = ''; - for (var i in search.options.items) { - var si = search.options.items[i]; - if ($.isPlainObject(search.options.items[i])) { - var val = si.id; - var txt = si.text; - if (typeof val == 'undefined' && typeof si.value != 'undefined') val = si.value; - if (typeof txt == 'undefined' && typeof si.caption != 'undefined') txt = si.caption; - if (val == null) val = ''; - options += ''; - } else { - options += ''; - } - } - $('#grid_'+ this.name +'_field_'+s).html(options); - break; - } - if (sdata != null) { - if (sdata.type == 'int' && sdata.operator == 'in') { - $('#grid_'+ this.name +'_field_'+ s).w2field('clear').val(sdata.value); - } - $('#grid_'+ this.name +'_operator_'+ s).val(sdata.operator).trigger('change'); - if (!$.isArray(sdata.value)) { - if (typeof sdata.value != 'udefined') $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); - } else { - if (sdata.operator == 'in') { - $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); - } else { - $('#grid_'+ this.name +'_field_'+ s).val(sdata.value[0]).trigger('change'); - $('#grid_'+ this.name +'_field2_'+ s).val(sdata.value[1]).trigger('change'); - } - } - } - } - // add on change event - $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches *[rel=search]').on('keypress', function (evnt) { - if (evnt.keyCode == 13 && (evnt.ctrlKey || evnt.metaKey)) { - obj.search(); - $().w2overlay(); - } - }); - }, - - getColumnsHTML: function () { - var obj = this; - var html = ''; - if (this.show.columnHeaders) { - if (this.columnGroups.length > 0) { - html = getColumns(true) + getGroups() + getColumns(false); - } else { - html = getColumns(true); - } - } - return html; - - function getGroups () { - var html = ''; - // add empty group at the end - if (obj.columnGroups[obj.columnGroups.length-1].caption != '') obj.columnGroups.push({ caption: '' }); - - if (obj.show.lineNumbers) { - html += ''+ - '
       
      '+ - ''; - } - if (obj.show.selectColumn) { - html += ''+ - '
       
      '+ - ''; - } - if (obj.show.expandColumn) { - html += ''+ - '
       
      '+ - ''; - } - var ii = 0; - for (var i=0; i
      '; - } - html += ''+ - resizer + - '
      '+ - '
      '+ - (!col.caption ? ' ' : col.caption) + - '
      '+ - ''; - } else { - html += ''+ - '
      '+ - (!colg.caption ? ' ' : colg.caption) + - '
      '+ - ''; - } - ii += colg.span; - } - html += ''; - return html; - } - - function getColumns (master) { - var html = '', - reorderCols = (obj.reorderColumns && (!obj.columnGroups || !obj.columnGroups.length)) ? ' w2ui-reorder-cols-head ' : ''; - if (obj.show.lineNumbers) { - html += ''+ - '
      #
      '+ - ''; - } - if (obj.show.selectColumn) { - html += ''+ - '
      '+ - ' '+ - '
      '+ - ''; - } - if (obj.show.expandColumn) { - html += ''+ - '
       
      '+ - ''; - } - var ii = 0; - var id = 0; - for (var i=0; i
      '; - } - html += ''+ - resizer + - '
      '+ - '
      '+ - (!col.caption ? ' ' : col.caption) + - '
      '+ - ''; - } - } - html += '
       
      '; - html += ''; - return html; - } - }, - - getRecordsHTML: function () { - // larget number works better with chrome, smaller with FF. - if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; - var records = $('#grid_'+ this.name +'_records'); - var limit = Math.floor(records.height() / this.recordHeight) + this.show_extra + 1; - if (!this.fixedBody) limit = this.buffered; - // always need first record for resizing purposes - var html = '' + this.getRecordHTML(-1, 0); - // first empty row with height - html += ''+ - ' '+ - ''; - for (var i = 0; i < limit; i++) { - html += this.getRecordHTML(i, i+1); - } - html += ''+ - ' '+ - ''+ - ''+ - ' '+ - ''+ - '
      '; - this.last.range_start = 0; - this.last.range_end = limit; - return html; - }, - - getSummaryHTML: function () { - if (this.summary.length == 0) return; - var html = ''; - for (var i = 0; i < this.summary.length; i++) { - html += this.getRecordHTML(i, i+1, true); - } - html += '
      '; - return html; - }, - - scroll: function (event) { - var time = (new Date()).getTime(); - var obj = this; - var records = $('#grid_'+ this.name +'_records'); - if (this.records.length == 0 || records.length == 0 || records.height() == 0) return; - if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; - // need this to enable scrolling when this.limit < then a screen can fit - if (records.height() < this.buffered * this.recordHeight && records.css('overflow-y') == 'hidden') { - if (this.total > 0) this.refresh(); - return; - } - // update footer - var t1 = Math.round(records[0].scrollTop / this.recordHeight + 1); - var t2 = t1 + (Math.round(records.height() / this.recordHeight) - 1); - if (t1 > this.buffered) t1 = this.buffered; - if (t2 > this.buffered) t2 = this.buffered; - var url = (typeof this.url != 'object' ? this.url : this.url.get); - $('#grid_'+ this.name + '_footer .w2ui-footer-right').html(w2utils.formatNumber(this.offset + t1) + '-' + w2utils.formatNumber(this.offset + t2) + ' ' + w2utils.lang('of') + ' ' + w2utils.formatNumber(this.total) + - (url ? ' ('+ w2utils.lang('buffered') + ' '+ w2utils.formatNumber(this.buffered) + (this.offset > 0 ? ', skip ' + w2utils.formatNumber(this.offset) : '') + ')' : '') - ); - // only for local data source, else no extra records loaded - if (!url && (!this.fixedBody || this.total <= 300)) return; - // regular processing - var start = Math.floor(records[0].scrollTop / this.recordHeight) - this.show_extra; - var end = start + Math.floor(records.height() / this.recordHeight) + this.show_extra * 2 + 1; - // var div = start - this.last.range_start; - if (start < 1) start = 1; - if (end > this.total) end = this.total; - var tr1 = records.find('#grid_'+ this.name +'_rec_top'); - var tr2 = records.find('#grid_'+ this.name +'_rec_bottom'); - // if row is expanded - if (String(tr1.next().prop('id')).indexOf('_expanded_row') != -1) tr1.next().remove(); - if (this.total > end && String(tr2.prev().prop('id')).indexOf('_expanded_row') != -1) tr2.prev().remove(); - var first = parseInt(tr1.next().attr('line')); - var last = parseInt(tr2.prev().attr('line')); - //$('#log').html('buffer: '+ this.buffered +' start-end: ' + start + '-'+ end + ' ===> first-last: ' + first + '-' + last); - if (first < start || first == 1 || this.last.pull_refresh) { // scroll down - // console.log('end', end, 'last', last, 'show_extre', this.show_extra, this.last.pull_refresh); - if (end <= last + this.show_extra - 2 && end != this.total) return; - this.last.pull_refresh = false; - // remove from top - while (true) { - var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); - if (tmp.attr('line') == 'bottom') break; - if (parseInt(tmp.attr('line')) < start) tmp.remove(); else break; - } - // add at bottom - var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); - var rec_start = tmp.attr('line'); - if (rec_start == 'top') rec_start = start; - for (var i = parseInt(rec_start) + 1; i <= end; i++) { - if (!this.records[i-1]) continue; - if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; - tr2.before(this.getRecordHTML(i-1, i)); - } - markSearch(); - setTimeout(function() { obj.refreshRanges(); }, 0); - } else { // scroll up - if (start >= first - this.show_extra + 2 && start > 1) return; - // remove from bottom - while (true) { - var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); - if (tmp.attr('line') == 'top') break; - if (parseInt(tmp.attr('line')) > end) tmp.remove(); else break; - } - // add at top - var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); - var rec_start = tmp.attr('line'); - if (rec_start == 'bottom') rec_start = end; - for (var i = parseInt(rec_start) - 1; i >= start; i--) { - if (!this.records[i-1]) continue; - if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; - tr1.after(this.getRecordHTML(i-1, i)); - } - markSearch(); - setTimeout(function() { obj.refreshRanges(); }, 0); - } - // first/last row size - var h1 = (start - 1) * obj.recordHeight; - var h2 = (this.buffered - end) * obj.recordHeight; - if (h2 < 0) h2 = 0; - tr1.css('height', h1 + 'px'); - tr2.css('height', h2 + 'px'); - obj.last.range_start = start; - obj.last.range_end = end; - // load more if needed - var s = Math.floor(records[0].scrollTop / this.recordHeight); - var e = s + Math.floor(records.height() / this.recordHeight); - if (e + 10 > this.buffered && this.last.pull_more !== true && this.buffered < this.total - this.offset) { - if (this.autoLoad === true) { - this.last.pull_more = true; - this.last.xhr_offset += this.limit; - this.request('get-records'); - } else { - var more = $('#grid_'+ this.name +'_rec_more'); - if (more.css('display') == 'none') { - more.show() - .on('click', function () { - obj.last.pull_more = true; - obj.last.xhr_offset += obj.limit; - obj.request('get-records'); - // show spinner the last - $(this).find('td').html('
      '); - }); - } - if (more.find('td').text().indexOf('Load') == -1) { - more.find('td').html('
      '+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
      '); - } - } - } - // check for grid end - if (this.buffered >= this.total - this.offset) $('#grid_'+ this.name +'_rec_more').hide(); - return; - - function markSearch() { - // mark search - if(obj.markSearch === false) return; - clearTimeout(obj.last.marker_timer); - obj.last.marker_timer = setTimeout(function () { - // mark all search strings - var str = []; - for (var s in obj.searchData) { - var tmp = obj.searchData[s]; - if ($.inArray(tmp.value, str) == -1) str.push(tmp.value); - } - if (str.length > 0) $(obj.box).find('.w2ui-grid-data > div').w2marker(str); - }, 50); - } - }, - - getRecordHTML: function (ind, lineNum, summary) { - var rec_html = ''; - var sel = this.last.selection; - var record; - // first record needs for resize purposes - if (ind == -1) { - rec_html += ''; - if (this.show.lineNumbers) rec_html += ''; - if (this.show.selectColumn) rec_html += ''; - if (this.show.expandColumn) rec_html += ''; - for (var i in this.columns) { - if (this.columns[i].hidden) continue; - rec_html += ''; - } - rec_html += ''; - rec_html += ''; - return rec_html; - } - // regular record - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (summary !== true) { - if (this.searchData.length > 0 && !url) { - if (ind >= this.last.searchIds.length) return ''; - ind = this.last.searchIds[ind]; - record = this.records[ind]; - } else { - if (ind >= this.records.length) return ''; - record = this.records[ind]; - } - } else { - if (ind >= this.summary.length) return ''; - record = this.summary[ind]; - } - if (!record) return ''; - var id = w2utils.escapeId(record.recid); - var isRowSelected = false; - if (sel.indexes.indexOf(ind) != -1) isRowSelected = true; - // render TR - rec_html += ''; - if (this.show.lineNumbers) { - rec_html += ''+ - (summary !== true ? '
      '+ lineNum +'
      ' : '') + - ''; - } - if (this.show.selectColumn) { - rec_html += - ''+ - (summary !== true ? - '
      '+ - ' '+ - '
      ' - : - '' ) + - ''; - } - if (this.show.expandColumn) { - var tmp_img = ''; - if (record.expanded === true) tmp_img = '-'; else tmp_img = '+'; - if (record.expanded == 'none') tmp_img = ''; - if (record.expanded == 'spinner') tmp_img = '
      '; - rec_html += - ''+ - (summary !== true ? - '
      '+ - ' '+ tmp_img +'
      ' - : - '' ) + - ''; - } - var col_ind = 0; - while (true) { - var col = this.columns[col_ind]; - if (col.hidden) { col_ind++; if (typeof this.columns[col_ind] == 'undefined') break; else continue; } - var isChanged = !summary && record.changes && typeof record.changes[col.field] != 'undefined'; - var rec_cell = this.getCellHTML(ind, col_ind, summary); - var addStyle = ''; - if (typeof col.render == 'string') { - var tmp = col.render.toLowerCase().split(':'); - if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) addStyle += 'text-align: right;'; - } - if (typeof record.style == 'object' && typeof record.style[col_ind] == 'string') { - addStyle += record.style[col_ind] + ';'; - } - var isCellSelected = false; - if (isRowSelected && $.inArray(col_ind, sel.columns[ind]) != -1) isCellSelected = true; - rec_html += ''+ - rec_cell + - ''; - col_ind++; - if (typeof this.columns[col_ind] == 'undefined') break; - } - rec_html += ''; - rec_html += ''; - return rec_html; - }, - - getCellHTML: function (ind, col_ind, summary) { - var col = this.columns[col_ind]; - var record = (summary !== true ? this.records[ind] : this.summary[ind]); - var data = this.getCellValue(ind, col_ind, summary); - var edit = col.editable; - // various renderers - if (typeof col.render != 'undefined') { - if (typeof col.render == 'function') { - data = $.trim(col.render.call(this, record, ind, col_ind)); - if (data.length < 4 || data.substr(0, 4).toLowerCase() != ''; - } - if (typeof col.render == 'object') data = '
      ' + col.render[data] + '
      '; - if (typeof col.render == 'string') { - var tmp = col.render.toLowerCase().split(':'); - var prefix = ''; - var suffix = ''; - if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) { - if (typeof tmp[1] == 'undefined' || !w2utils.isInt(tmp[1])) tmp[1] = 0; - if (tmp[1] > 20) tmp[1] = 20; - if (tmp[1] < 0) tmp[1] = 0; - if (['money', 'currency'].indexOf(tmp[0]) != -1) { tmp[1] = w2utils.settings.currencyPrecision; prefix = w2utils.settings.currencyPrefix; suffix = w2utils.settings.currencySuffix } - if (tmp[0] == 'percent') { suffix = '%'; if (tmp[1] !== '0') tmp[1] = 1; } - if (tmp[0] == 'int') { tmp[1] = 0; } - // format - data = '
      ' + (data !== '' ? prefix + w2utils.formatNumber(Number(data).toFixed(tmp[1])) + suffix : '') + '
      '; - } - if (tmp[0] == 'time') { - if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.time_format; - data = '
      ' + prefix + w2utils.formatTime(data, tmp[1] == 'h12' ? 'hh:mi pm': 'h24:min') + suffix + '
      '; - } - if (tmp[0] == 'date') { - if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.date_display; - data = '
      ' + prefix + w2utils.formatDate(data, tmp[1]) + suffix + '
      '; - } - if (tmp[0] == 'age') { - data = '
      ' + prefix + w2utils.age(data) + suffix + '
      '; - } - } - } else { - // if editable checkbox - var addStyle = ''; - if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { - var changeInd = summary ? -(ind + 1) : ind; - addStyle = 'text-align: center'; - data = ''; - } - if (!this.show.recordTitles) { - var data = '
      '+ data +'
      '; - } else { - // title overwrite - var title = String(data).replace(/"/g, "''"); - if (typeof col.title != 'undefined') { - if (typeof col.title == 'function') title = col.title.call(this, record, ind, col_ind); - if (typeof col.title == 'string') title = col.title; - } - var data = '
      '+ data +'
      '; - } - } - if (data == null || typeof data == 'undefined') data = ''; - return data; - }, - - getCellValue: function (ind, col_ind, summary) { - var col = this.columns[col_ind]; - var record = (summary !== true ? this.records[ind] : this.summary[ind]); - var data = this.parseField(record, col.field); - if (record.changes && typeof record.changes[col.field] != 'undefined') data = record.changes[col.field]; - if (data == null || typeof data == 'undefined') data = ''; - return data; - }, - - getFooterHTML: function () { - return '
      '+ - ' '+ - ' '+ - ' '+ - '
      '; - }, - - status: function (msg) { - if (typeof msg != 'undefined') { - $('#grid_'+ this.name +'_footer').find('.w2ui-footer-left').html(msg); - } else { - // show number of selected - var msgLeft = ''; - var sel = this.getSelection(); - if (sel.length > 0) { - msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") + ' ' + w2utils.lang('selected'); - var tmp = sel[0]; - if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column; - if (sel.length == 1) msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' '; - } - $('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft); - // toolbar - if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); - if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); - } - }, - - lock: function (msg, showSpinner) { - var box = $(this.box).find('> div:first-child'); - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(box); - setTimeout(function () { w2utils.lock.apply(window, args); }, 10); - }, - - unlock: function () { - var box = this.box; - setTimeout(function () { w2utils.unlock(box); }, 25); // needed timer so if server fast, it will not flash - }, - - parseField: function (obj, field) { - var val = ''; - try { // need this to make sure no error in fields - val = obj; - var tmp = String(field).split('.'); - for (var i in tmp) { - val = val[tmp[i]]; - } - } catch (event) { - val = ''; - } - return val; - }, - - prepareData: function () { - // loops thru records and prepares date and time objects - for (var r in this.records) { - var rec = this.records[r]; - for (var c in this.columns) { - var column = this.columns[c]; - if (rec[column.field] == null || typeof column.render != 'string') continue; - // number - if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { - if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]); - } - // date - if (['date', 'age'].indexOf(column.render) != -1) { - if (!rec[column.field + '_']) { - var dt = rec[column.field]; - if (w2utils.isInt(dt)) dt = parseInt(dt); - rec[column.field + '_'] = new Date(dt); - } - } - // time - if (['time'].indexOf(column.render) != -1) { - if (w2utils.isTime(rec[column.field])) { // if string - var tmp = w2utils.isTime(rec[column.field], true); - var dt = new Date(); - dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0); // sets hours, min, sec, mills - if (!rec[column.field + '_']) rec[column.field + '_'] = dt; - } else { // if date object - var tmp = rec[column.field]; - if (w2utils.isInt(tmp)) tmp = parseInt(tmp); - var tmp = (tmp != null ? new Date(tmp) : new Date()); - var dt = new Date(); - dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0); // sets hours, min, sec, mills - if (!rec[column.field + '_']) rec[column.field + '_'] = dt; - } - } - } - } - }, - - nextCell: function (col_ind, editable) { - var check = col_ind + 1; - if (this.columns.length == check) return false; - if (editable === true) { - var edit = this.columns[check].editable; - if (this.columns[check].hidden || typeof edit == 'undefined' - || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.nextCell(check, editable); - } - return check; - }, - - prevCell: function (col_ind, editable) { - var check = col_ind - 1; - if (check < 0) return false; - if (editable === true) { - var edit = this.columns[check].editable; - if (this.columns[check].hidden || typeof edit == 'undefined' - || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.prevCell(check, editable); - } - return check; - }, - - nextRow: function (ind) { - if ((ind + 1 < this.records.length && this.last.searchIds.length == 0) // if there are more records - || (this.last.searchIds.length > 0 && ind < this.last.searchIds[this.last.searchIds.length-1])) { - ind++; - if (this.last.searchIds.length > 0) { - while (true) { - if ($.inArray(ind, this.last.searchIds) != -1 || ind > this.records.length) break; - ind++; - } - } - return ind; - } else { - return null; - } - }, - - prevRow: function (ind) { - if ((ind > 0 && this.last.searchIds.length == 0) // if there are more records - || (this.last.searchIds.length > 0 && ind > this.last.searchIds[0])) { - ind--; - if (this.last.searchIds.length > 0) { - while (true) { - if ($.inArray(ind, this.last.searchIds) != -1 || ind < 0) break; - ind--; - } - } - return ind; - } else { - return null; - } - } - }; - - $.extend(w2grid.prototype, w2utils.event); - w2obj.grid = w2grid; + var w2grid = function(options) { + + // public properties + this.name = null; + this.box = null; // HTML element that hold this element + this.header = ''; + this.url = ''; + this.columns = []; // { field, caption, size, attr, render, hidden, gridMinWidth, [editable: {type, inTag, outTag, style, items}] } + this.columnGroups = []; // { span: int, caption: 'string', master: true/false } + this.records = []; // { recid: int(requied), field1: 'value1', ... fieldN: 'valueN', style: 'string', editable: true/false, summary: true/false, changes: object } + this.summary = []; // arry of summary records, same structure as records array + this.searches = []; // { type, caption, field, inTag, outTag, default, items, hidden } + this.searchData = []; + this.sortData = []; + this.postData = {}; + this.toolbar = {}; // if not empty object; then it is toolbar object + + this.show = { + header : false, + toolbar : false, + footer : false, + columnHeaders : true, + lineNumbers : false, + expandColumn : false, + selectColumn : false, + emptyRecords : true, + toolbarReload : true, + toolbarColumns : true, + toolbarSearch : true, + toolbarAdd : false, + toolbarEdit : false, + toolbarDelete : false, + toolbarSave : false, + selectionBorder : true, + recordTitles : true + }; + + this.autoLoad = true; // for infinite scroll + this.fixedBody = true; // if false; then grid grows with data + this.recordHeight = 24; + this.keyboard = true; + this.selectType = 'row'; // can be row|cell + this.multiSearch = true; + this.multiSelect = true; + this.multiSort = true; + this.reorderColumns = false; + this.reorderRows = false; + this.markSearch = true; + + this.total = 0; // server total + this.buffered = 0; // number of records in the records array + this.limit = 100; + this.offset = 0; // how many records to skip (for infinite scroll) when pulling from server + this.style = ''; + this.ranges = []; + this.menu = []; + this.method; // if defined, then overwrited ajax method + this.recid; + this.parser; + + // events + this.onAdd = null; + this.onEdit = null; + this.onRequest = null; // called on any server event + this.onLoad = null; + this.onDelete = null; + this.onDeleted = null; + this.onSubmit = null; + this.onSave = null; + this.onSelect = null; + this.onUnselect = null; + this.onClick = null; + this.onDblClick = null; + this.onContextMenu = null; + this.onMenuClick = null; // when context menu item selected + this.onColumnClick = null; + this.onColumnResize = null; + this.onSort = null; + this.onSearch = null; + this.onChange = null; // called when editable record is changed + this.onRestore = null; // called when editable record is restored + this.onExpand = null; + this.onCollapse = null; + this.onError = null; + this.onKeydown = null; + this.onToolbar = null; // all events from toolbar + this.onColumnOnOff = null; + this.onCopy = null; + this.onPaste = null; + this.onSelectionExtend = null; + this.onEditField = null; + this.onRender = null; + this.onRefresh = null; + this.onReload = null; + this.onResize = null; + this.onDestroy = null; + + // internal + this.last = { + field : 'all', + caption : w2utils.lang('All Fields'), + logic : 'OR', + search : '', + searchIds : [], + selection : { + indexes : [], + columns : {}, + }, + multi : false, + scrollTop : 0, + scrollLeft : 0, + sortData : null, + sortCount : 0, + xhr : null, + range_start : null, + range_end : null, + sel_ind : null, + sel_col : null, + sel_type : null, + edit_col : null + }; + + this.isIOS = (navigator.userAgent.toLowerCase().indexOf('iphone') != -1 || + navigator.userAgent.toLowerCase().indexOf('ipod') != -1 || + navigator.userAgent.toLowerCase().indexOf('ipad') != -1) ? true : false; + + $.extend(true, this, w2obj.grid, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2grid = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2grid')) return; + // remember items + var columns = method.columns; + var columnGroups = method.columnGroups; + var records = method.records; + var searches = method.searches; + var searchData = method.searchData; + var sortData = method.sortData; + var postData = method.postData; + var toolbar = method.toolbar; + // extend items + var object = new w2grid(method); + $.extend(object, { postData: {}, records: [], columns: [], searches: [], toolbar: {}, sortData: [], searchData: [], handlers: [] }); + if (object.onExpand != null) object.show.expandColumn = true; + $.extend(true, object.toolbar, toolbar); + // reassign variables + for (var p in columns) object.columns[p] = $.extend(true, {}, columns[p]); + for (var p in columnGroups) object.columnGroups[p] = $.extend(true, {}, columnGroups[p]); + for (var p in searches) object.searches[p] = $.extend(true, {}, searches[p]); + for (var p in searchData) object.searchData[p] = $.extend(true, {}, searchData[p]); + for (var p in sortData) object.sortData[p] = $.extend(true, {}, sortData[p]); + object.postData = $.extend(true, {}, postData); + + // check if there are records without recid + for (var r in records) { + if (records[r].recid == null || typeof records[r].recid == 'undefined') { + console.log('ERROR: Cannot add records without recid. (obj: '+ object.name +')'); + return; + } + object.records[r] = $.extend(true, {}, records[r]); + } + if (object.records.length > 0) object.buffered = object.records.length; + // add searches + for (var c in object.columns) { + var col = object.columns[c]; + if (typeof col.searchable == 'undefined' || object.getSearch(col.field) != null) continue; + var stype = col.searchable; + var attr = ''; + if (col.searchable === true) { stype = 'text'; attr = 'size="20"'; } + object.addSearch({ field: col.field, caption: col.caption, type: stype, attr: attr }); + } + // init toolbar + object.initToolbar(); + // render if necessary + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + return object; + + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2grid'); + } + } + + // ==================================================== + // -- Implementation of core functionality + + w2grid.prototype = { + // ---- + // properties that need to be in prototype + + msgDelete : 'Are you sure you want to delete selected records?', + msgNotJSON : 'Returned data is not in valid JSON format.', + msgAJAXerror : 'AJAX error. See console for more details.', + msgRefresh : 'Refreshing...', + + // for easy button overwrite + buttons: { + 'reload' : { type: 'button', id: 'w2ui-reload', img: 'icon-reload', hint: 'Reload data in the list' }, + 'columns' : { type: 'drop', id: 'w2ui-column-on-off', img: 'icon-columns', hint: 'Show/hide columns', arrow: false, html: '' }, + 'search' : { type: 'html', id: 'w2ui-search', + html: '
      ' + }, + 'search-go': { type: 'check', id: 'w2ui-search-advanced', caption: 'Search...', hint: 'Open Search Fields' }, + 'add' : { type: 'button', id: 'w2ui-add', caption: 'Add New', hint: 'Add new record', img: 'icon-add' }, + 'edit' : { type: 'button', id: 'w2ui-edit', caption: 'Edit', hint: 'Edit selected record', img: 'icon-edit', disabled: true }, + 'delete' : { type: 'button', id: 'w2ui-delete', caption: 'Delete', hint: 'Delete selected records', img: 'icon-delete', disabled: true }, + 'save' : { type: 'button', id: 'w2ui-save', caption: 'Save', hint: 'Save changed records', img: 'icon-save' } + }, + + add: function (record) { + if (!$.isArray(record)) record = [record]; + var added = 0; + for (var o in record) { + if (!this.recid && typeof record[o].recid == 'undefined') record[o].recid = record[o][this.recid]; + if (record[o].recid == null || typeof record[o].recid == 'undefined') { + console.log('ERROR: Cannot add record without recid. (obj: '+ this.name +')'); + continue; + } + this.records.push(record[o]); + added++; + } + this.buffered = this.records.length; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.total = this.records.length; + this.localSort(); + this.localSearch(); + } + this.refresh(); // ?? should it be reload? + return added; + }, + + find: function (obj, returnIndex) { + if (typeof obj == 'undefined' || obj == null) obj = {}; + var recs = []; + var hasDots = false; + // check if property is nested - needed for speed + for (var o in obj) if (String(o).indexOf('.') != -1) hasDots = true; + // look for an item + for (var i = 0; i < this.records.length; i++) { + var match = true; + for (var o in obj) { + var val = this.records[i][o]; + if (hasDots && String(o).indexOf('.') != -1) val = this.parseField(this.records[i], o); + if (obj[o] != val) match = false; + } + if (match && returnIndex !== true) recs.push(this.records[i].recid); + if (match && returnIndex === true) recs.push(i); + } + return recs; + }, + + set: function (recid, record, noRefresh) { // does not delete existing, but overrides on top of it + if (typeof recid == 'object') { + noRefresh = record; + record = recid; + recid = null; + } + // update all records + if (recid == null) { + for (var r in this.records) { + $.extend(true, this.records[r], record); // recid is the whole record + } + if (noRefresh !== true) this.refresh(); + } else { // find record to update + var ind = this.get(recid, true); + if (ind == null) return false; + $.extend(true, this.records[ind], record); + if (noRefresh !== true) this.refreshRow(recid); // refresh only that record + } + return true; + }, + + get: function (recid, returnIndex) { + for (var i = 0; i < this.records.length; i++) { + if (this.records[i].recid == recid) { + if (returnIndex === true) return i; else return this.records[i]; + } + } + return null; + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.records.length-1; r >= 0; r--) { + if (this.records[r].recid == arguments[a]) { this.records.splice(r, 1); removed++; } + } + } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.buffered = this.records.length; + this.localSort(); + this.localSearch(); + } + this.refresh(); + return removed; + }, + + addColumn: function (before, columns) { + var added = 0; + if (arguments.length == 1) { + columns = before; + before = this.columns.length; + } else { + if (typeof before == 'string') before = this.getColumn(before, true); + if (before === null) before = this.columns.length; + } + if (!$.isArray(columns)) columns = [columns]; + for (var o in columns) { + this.columns.splice(before, 0, columns[o]); + before++; + added++; + } + this.initColumnOnOff(); + this.refresh(); + return added; + }, + + removeColumn: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a]) { this.columns.splice(r, 1); removed++; } + } + } + this.initColumnOnOff(); + this.refresh(); + return removed; + }, + + getColumn: function (field, returnIndex) { + for (var i = 0; i < this.columns.length; i++) { + if (this.columns[i].field == field) { + if (returnIndex === true) return i; else return this.columns[i]; + } + } + return null; + }, + + toggleColumn: function () { + var effected = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a]) { + this.columns[r].hidden = !this.columns[r].hidden; + effected++; + } + } + } + this.refresh(); + return effected; + }, + + showColumn: function () { + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a] && this.columns[r].hidden !== false) { + this.columns[r].hidden = false; + shown++; + } + } + } + this.refresh(); + return shown; + }, + + hideColumn: function () { + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a] && this.columns[r].hidden !== true) { + this.columns[r].hidden = true; + hidden++; + } + } + } + this.refresh(); + return hidden; + }, + + addSearch: function (before, search) { + var added = 0; + if (arguments.length == 1) { + search = before; + before = this.searches.length; + } else { + if (typeof before == 'string') before = this.getSearch(before, true); + if (before === null) before = this.searches.length; + } + if (!$.isArray(search)) search = [search]; + for (var o in search) { + this.searches.splice(before, 0, search[o]); + before++; + added++; + } + this.searchClose(); + return added; + }, + + removeSearch: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { this.searches.splice(r, 1); removed++; } + } + } + this.searchClose(); + return removed; + }, + + getSearch: function (field, returnIndex) { + for (var i = 0; i < this.searches.length; i++) { + if (this.searches[i].field == field) { + if (returnIndex === true) return i; else return this.searches[i]; + } + } + return null; + }, + + toggleSearch: function () { + var effected = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { + this.searches[r].hidden = !this.searches[r].hidden; + effected++; + } + } + } + this.searchClose(); + return effected; + }, + + showSearch: function () { + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== false) { + this.searches[r].hidden = false; + shown++; + } + } + } + this.searchClose(); + return shown; + }, + + hideSearch: function () { + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + for (var r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== true) { + this.searches[r].hidden = true; + hidden++; + } + } + } + this.searchClose(); + return hidden; + }, + + getSearchData: function (field) { + for (var s in this.searchData) { + if (this.searchData[s].field == field) return this.searchData[s]; + } + return null; + }, + + localSort: function (silent) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + console.log('ERROR: grid.localSort can only be used on local data source, grid.url should be empty.'); + return; + } + if ($.isEmptyObject(this.sortData)) return; + var time = (new Date()).getTime(); + var obj = this; + // process date fields + obj.prepareData(); + // process sortData + for (var s in this.sortData) { + var column = this.getColumn(this.sortData[s].field); + if (!column) return; + if (column.render && ['date', 'age'].indexOf(column.render) != -1) { + this.sortData[s]['field_'] = column.field + '_'; + } + if (column.render && ['time'].indexOf(column.render) != -1) { + this.sortData[s]['field_'] = column.field + '_'; + } + } + // process sort + this.records.sort(function (a, b) { + var ret = 0; + for (var s in obj.sortData) { + var fld = obj.sortData[s].field; + if (obj.sortData[s].field_) fld = obj.sortData[s].field_; + var aa = a[fld]; + var bb = b[fld]; + if (String(fld).indexOf('.') != -1) { + aa = obj.parseField(a, fld); + bb = obj.parseField(b, fld); + } + if (typeof aa == 'string') aa = $.trim(aa.toLowerCase()); + if (typeof bb == 'string') bb = $.trim(bb.toLowerCase()); + if (aa > bb) ret = (obj.sortData[s].direction == 'asc' ? 1 : -1); + if (aa < bb) ret = (obj.sortData[s].direction == 'asc' ? -1 : 1); + if (typeof aa != 'object' && typeof bb == 'object') ret = -1; + if (typeof bb != 'object' && typeof aa == 'object') ret = 1; + if (aa == null && bb != null) ret = 1; // all nuls and undefined on bottom + if (aa != null && bb == null) ret = -1; + if (ret != 0) break; + } + return ret; + }); + time = (new Date()).getTime() - time; + if (silent !== true) setTimeout(function () { obj.status('Sorting took ' + time/1000 + ' sec'); }, 10); + return time; + }, + + localSearch: function (silent) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + console.log('ERROR: grid.localSearch can only be used on local data source, grid.url should be empty.'); + return; + } + var time = (new Date()).getTime(); + var obj = this; + this.total = this.records.length; + // mark all records as shown + this.last.searchIds = []; + // prepare date/time fields + this.prepareData(); + // hide records that did not match + if (this.searchData.length > 0 && !url) { + this.total = 0; + for (var r in this.records) { + var rec = this.records[r]; + var fl = 0; + for (var s in this.searchData) { + var sdata = this.searchData[s]; + var search = this.getSearch(sdata.field); + if (sdata == null) continue; + if (search == null) search = { field: sdata.field, type: sdata.type }; + var val1 = String(obj.parseField(rec, search.field)).toLowerCase(); + if (typeof sdata.value != 'undefined') { + if (!$.isArray(sdata.value)) { + var val2 = String(sdata.value).toLowerCase(); + } else { + var val2 = sdata.value[0]; + var val3 = sdata.value[1]; + } + } + switch (sdata.operator) { + case 'is': + if (rec[search.field] == sdata.value) fl++; // do not hide record + if (search.type == 'date') { + var val1 = w2utils.formatDate(rec[search.field + '_'], 'yyyy-mm-dd'); + var val2 = w2utils.formatDate(val2, 'yyyy-mm-dd'); + if (val1 == val2) fl++; + } + if (search.type == 'time') { + var val1 = w2utils.formatTime(rec[search.field + '_'], 'h24:mi'); + var val2 = w2utils.formatTime(val2, 'h24:mi'); + if (val1 == val2) fl++; + } + break; + case 'between': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + if (parseFloat(rec[search.field]) >= parseFloat(val2) && parseFloat(rec[search.field]) <= parseFloat(val3)) fl++; + } + if (search.type == 'date') { + var val1 = rec[search.field + '_']; + var val2 = w2utils.isDate(val2, w2utils.settings.date_format, true); + var val3 = w2utils.isDate(val3, w2utils.settings.date_format, true); + if (val3 != null) val3 = new Date(val3.getTime() + 86400000); // 1 day + if (val1 >= val2 && val1 < val3) fl++; + } + if (search.type == 'time') { + var val1 = rec[search.field + '_']; + var val2 = w2utils.isTime(val2, true); + var val3 = w2utils.isTime(val3, true); + val2 = (new Date()).setHours(val2.hours, val2.minutes, val2.seconds ? val2.seconds : 0, 0); + val3 = (new Date()).setHours(val3.hours, val3.minutes, val3.seconds ? val3.seconds : 0, 0); + if (val1 >= val2 && val1 < val3) fl++; + } + break; + case 'in': + if (sdata.svalue) { + if (sdata.svalue.indexOf(val1) !== -1) fl++; + } else { + if (sdata.value.indexOf(val1) !== -1) fl++; + } + break; + case 'begins': + if (val1.indexOf(val2) == 0) fl++; // do not hide record + break; + case 'contains': + if (val1.indexOf(val2) >= 0) fl++; // do not hide record + break; + case 'ends': + if (val1.indexOf(val2) == val1.length - val2.length) fl++; // do not hide record + break; + } + } + if ((this.last.logic == 'OR' && fl != 0) || (this.last.logic == 'AND' && fl == this.searchData.length)) this.last.searchIds.push(parseInt(r)); + } + this.total = this.last.searchIds.length; + } + this.buffered = this.total; + time = (new Date()).getTime() - time; + if (silent !== true) setTimeout(function () { obj.status('Search took ' + time/1000 + ' sec'); }, 10); + return time; + }, + + getRangeData: function (range, extra) { + var rec1 = this.get(range[0].recid, true); + var rec2 = this.get(range[1].recid, true); + var col1 = range[0].column; + var col2 = range[1].column; + + var res = []; + if (col1 == col2) { // one row + for (var r = rec1; r <= rec2; r++) { + var record = this.records[r]; + var dt = record[this.columns[col1].field] || null; + if (extra !== true) { + res.push(dt); + } else { + res.push({ data: dt, column: col1, index: r, record: record }); + } + } + } else if (rec1 == rec2) { // one line + var record = this.records[rec1]; + for (var i = col1; i <= col2; i++) { + var dt = record[this.columns[i].field] || null; + if (extra !== true) { + res.push(dt); + } else { + res.push({ data: dt, column: i, index: rec1, record: record }); + } + } + } else { + for (var r = rec1; r <= rec2; r++) { + var record = this.records[r]; + res.push([]); + for (var i = col1; i <= col2; i++) { + var dt = record[this.columns[i].field]; + if (extra !== true) { + res[res.length-1].push(dt); + } else { + res[res.length-1].push({ data: dt, column: i, index: r, record: record }); + } + } + } + } + return res; + }, + + addRange: function (ranges) { + var added = 0; + if (this.selectType == 'row') return added; + if (!$.isArray(ranges)) ranges = [ranges]; + // if it is selection + for (var r in ranges) { + if (typeof ranges[r] != 'object') ranges[r] = { name: 'selection' }; + if (ranges[r].name == 'selection') { + if (this.show.selectionBorder === false) continue; + var sel = this.getSelection(); + if (sel.length == 0) { + this.removeRange(ranges[r].name); + continue; + } else { + var first = sel[0]; + var last = sel[sel.length-1]; + var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); + var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); + } + } else { // other range + var first = ranges[r].range[0]; + var last = ranges[r].range[1]; + var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); + var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); + } + if (first) { + var rg = { + name: ranges[r].name, + range: [{ recid: first.recid, column: first.column }, { recid: last.recid, column: last.column }], + style: ranges[r].style || '' + }; + // add range + var ind = false; + for (var t in this.ranges) if (this.ranges[t].name == ranges[r].name) { ind = r; break; } + if (ind !== false) { + this.ranges[ind] = rg; + } else { + this.ranges.push(rg); + } + added++ + } + } + this.refreshRanges(); + return added; + }, + + removeRange: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var name = arguments[a]; + $('#grid_'+ this.name +'_'+ name).remove(); + for (var r = this.ranges.length-1; r >= 0; r--) { + if (this.ranges[r].name == name) { + this.ranges.splice(r, 1); + removed++; + } + } + } + return removed; + }, + + refreshRanges: function () { + var obj = this; + var time = (new Date()).getTime(); + var rec = $('#grid_'+ this.name +'_records'); + for (var r in this.ranges) { + var rg = this.ranges[r]; + var first = rg.range[0]; + var last = rg.range[1]; + var td1 = $('#grid_'+ this.name +'_rec_'+ first.recid + ' td[col='+ first.column +']'); + var td2 = $('#grid_'+ this.name +'_rec_'+ last.recid + ' td[col='+ last.column +']'); + if ($('#grid_'+ this.name +'_'+ rg.name).length == 0) { + rec.append('
      '+ + (rg.name == 'selection' ? '
      ' : '')+ + '
      '); + } else { + $('#grid_'+ this.name +'_'+ rg.name).attr('style', rg.style); + } + if (td1.length > 0 && td2.length > 0) { + $('#grid_'+ this.name +'_'+ rg.name).css({ + left : (td1.position().left - 1 + rec.scrollLeft()) + 'px', + top : (td1.position().top - 1 + rec.scrollTop()) + 'px', + width : (td2.position().left - td1.position().left + td2.width() + 3) + 'px', + height : (td2.position().top - td1.position().top + td2.height() + 3) + 'px' + }); + } + } + + // add resizer events + $(this.box).find('#grid_'+ this.name +'_resizer').off('mousedown').on('mousedown', mouseStart); + //$(this.box).find('#grid_'+ this.name +'_resizer').off('selectstart').on('selectstart', function () { return false; }); // fixes chrome cursror bug + + var eventData = { phase: 'before', type: 'selectionExtend', target: obj.name, originalRange: null, newRange: null }; + + function mouseStart (event) { + var sel = obj.getSelection(); + obj.last.move = { + type : 'expand', + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + recid : sel[0].recid, + column : sel[0].column, + originalRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }], + newRange : [{ recid: sel[0].recid, column: sel[0].column }, { recid: sel[sel.length-1].recid, column: sel[sel.length-1].column }] + }; + $(document).off('mousemove', mouseMove).on('mousemove', mouseMove); + $(document).off('mouseup', mouseStop).on('mouseup', mouseStop); + } + + function mouseMove (event) { + var mv = obj.last.move; + if (!mv || mv.type != 'expand') return; + mv.divX = (event.screenX - mv.x); + mv.divY = (event.screenY - mv.y); + // find new cell + var recid, column; + var tmp = event.originalEvent.target; + if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; + if (typeof $(tmp).attr('col') != 'undefined') column = parseInt($(tmp).attr('col')); + tmp = $(tmp).parents('tr')[0]; + recid = $(tmp).attr('recid'); + // new range + if (mv.newRange[1].recid == recid && mv.newRange[1].column == column) return; + var prevNewRange = $.extend({}, mv.newRange); + mv.newRange = [{ recid: mv.recid, column: mv.column }, { recid: recid, column: column }]; + // event before + eventData = obj.trigger($.extend(eventData, { originalRange: mv.originalRange, newRange : mv.newRange })); + if (eventData.isCancelled === true) { + mv.newRange = prevNewRange; + eventData.newRange = prevNewRange; + return; + } else { + // default behavior + obj.removeRange('grid-selection-expand'); + obj.addRange({ + name : 'grid-selection-expand', + range : eventData.newRange, + style : 'background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);' + }); + } + } + + function mouseStop (event) { + // default behavior + obj.removeRange('grid-selection-expand'); + delete obj.last.move; + $(document).off('mousemove', mouseMove); + $(document).off('mouseup', mouseStop); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + + return (new Date()).getTime() - time; + }, + + select: function () { + var selected = 0; + var sel = this.last.selection; + if (!this.multiSelect) this.selectNone(); + for (var a = 0; a < arguments.length; a++) { + var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; + var record = this.get(recid); + if (record == null) continue; + var index = this.get(recid, true); + var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) >= 0) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, recid: recid, index: index }); + if (eventData.isCancelled === true) continue; + // default action + sel.indexes.push(index); + sel.indexes.sort(function(a, b) { return a-b }); + recEl.addClass('w2ui-selected').data('selected', 'yes'); + recEl.find('.w2ui-grid-select-check').prop("checked", true); + selected++; + } else { + var col = arguments[a].column; + if (!w2utils.isInt(col)) { // select all columns + var cols = []; + for (var c in this.columns) { if (this.columns[c].hidden) continue; cols.push({ recid: recid, column: parseInt(c) }); } + if (!this.multiSelect) cols = cols.splice(0, 1); + return this.select.apply(this, cols); + } + var s = sel.columns[index] || []; + if ($.isArray(s) && s.indexOf(col) != -1) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, recid: recid, index: index, column: col }); + if (eventData.isCancelled === true) continue; + // default action + if (sel.indexes.indexOf(index) == -1) { + sel.indexes.push(index); + sel.indexes.sort(function(a, b) { return a-b }); + } + s.push(col); + s.sort(function(a, b) { return a-b }); // sort function must be for numerical sort + recEl.find(' > td[col='+ col +']').addClass('w2ui-selected'); + selected++; + recEl.data('selected', 'yes'); + recEl.find('.w2ui-grid-select-check').prop("checked", true); + // save back to selection object + sel.columns[index] = s; + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + // all selected? + if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { + $('#grid_'+ this.name +'_check_all').prop('checked', true); + } else { + $('#grid_'+ this.name +'_check_all').prop('checked', false); + } + this.status(); + this.addRange('selection'); + return selected; + }, + + unselect: function () { + var unselected = 0; + var sel = this.last.selection; + for (var a = 0; a < arguments.length; a++) { + var recid = typeof arguments[a] == 'object' ? arguments[a].recid : arguments[a]; + var record = this.get(recid); + if (record == null) continue; + var index = this.get(record.recid, true); + var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) == -1) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, index: index }); + if (eventData.isCancelled === true) continue; + // default action + sel.indexes.splice(sel.indexes.indexOf(index), 1); + recEl.removeClass('w2ui-selected').removeData('selected'); + if (recEl.length != 0) recEl[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl.attr('custom_style'); + recEl.find('.w2ui-grid-select-check').prop("checked", false); + unselected++; + } else { + var col = arguments[a].column; + if (!w2utils.isInt(col)) { // unselect all columns + var cols = []; + for (var c in this.columns) { if (this.columns[c].hidden) continue; cols.push({ recid: recid, column: parseInt(c) }); } + return this.unselect.apply(this, cols); + } + var s = sel.columns[index]; + if (!$.isArray(s) || s.indexOf(col) == -1) continue; + // event before + var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, recid: recid, column: col }); + if (eventData.isCancelled === true) continue; + // default action + s.splice(s.indexOf(col), 1); + $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid) + ' > td[col='+ col +']').removeClass('w2ui-selected'); + unselected++; + if (s.length == 0) { + delete sel.columns[index]; + sel.indexes.splice(sel.indexes.indexOf(index), 1); + recEl.removeData('selected'); + recEl.find('.w2ui-grid-select-check').prop("checked", false); + } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + // all selected? + if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { + $('#grid_'+ this.name +'_check_all').prop('checked', true); + } else { + $('#grid_'+ this.name +'_check_all').prop('checked', false); + } + // show number of selected + this.status(); + this.addRange('selection'); + return unselected; + }, + + selectAll: function () { + if (this.multiSelect === false) return; + // event before + var eventData = this.trigger({ phase: 'before', type: 'select', target: this.name, all: true }); + if (eventData.isCancelled === true) return; + // default action + var url = (typeof this.url != 'object' ? this.url : this.url.get); + var sel = this.last.selection; + var cols = []; + for (var c in this.columns) cols.push(parseInt(c)); + // if local data source and searched + sel.indexes = []; + if (!url && this.searchData.length !== 0) { + // local search applied + for (var i = 0; i < this.last.searchIds.length; i++) { + sel.indexes.push(this.last.searchIds[i]); + if (this.selectType != 'row') sel.columns[this.last.searchIds[i]] = cols.slice(); // .slice makes copy of the array + } + } else { + for (var i = 0; i < this.records.length; i++) { + sel.indexes.push(i); + if (this.selectType != 'row') sel.columns[i] = cols.slice(); // .slice makes copy of the array + } + } + this.refresh(); + // enable/disable toolbar buttons + var sel = this.getSelection(); + if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); + if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); + this.addRange('selection'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + selectNone: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'unselect', target: this.name, all: true }); + if (eventData.isCancelled === true) return; + // default action + var sel = this.last.selection; + for (var s in sel.indexes) { + var index = sel.indexes[s]; + var rec = this.records[index]; + var recid = rec ? rec.recid : null; + var recEl = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + recEl.removeClass('w2ui-selected').removeData('selected'); + recEl.find('.w2ui-grid-select-check').prop("checked", false); + // for not rows + if (this.selectType != 'row') { + var cols = sel.columns[index]; + for (var c in cols) recEl.find(' > td[col='+ cols[c] +']').removeClass('w2ui-selected'); + } + } + sel.indexes = []; + sel.columns = {}; + this.toolbar.disable('w2ui-edit', 'w2ui-delete'); + this.removeRange('selection'); + $('#grid_'+ this.name +'_check_all').prop('checked', false); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + getSelection: function (returnIndex) { + var ret = []; + var sel = this.last.selection; + if (this.selectType == 'row') { + for (var s in sel.indexes) { + if (!this.records[sel.indexes[s]]) continue; + if (returnIndex === true) ret.push(sel.indexes[s]); else ret.push(this.records[sel.indexes[s]].recid); + } + return ret; + } else { + for (var s in sel.indexes) { + var cols = sel.columns[sel.indexes[s]]; + if (!this.records[sel.indexes[s]]) continue; + for (var c in cols) { + ret.push({ recid: this.records[sel.indexes[s]].recid, index: parseInt(sel.indexes[s]), column: cols[c] }); + } + } + return ret; + } + }, + + search: function (field, value) { + var obj = this; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + var searchData = []; + var last_multi = this.last.multi; + var last_logic = this.last.logic; + var last_field = this.last.field; + var last_search = this.last.search; + // 1: search() - advanced search (reads from popup) + if (arguments.length == 0) { + last_search = ''; + // advanced search + for (var s in this.searches) { + var search = this.searches[s]; + var operator = $('#grid_'+ this.name + '_operator_'+s).val(); + var field1 = $('#grid_'+ this.name + '_field_'+s); + var field2 = $('#grid_'+ this.name + '_field2_'+s); + var value1 = field1.val(); + var value2 = field2.val(); + var svalue = null; + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + var fld1 = field1.data('w2field'); + var fld2 = field2.data('w2field'); + if (fld1) value1 = fld1.clean(value1); + if (fld2) value2 = fld2.clean(value2); + } + if (['list', 'enum'].indexOf(search.type) != -1) { + value1 = field1.data('selected') || {}; + if ($.isArray(value1)) { + svalue = []; + for (var v in value1) { + svalue.push(w2utils.isFloat(value1[v].id) ? parseFloat(value1[v].id) : String(value1[v].id).toLowerCase()); + delete value1[v].hidden; + } + } else { + value1 = value1.id || ''; + } + } + if ((value1 != '' && value1 != null) || (typeof value2 != 'undefined' && value2 != '')) { + var tmp = { + field : search.field, + type : search.type, + operator : operator + } + if (operator == 'between') { + $.extend(tmp, { value: [value1, value2] }); + } else if (operator == 'in' && typeof value1 == 'string') { + $.extend(tmp, { value: value1.split(',') }); + } else { + $.extend(tmp, { value: value1 }); + } + if (svalue) $.extend(tmp, { svalue: svalue }); + // conver date to unix time + try { + if (search.type == 'date' && operator == 'between') { + tmp.value[0] = value1; // w2utils.isDate(value1, w2utils.settings.date_format, true).getTime(); + tmp.value[1] = value2; // w2utils.isDate(value2, w2utils.settings.date_format, true).getTime(); + } + if (search.type == 'date' && operator == 'is') { + tmp.value = value1; // w2utils.isDate(value1, w2utils.settings.date_format, true).getTime(); + } + } catch (e) { + + } + searchData.push(tmp); + } + } + if (searchData.length > 0 && !url) { + last_multi = true; + last_logic = 'AND'; + } else { + last_multi = true; + last_logic = 'AND'; + } + } + // 2: search(field, value) - regular search + if (typeof field == 'string') { + last_field = field; + last_search = value; + last_multi = false; + last_logic = 'OR'; + // loop through all searches and see if it applies + if (typeof value != 'undefined') { + if (field.toLowerCase() == 'all') { + // if there are search fields loop thru them + if (this.searches.length > 0) { + for (var s in this.searches) { + var search = this.searches[s]; + if (search.type == 'text' || (search.type == 'alphanumeric' && w2utils.isAlphaNumeric(value)) + || (search.type == 'int' && w2utils.isInt(value)) || (search.type == 'float' && w2utils.isFloat(value)) + || (search.type == 'percent' && w2utils.isFloat(value)) || (search.type == 'hex' && w2utils.isHex(value)) + || (search.type == 'currency' && w2utils.isMoney(value)) || (search.type == 'money' && w2utils.isMoney(value)) + || (search.type == 'date' && w2utils.isDate(value)) ) { + var tmp = { + field : search.field, + type : search.type, + operator : (search.type == 'text' ? 'contains' : 'is'), + value : value + }; + searchData.push(tmp); + } + // range in global search box + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1 && String(value).indexOf('-') != -1) { + var t = String(value).split('-'); + var tmp = { + field : search.field, + type : search.type, + operator : 'between', + value : [t[0], t[1]] + }; + searchData.push(tmp); + } + } + } else { + // no search fields, loop thru columns + for (var c in this.columns) { + var tmp = { + field : this.columns[c].field, + type : 'text', + operator : 'contains', + value : value + }; + searchData.push(tmp); + } + } + } else { + var el = $('#grid_'+ this.name +'_search_all'); + var search = this.getSearch(field); + if (search == null) search = { field: field, type: 'text' }; + if (search.field == field) this.last.caption = search.caption; + if (search.type == 'list') { + var tmp = el.data('selected'); + if (tmp && !$.isEmptyObject(tmp)) value = tmp.id; + } + if (value != '') { + var op = 'contains'; + var val = value; + if (w2utils.isInt(value)) op = 'is'; + if (['date', 'time'].indexOf(search.type) != -1) op = 'is'; + if (search.type == 'int' && value != '') { + if (String(value).indexOf('-') != -1) { + var tmp = value.split('-'); + if (tmp.length == 2) { + op = 'between'; + val = [parseInt(tmp[0]), parseInt(tmp[1])]; + } + } + if (String(value).indexOf(',') != -1) { + var tmp = value.split(','); + op = 'in'; + val = []; + for (var t in tmp) val.push(tmp[t]); + } + } + var tmp = { + field : search.field, + type : search.type, + operator : op, + value : val + } + searchData.push(tmp); + } + } + } + } + // 3: search([ { field, value, [operator,] [type] }, { field, value, [operator,] [type] } ], logic) - submit whole structure + if ($.isArray(field)) { + var logic = 'AND'; + if (typeof value == 'string') { + logic = value.toUpperCase(); + if (logic != 'OR' && logic != 'AND') logic = 'AND'; + } + last_search = ''; + last_multi = true; + last_logic = logic; + for (var f in field) { + var data = field[f]; + var search = this.getSearch(data.field); + if (search == null) search = { type: 'text', operator: 'contains' }; + // merge current field and search if any + searchData.push($.extend(true, {}, search, data)); + } + } + // event before + var eventData = this.trigger({ phase: 'before', type: 'search', target: this.name, searchData: searchData, + searchField: (field ? field : 'multi'), searchValue: (value ? value : 'multi') }); + if (eventData.isCancelled === true) return; + // default action + this.searchData = eventData.searchData; + this.last.field = last_field; + this.last.search = last_search; + this.last.multi = last_multi; + this.last.logic = last_logic; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + // -- clear all search field + this.searchClose(); + this.set({ expanded: false }, true); + // apply search + if (url) { + this.last.xhr_offset = 0; + this.reload(); + } else { + // local search + this.localSearch(); + this.refresh(); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + searchOpen: function () { + if (!this.box) return; + if (this.searches.length == 0) return; + var obj = this; + // show search + $('#tb_'+ this.name +'_toolbar_item_w2ui-search-advanced').w2overlay( + this.getSearchesHTML(), { + name : 'searches-'+ this.name, + left : -10, + 'class' : 'w2ui-grid-searches', + onShow : function () { + if (obj.last.logic == 'OR') obj.searchData = []; + obj.initSearches(); + $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches').data('grid-name', obj.name); + var sfields = $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches *[rel=search]'); + if (sfields.length > 0) sfields[0].focus(); + } + } + ); + }, + + searchClose: function () { + if (!this.box) return; + if (this.searches.length == 0) return; + if (this.toolbar) this.toolbar.uncheck('w2ui-search-advanced') + // hide search + if ($('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches').length > 0) { + $().w2overlay('', { name: 'searches-'+ this.name }); + } + }, + + searchShowFields: function () { + var el = $('#grid_'+ this.name +'_search_all'); + var html = '
      '; + for (var s = -1; s < this.searches.length; s++) { + var search = this.searches[s]; + if (s == -1) { + if (!this.multiSearch) continue; + search = { field: 'all', caption: w2utils.lang('All Fields') }; + } else { + if (this.searches[s].hidden === true) continue; + } + html += ''+ + ' '+ + ' '+ + ''; + } + html += "
      '+ search.caption +'
      "; + // need timer otherwise does nto show with list type + setTimeout(function () { + $(el).w2overlay(html, { left: -10 }); + }, 1); + }, + + initAllField: function (field, value) { + var el = $('#grid_'+ this.name +'_search_all'); + var search = this.getSearch(field); + if (field == 'all') { + search = { field: 'all', caption: w2utils.lang('All Fields') }; + el.w2field('clear'); + el.change().focus(); + } else { + var st = search.type; + if (['enum', 'select'].indexOf(st) != -1) st = 'list'; + el.w2field(st, $.extend({}, search.options, { suffix: '', autoFormat: false, selected: value })); + if (['list', 'enum'].indexOf(search.type) != -1) { + this.last.search = ''; + this.last.item = ''; + el.val(''); + } + // set focus + setTimeout(function () { + el.focus(); /* do not do el.change() as it will refresh grid and pull from server */ + }, 1); + } + // update field + if (this.last.search != '') { + this.search(search.field, this.last.search); + } else { + this.last.field = search.field; + this.last.caption = search.caption; + } + el.attr('placeholder', search.caption); + $().w2overlay(); + }, + + searchReset: function (noRefresh) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'search', target: this.name, searchData: [] }); + if (eventData.isCancelled === true) return; + // default action + this.searchData = []; + this.last.search = ''; + this.last.logic = 'OR'; + // --- do not reset to All Fields (I think) + // if (this.last.multi) { + // if (!this.multiSearch) { + // this.last.field = this.searches[0].field; + // this.last.caption = this.searches[0].caption; + // } else { + // this.last.field = 'all'; + // this.last.caption = w2utils.lang('All Fields'); + // } + // } + this.last.multi = false; + this.last.xhr_offset = 0; + // reset scrolling position + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + // -- clear all search field + this.searchClose(); + $('#grid_'+ this.name +'_search_all').val(''); + // apply search + if (!noRefresh) this.reload(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + clear: function (noRefresh) { + this.offset = 0; + this.total = 0; + this.buffered = 0; + this.records = []; + this.summary = []; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.range_start = null; + this.last.range_end = null; + this.last.xhr_offset = 0; + if (!noRefresh) this.refresh(); + }, + + reset: function (noRefresh) { + // reset last remembered state + this.offset = 0; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.selection.indexes = []; + this.last.selection.columns = {}; + this.last.range_start = null; + this.last.range_end = null; + this.last.xhr_offset = 0; + this.searchReset(noRefresh); + // initial sort + if (this.last.sortData != null ) this.sortData = this.last.sortData; + // select none without refresh + this.set({ expanded: false }, true); + // refresh + if (!noRefresh) this.refresh(); + }, + + skip: function (offset) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + this.offset = parseInt(offset); + if (this.offset < 0 || !w2utils.isInt(this.offset)) this.offset = 0; + if (this.offset > this.total) this.offset = this.total - this.limit; + this.records = []; + this.buffered = 0; + this.last.xhr_offset = 0; + this.last.pull_more = true; + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + $('#grid_'+ this.name +'_records').prop('scrollTop', 0); + this.initColumnOnOff(); + this.reload(); + } else { + console.log('ERROR: grid.skip() can only be called when you have remote data source.'); + } + }, + + load: function (url, callBack) { + if (typeof url == 'undefined') { + console.log('ERROR: You need to provide url argument when calling .load() method of "'+ this.name +'" object.'); + return; + } + // default action + this.request('get-records', {}, url, callBack); + }, + + reload: function (callBack) { + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + this.clear(true); + this.request('get-records', {}, null, callBack); + } else { + this.last.scrollTop = 0; + this.last.scrollLeft = 0; + this.last.range_start = null; + this.last.range_end = null; + this.localSearch(); + this.refresh(); + if (typeof callBack == 'function') callBack({ status: 'success' }); + } + }, + + request: function (cmd, add_params, url, callBack) { + if (typeof add_params == 'undefined') add_params = {}; + if (typeof url == 'undefined' || url == '' || url == null) url = this.url; + if (url == '' || url == null) return; + // build parameters list + var params = {}; + if (!w2utils.isInt(this.offset)) this.offset = 0; + if (!w2utils.isInt(this.last.xhr_offset)) this.last.xhr_offset = 0; + // add list params + params['cmd'] = cmd; + params['selected'] = this.getSelection(); + params['limit'] = this.limit; + params['offset'] = parseInt(this.offset) + this.last.xhr_offset; + params['search'] = this.searchData; + params['searchLogic'] = this.last.logic; + params['sort'] = (this.sortData.length != 0 ? this.sortData : ''); + // append other params + $.extend(params, this.postData); + $.extend(params, add_params); + // event before + if (cmd == 'get-records') { + var eventData = this.trigger({ phase: 'before', type: 'request', target: this.name, url: url, postData: params }); + if (eventData.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } + } else { + var eventData = { url: url, postData: params }; + } + // call server to get data + var obj = this; + if (this.last.xhr_offset == 0) { + this.lock(this.msgRefresh, true); + } else { + var more = $('#grid_'+ this.name +'_rec_more'); + if (this.autoLoad === true) { + more.show().find('td').html('
      '); + } else { + more.find('td').html('
      '+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
      '); + } + } + if (this.last.xhr) try { this.last.xhr.abort(); } catch (e) {}; + var xhr_type = 'GET'; + var url = (typeof eventData.url != 'object' ? eventData.url : eventData.url.get); + if (params.cmd == 'save-records') { + if (typeof eventData.url == 'object') url = eventData.url.save; + xhr_type = 'PUT'; // so far it is always update + } + if (params.cmd == 'delete-records') { + if (typeof eventData.url == 'object') url = eventData.url.remove; + xhr_type = 'DELETE'; + } + if (!w2utils.settings.RESTfull) xhr_type = 'POST'; + if (this.method) xhr_type = this.method; + this.last.xhr_cmd = params.cmd; + this.last.xhr_start = (new Date()).getTime(); + this.last.xhr = $.ajax({ + type : xhr_type, + url : url, + data : (typeof eventData.postData == 'object' ? String($.param(eventData.postData, false)).replace(/%5B/g, '[').replace(/%5D/g, ']') : eventData.postData), + dataType : 'text', + complete : function (xhr, status) { + obj.requestComplete(status, cmd, callBack); + } + }); + if (cmd == 'get-records') { + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + }, + + requestComplete: function(status, cmd, callBack) { + var obj = this; + this.unlock(); + setTimeout(function () { obj.status(w2utils.lang('Server Response') + ' ' + ((new Date()).getTime() - obj.last.xhr_start)/1000 +' ' + w2utils.lang('sec')); }, 10); + this.last.pull_more = false; + this.last.pull_refresh = true; + + // event before + var event_name = 'load'; + if (this.last.xhr_cmd == 'save-records') event_name = 'save'; + if (this.last.xhr_cmd == 'delete-records') event_name = 'deleted'; + var eventData = this.trigger({ phase: 'before', target: this.name, type: event_name, xhr: this.last.xhr, status: status }); + if (eventData.isCancelled === true) { + if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); + return; + } + // parse server response + var data; + var responseText = this.last.xhr.responseText; + if (status != 'error') { + // default action + if (typeof responseText != 'undefined' && responseText != '') { + // check if the onLoad handler has not already parsed the data + if (typeof responseText == "object") { + data = responseText; + } else { + if (typeof obj.parser == 'function') { + data = obj.parser(responseText); + if (typeof data != 'object') { + console.log('ERROR: Your parser did not return proper object'); + } + } else { + // $.parseJSON or $.getJSON did not work because those expect perfect JSON data - where everything is in double quotes + // + // TODO: avoid (potentially malicious) code injection from the response. + try { eval('data = '+ responseText); } catch (e) { } + } + } + // convert recids + if (obj.recid) { + for (var r in data.records) { + data.records[r]['recid'] = data.records[r][obj.recid]; + } + } + if (typeof data == 'undefined') { + data = { + status : 'error', + message : this.msgNotJSON, + responseText : responseText + }; + } + if (data['status'] == 'error') { + obj.error(data['message']); + } else { + if (cmd == 'get-records') { + if (this.last.xhr_offset == 0) { + this.records = []; + this.summary = []; + //data.xhr_status=data.status; + delete data.status; + $.extend(true, this, data); + this.buffered = this.records.length; + } else { + var records = data.records; + delete data.records; + //data.xhr_status=data.status; + delete data.status; + $.extend(true, this, data); + for (var r in records) { + this.records.push(records[r]); + } + this.buffered = this.records.length; + } + } + if (cmd == 'delete-records') { + this.reset(); // unselect old selections + this.reload(); + return; + } + } + } + } else { + data = { + status : 'error', + message : this.msgAJAXerror, + responseText : responseText + }; + obj.error(this.msgAJAXerror); + } + // event after + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(); + this.localSearch(); + } + this.total = parseInt(this.total); + this.trigger($.extend(eventData, { phase: 'after' })); + // do not refresh if loading on infinite scroll + if (this.last.xhr_offset == 0) this.refresh(); else this.scroll(); + // call back + if (typeof callBack == 'function') callBack(data); + }, + + error: function (msg) { + var obj = this; + // let the management of the error outside of the grid + var eventData = this.trigger({ target: this.name, type: 'error', message: msg , xhr: this.last.xhr }); + if (eventData.isCancelled === true) { + if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); + return; + } + w2alert(msg, 'Error'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + getChanges: function () { + var changes = []; + for (var r in this.records) { + var rec = this.records[r]; + if (typeof rec['changes'] != 'undefined') { + changes.push($.extend(true, { recid: rec.recid }, rec.changes)); + } + } + return changes; + }, + + mergeChanges: function () { + var changes = this.getChanges(); + for (var c in changes) { + var record = this.get(changes[c].recid); + for (var s in changes[c]) { + if (s == 'recid') continue; // do not allow to change recid + try { eval('record.' + s + ' = changes[c][s]'); } catch (e) {} + delete record.changes; + } + } + this.refresh(); + }, + + // =================================================== + // -- Action Handlers + + save: function () { + var obj = this; + var changes = this.getChanges(); + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'submit', changes: changes }); + if (eventData.isCancelled === true) return; + var url = (typeof this.url != 'object' ? this.url : this.url.save); + if (url) { + this.request('save-records', { 'changes' : eventData.changes }, null, + function (data) { + if (data.status !== 'error') { + // only merge changes, if save was successful + obj.mergeChanges(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + ); + } else { + this.mergeChanges(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + }, + + editField: function (recid, column, value, event) { + var obj = this; + var index = obj.get(recid, true); + var rec = obj.records[index]; + var col = obj.columns[column]; + var edit = col ? col.editable : null; + if (!rec || !col || !edit || rec.editable === false) return; + if (['enum', 'file'].indexOf(edit.type) != -1) { + console.log('ERROR: input types "enum" and "file" are not supported in inline editing.'); + return; + } + // event before + var eventData = obj.trigger({ phase: 'before', type: 'editField', target: obj.name, recid: recid, column: column, value: value, + index: index, originalEvent: event }); + if (eventData.isCancelled === true) return; + value = eventData.value; + // default behaviour + this.selectNone(); + this.select({ recid: recid, column: column }); + this.last.edit_col = column; + if (['checkbox', 'check'].indexOf(edit.type) != -1) return; + // create input element + var tr = $('#grid_'+ obj.name +'_rec_'+ w2utils.escapeId(recid)); + var el = tr.find('[col='+ column +'] > div'); + if (typeof edit.inTag == 'undefined') edit.inTag = ''; + if (typeof edit.outTag == 'undefined') edit.outTag = ''; + if (typeof edit.style == 'undefined') edit.style = ''; + if (typeof edit.items == 'undefined') edit.items = []; + var val = (rec.changes && typeof rec.changes[col.field] != 'undefined' ? w2utils.stripTags(rec.changes[col.field]) : w2utils.stripTags(rec[col.field])); + if (val == null || typeof val == 'undefined') val = ''; + if (typeof value != 'undefined' && value != null) val = value; + var addStyle = (typeof col.style != 'undefined' ? col.style + ';' : ''); + if (typeof col.render == 'string' && ['number', 'int', 'float', 'money', 'percent'].indexOf(col.render.split(':')[0]) != -1) { + addStyle += 'text-align: right;'; + } + if (edit.type == 'select') { + var html = ''; + for (var i in edit.items) { + html += ''; + } + el.addClass('w2ui-editable') + .html('' + edit.outTag); + el.find('select').focus() + .on('change', function (event) { + delete obj.last.move; + }) + .on('blur', function (event) { + obj.editChange.call(obj, this, index, column, event); + }); + } else { + el.addClass('w2ui-editable') + .html('' + edit.outTag); + if (value == null) el.find('input').val(val != 'object' ? val : ''); + // init w2field + var input = el.find('input').get(0); + $(input).w2field(edit.type, $.extend(edit, { selected: val })) + // add blur listener + setTimeout(function () { + var tmp = input; + if (edit.type == 'list') { + tmp = $($(input).data('w2field').helpers.focus).find('input'); + if (val != 'object' && val != '') tmp.val(val).css({ opacity: 1 }).prev().css({ opacity: 1 }); + } + $(tmp).on('blur', function (event) { + obj.editChange.call(obj, input, index, column, event); + }); + }, 10); + if (value != null) $(input).val(val != 'object' ? val : ''); + } + setTimeout(function () { + el.find('input, select') + .on('click', function (event) { + event.stopPropagation(); + }) + .on('keydown', function (event) { + var cancel = false; + switch (event.keyCode) { + case 9: // tab + cancel = true; + var next_rec = recid; + var next_col = event.shiftKey ? obj.prevCell(column, true) : obj.nextCell(column, true); + // next or prev row + if (next_col === false) { + var tmp = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); + if (tmp != null && tmp != index) { + next_rec = obj.records[tmp].recid; + // find first editable row + for (var c in obj.columns) { + var tmp = obj.columns[c].editable; + if (typeof tmp != 'undefined' && ['checkbox', 'check'].indexOf(tmp.type) == -1) { + next_col = parseInt(c); + if (!event.shiftKey) break; + } + } + } + + } + if (next_rec === false) next_rec = recid; + if (next_col === false) next_col = column; + // init new or same record + this.blur(); + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: next_rec, column: next_col }); + } else { + obj.editField(next_rec, next_col, null, event); + } + }, 1); + break; + + case 13: // enter + this.blur(); + var next = event.shiftKey ? obj.prevRow(index) : obj.nextRow(index); + if (next != null && next != index) { + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: obj.records[next].recid, column: column }); + } else { + obj.editField(obj.records[next].recid, column, null, event); + } + }, 100); + } + break; + + case 38: // up arrow + if (!event.shiftKey) break; + cancel = true; + var next = obj.prevRow(index); + if (next != index) { + this.blur(); + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: obj.records[next].recid, column: column }); + } else { + obj.editField(obj.records[next].recid, column, null, event); + } + }, 1); + } + break; + + case 40: // down arrow + if (!event.shiftKey) break; + cancel = true; + var next = obj.nextRow(index); + if (next != null && next != index) { + this.blur(); + setTimeout(function () { + if (obj.selectType != 'row') { + obj.selectNone(); + obj.select({ recid: obj.records[next].recid, column: column }); + } else { + obj.editField(obj.records[next].recid, column, null, event); + } + }, 1); + } + break; + + case 27: // escape + var old = obj.parseField(rec, col.field); + if (rec.changes && typeof rec.changes[col.field] != 'undefined') old = rec.changes[col.field]; + this.value = typeof old != 'undefined' ? old : ''; + this.blur(); + setTimeout(function () { obj.select({ recid: recid, column: column }) }, 1); + break; + } + if (cancel) if (event.preventDefault) event.preventDefault(); + }); + // focus and select + var tmp = el.find('input').focus(); + if (value != null) { + // set cursor to the end + tmp[0].setSelectionRange(tmp.val().length, tmp.val().length); + } else { + tmp.select(); + } + + }, 1); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + editChange: function (el, index, column, event) { + // all other fields + var summary = index < 0; + index = index < 0 ? -index - 1 : index; + var records = summary ? this.summary : this.records; + var rec = records[index]; + var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(rec.recid)); + var col = this.columns[column]; + var new_val = el.value; + var old_val = this.parseField(rec, col.field); + var tmp = $(el).data('w2field'); + if (tmp) { + new_val = tmp.clean(new_val); + if (tmp.type == 'list' && new_val != '') new_val = $(el).data('selected'); + } + if (el.type == 'checkbox') new_val = el.checked; + // change/restore event + var eventData = { + phase: 'before', type: 'change', target: this.name, input_id: el.id, recid: rec.recid, index: index, column: column, + value_new: new_val, value_previous: (rec.changes && rec.changes.hasOwnProperty(col.field) ? rec.changes[col.field]: old_val), value_original: old_val + }; + while (true) { + new_val = eventData.value_new; + if (( typeof old_val == 'undefined' || old_val === null ? '' : String(old_val)) !== String(new_val)) { + // change event + eventData = this.trigger($.extend(eventData, { type: 'change', phase: 'before' })); + if (eventData.isCancelled !== true) { + if (new_val !== eventData.value_new) { + // re-evaluate the type of change to be made + continue; + } + // default action + rec.changes = rec.changes || {}; + rec.changes[col.field] = eventData.value_new; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + } else { + // restore event + eventData = this.trigger($.extend(eventData, { type: 'restore', phase: 'before' })); + if (eventData.isCancelled !== true) { + if (new_val !== eventData.value_new) { + // re-evaluate the type of change to be made + continue; + } + // default action + if (rec.changes) delete rec.changes[col.field]; + if ($.isEmptyObject(rec.changes)) delete rec.changes; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + } + break; + } + // refresh cell + var cell = this.getCellHTML(index, column, summary); + if (!summary) { + if (rec.changes && typeof rec.changes[col.field] != 'undefined') { + $(tr).find('[col='+ column +']').addClass('w2ui-changed').html(cell); + } else { + $(tr).find('[col='+ column +']').removeClass('w2ui-changed').html(cell); + } + } + }, + + delete: function (force) { + var obj = this; + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'delete', force: force }); + if (eventData.isCancelled === true) return; + force = eventData.force; + // default action + var recs = this.getSelection(); + if (recs.length == 0) return; + if (this.msgDelete != '' && !force) { + w2confirm({ + title : w2utils.lang('Delete Confirmation'), + msg : obj.msgDelete, + callBack: function (result) { + console.log('result', result); + if (result == 'Yes') w2ui[obj.name].delete(true); + } + }); + return; + } + // call delete script + var url = (typeof this.url != 'object' ? this.url : this.url.remove); + if (url) { + this.request('delete-records'); + } else { + this.selectNone(); + if (typeof recs[0] != 'object') { + this.remove.apply(this, recs); + } else { + // clear cells + for (var r in recs) { + var fld = this.columns[recs[r].column].field; + var ind = this.get(recs[r].recid, true); + if (ind != null && fld != 'recid') { + this.records[ind][fld] = ''; + if (this.records[ind].changes) delete this.records[ind].changes[fld]; + } + } + this.refresh(); + } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + click: function (recid, event) { + var time = (new Date()).getTime(); + var column = null; + if (this.last.cancelClick == true) return; + if (typeof recid == 'object') { + column = recid.column; + recid = recid.recid; + } + if (typeof event == 'undefined') event = {}; + // check for double click + if (time - parseInt(this.last.click_time) < 250 && event.type == 'click') { + this.dblClick(recid, event); + return; + } + this.last.click_time = time; + // column user clicked on + if (column == null && event.target) { + var tmp = event.target; + if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; + if (typeof $(tmp).attr('col') != 'undefined') column = parseInt($(tmp).attr('col')); + } + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'click', recid: recid, column: column, originalEvent: event }); + if (eventData.isCancelled === true) return; + // if it is subgrid unselect top grid + var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)).parents('tr'); + if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var grid = parent.parents('.w2ui-grid').attr('name'); + w2ui[grid].selectNone(); + // all subgrids + parent.parents('.w2ui-grid').find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { + var grid = $(el).attr('name'); + if (w2ui[grid]) w2ui[grid].selectNone(); + }); + } + // unselect all subgrids + $(this.box).find('.w2ui-expanded-row .w2ui-grid').each(function (index, el) { + var grid = $(el).attr('name'); + if (w2ui[grid]) w2ui[grid].selectNone(); + }); + // default action + var obj = this; + var sel = this.getSelection(); + $('#grid_'+ this.name +'_check_all').prop("checked", false); + var ind = this.get(recid, true); + var record = this.records[ind]; + var selectColumns = []; + obj.last.sel_ind = ind; + obj.last.sel_col = column; + obj.last.sel_recid = recid; + obj.last.sel_type = 'click'; + // multi select with shif key + if (event.shiftKey && sel.length > 0 && obj.multiSelect) { + if (sel[0].recid) { + var start = this.get(sel[0].recid, true); + var end = this.get(recid, true); + if (column > sel[0].column) { + var t1 = sel[0].column; + var t2 = column; + } else { + var t1 = column; + var t2 = sel[0].column; + } + for (var c = t1; c <= t2; c++) selectColumns.push(c); + } else { + var start = this.get(sel[0], true); + var end = this.get(recid, true); + } + var sel_add = [] + if (start > end) { var tmp = start; start = end; end = tmp; } + var url = (typeof this.url != 'object' ? this.url : this.url.get); + for (var i = start; i <= end; i++) { + if (this.searchData.length > 0 && !url && $.inArray(i, this.last.searchIds) == -1) continue; + if (this.selectType == 'row') { + sel_add.push(this.records[i].recid); + } else { + for (var sc in selectColumns) sel_add.push({ recid: this.records[i].recid, column: selectColumns[sc] }); + } + //sel.push(this.records[i].recid); + } + this.select.apply(this, sel_add); + } else { + var last = this.last.selection; + var flag = (last.indexes.indexOf(ind) != -1 ? true : false); + // clear other if necessary + if (((!event.ctrlKey && !event.shiftKey && !event.metaKey) || !this.multiSelect) && !this.showSelectColumn) { + if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; + if (sel.length > 300) this.selectNone(); else this.unselect.apply(this, sel); + if (flag === true) { + this.unselect({ recid: recid, column: column }); + } else { + this.select({ recid: recid, column: column }); + } + } else { + if (this.selectType != 'row' && $.inArray(column, last.columns[ind]) == -1) flag = false; + if (flag === true) { + this.unselect({ recid: recid, column: column }); + } else { + this.select({ recid: recid, column: column }); + } + } + } + this.status(); + obj.initResize(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + columnClick: function (field, event) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'columnClick', target: this.name, field: field, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behaviour + var column = this.getColumn(field); + if (column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false) ); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + keydown: function (event) { + // this method is called from w2utils + var obj = this; + if (obj.keyboard !== true) return; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behavior + var empty = false; + var records = $('#grid_'+ obj.name +'_records'); + var sel = obj.getSelection(); + if (sel.length == 0) empty = true; + var recid = sel[0] || null; + var columns = []; + var recid2 = sel[sel.length-1]; + if (typeof recid == 'object' && recid != null) { + recid = sel[0].recid; + columns = []; + var ii = 0; + while (true) { + if (!sel[ii] || sel[ii].recid != recid) break; + columns.push(sel[ii].column); + ii++; + } + recid2 = sel[sel.length-1].recid; + } + var ind = obj.get(recid, true); + var ind2 = obj.get(recid2, true); + var rec = obj.get(recid); + var recEL = $('#grid_'+ obj.name +'_rec_'+ (ind !== null ? w2utils.escapeId(obj.records[ind].recid) : 'none')); + var cancel = false; + var key = event.keyCode; + var shiftKey= event.shiftKey; + if (key == 9) { // tab key + if (event.shiftKey) key = 37; else key = 39; // replace with arrows + shiftKey = false; + cancel = true; + } + switch (key) { + case 8: // backspace + case 46: // delete + obj.delete(); + cancel = true; + event.stopPropagation(); + break; + + case 27: // escape + obj.selectNone(); + if (sel.length > 0 && typeof sel[0] == 'object') { + obj.select({ recid: sel[0].recid, column: sel[0].column }); + } + cancel = true; + break; + + case 65: // cmd + A + if (!event.metaKey && !event.ctrlKey) break; + obj.selectAll(); + cancel = true; + break; + + case 70: // cmd + F + if (!event.metaKey && !event.ctrlKey) break; + $('#grid_'+ obj.name + '_search_all').focus(); + cancel = true; + break; + + case 13: // enter + // if expandable columns - expand it + if (this.selectType == 'row' && obj.show.expandColumn === true) { + if (recEL.length <= 0) break; + obj.toggle(recid, event); + cancel = true; + } else { // or enter edit + for (var c in this.columns) { + if (this.columns[c].editable) { + columns.push(parseInt(c)); + break; + } + } + // edit last column that was edited + if (this.selectType == 'row' && this.last.edit_col) columns = [this.last.edit_col]; + if (columns.length > 0) { + obj.editField(recid, columns[0], null, event); + cancel = true; + } + } + break; + + case 37: // left + if (empty) break; + // check if this is subgrid + var parent = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind].recid)).parents('tr'); + if (parent.length > 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var recid = parent.prev().attr('recid'); + var grid = parent.parents('.w2ui-grid').attr('name'); + obj.selectNone(); + w2utils.keyboard.active(grid); + w2ui[grid].set(recid, { expanded: false }); + w2ui[grid].collapse(recid); + w2ui[grid].click(recid); + cancel = true; + break; + } + if (this.selectType == 'row') { + if (recEL.length <= 0 || rec.expanded !== true ) break; + obj.set(recid, { expanded: false }, true); + obj.collapse(recid, event); + } else { + var prev = obj.prevCell(columns[0]); + if (prev !== false) { + if (shiftKey && obj.multiSelect) { + if (tmpUnselect()) return; + var tmp = []; + var newSel = []; + var unSel = []; + if (columns.indexOf(this.last.sel_col) == 0 && columns.length > 1) { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + unSel.push({ recid: sel[i].recid, column: columns[columns.length-1] }); + } + } else { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + newSel.push({ recid: sel[i].recid, column: prev }); + } + } + obj.unselect.apply(obj, unSel); + obj.select.apply(obj, newSel); + } else { + event.shiftKey = false; + obj.click({ recid: recid, column: prev }, event); + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=1; s 1) { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + unSel.push({ recid: sel[i].recid, column: columns[0] }); + } + } else { + for (var i in sel) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid); + newSel.push({ recid: sel[i].recid, column: next }); + } + } + obj.unselect.apply(obj, unSel); + obj.select.apply(obj, newSel); + } else { + obj.click({ recid: recid, column: next }, event); + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=0; s 0 && w2ui[subgrid.attr('name')]) { + obj.selectNone(); + var grid = subgrid.attr('name'); + var recs = w2ui[grid].records; + w2utils.keyboard.active(grid); + w2ui[grid].click(recs[recs.length-1].recid); + cancel = true; + break; + } + } + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return; + if (obj.selectType == 'row') { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + obj.unselect(obj.records[ind2].recid); + } else { + obj.select(obj.records[prev].recid); + } + } else { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + prev = ind2; + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); + obj.unselect.apply(obj, tmp); + } else { + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }); + obj.select.apply(obj, tmp); + } + } + } else { // move selected record + obj.selectNone(); + obj.click({ recid: obj.records[prev].recid, column: columns[0] }, event); + } + obj.scrollIntoView(prev); + if (event.preventDefault) event.preventDefault(); + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=1; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var recid = parent.prev().attr('recid'); + var grid = parent.parents('.w2ui-grid').attr('name'); + obj.selectNone(); + w2utils.keyboard.active(grid); + w2ui[grid].click(recid); + cancel = true; + break; + } + } + break; + + case 40: // down + if (empty) selectTopRecord(); + if (recEL.length <= 0) break; + // jump into subgrid + if (obj.records[ind2].expanded) { + var subgrid = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(obj.records[ind2].recid) +'_expanded_row').find('.w2ui-grid'); + if (subgrid.length > 0 && w2ui[subgrid.attr('name')]) { + obj.selectNone(); + var grid = subgrid.attr('name'); + var recs = w2ui[grid].records; + w2utils.keyboard.active(grid); + w2ui[grid].click(recs[0].recid); + cancel = true; + break; + } + } + // move to the next record + var next = obj.nextRow(ind2); + if (next != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return; + if (obj.selectType == 'row') { + if (this.last.sel_ind < next && this.last.sel_ind != ind) { + obj.unselect(obj.records[ind].recid); + } else { + obj.select(obj.records[next].recid); + } + } else { + if (this.last.sel_ind < next && this.last.sel_ind != ind) { + next = ind; + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); + obj.unselect.apply(obj, tmp); + } else { + var tmp = []; + for (var c in columns) tmp.push({ recid: obj.records[next].recid, column: columns[c] }); + obj.select.apply(obj, tmp); + } + } + } else { // move selected record + obj.selectNone(); + obj.click({ recid: obj.records[next].recid, column: columns[0] }, event); + } + obj.scrollIntoView(next); + cancel = true; + } else { + // if selected more then one, then select first + if (!shiftKey) { + for (var s=0; s 0 && String(parent.attr('id')).indexOf('expanded_row') != -1) { + var recid = parent.next().attr('recid'); + var grid = parent.parents('.w2ui-grid').attr('name'); + obj.selectNone(); + w2utils.keyboard.active(grid); + w2ui[grid].click(recid); + cancel = true; + break; + } + } + break; + + case 86: // v - paste + if (empty) break; + if (event.ctrlKey || event.metaKey) { + $('body').append(''); + $('#_tmp_copy_data').focus(); + setTimeout(function () { + obj.paste($('#_tmp_copy_data').val()); + $('#_tmp_copy_data').remove(); + }, 50); // need timer to allow paste + } + break; + + case 88: // x - cut + if (empty) break; + if (event.ctrlKey || event.metaKey) { + setTimeout(function () { obj.delete(true); }, 100); + } + case 67: // c - copy + if (empty) break; + if (event.ctrlKey || event.metaKey) { + var text = obj.copy(); + $('body').append(''); + $('#_tmp_copy_data').focus().select(); + setTimeout(function () { $('#_tmp_copy_data').remove(); }, 50); + } + break; + } + var tmp = [187, 189, 32]; // =-spacebar + for (var i=48; i<=90; i++) tmp.push(i); // 0-9,a-z,A-Z + if (tmp.indexOf(key) != -1 && !event.ctrlKey && !event.metaKey && !cancel) { + if (columns.length == 0) columns.push(0); + var tmp = String.fromCharCode(key); + if (key == 187) tmp = '='; + if (key == 189) tmp = '-'; + if (!shiftKey) tmp = tmp.toLowerCase(); + obj.editField(recid, columns[0], tmp, event); + cancel = true; + } + if (cancel) { // cancel default behaviour + if (event.preventDefault) event.preventDefault(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + + function selectTopRecord() { + var ind = Math.floor((records[0].scrollTop + (records.height() / 2.1)) / obj.recordHeight); + if (!obj.records[ind]) ind = 0; + obj.select({ recid: obj.records[ind].recid, column: 0}); + } + + function tmpUnselect () { + if (obj.last.sel_type != 'click') return false; + if (obj.selectType != 'row') { + obj.last.sel_type = 'key'; + if (sel.length > 1) { + for (var s in sel) { + if (sel[s].recid == obj.last.sel_recid && sel[s].column == obj.last.sel_col) { + sel.splice(s, 1); + break; + } + } + obj.unselect.apply(obj, sel); + return true; + } + return false; + } else { + obj.last.sel_type = 'key'; + if (sel.length > 1) { + sel.splice(sel.indexOf(obj.records[obj.last.sel_ind].recid), 1); + obj.unselect.apply(obj, sel); + return true; + } + return false; + } + } + }, + + scrollIntoView: function (ind) { + if (typeof ind == 'undefined') { + var sel = this.getSelection(); + if (sel.length == 0) return; + ind = this.get(sel[0], true); + } + var records = $('#grid_'+ this.name +'_records'); + if (records.length == 0) return; + // if all records in view + var len = this.last.searchIds.length; + if (records.height() > this.recordHeight * (len > 0 ? len : this.records.length)) return; + if (len > 0) ind = this.last.searchIds.indexOf(ind); // if seach is applied + // scroll to correct one + var t1 = Math.floor(records[0].scrollTop / this.recordHeight); + var t2 = t1 + Math.floor(records.height() / this.recordHeight); + if (ind == t1) records.animate({ 'scrollTop': records.scrollTop() - records.height() / 1.3 }, 250, 'linear'); + if (ind == t2) records.animate({ 'scrollTop': records.scrollTop() + records.height() / 1.3 }, 250, 'linear'); + if (ind < t1 || ind > t2) records.animate({ 'scrollTop': (ind - 1) * this.recordHeight }); + }, + + dblClick: function (recid, event) { + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // find columns + var column = null; + if (typeof recid == 'object') { + column = recid.column; + recid = recid.recid; + } + if (typeof event == 'undefined') event = {}; + // column user clicked on + if (column == null && event.target) { + var tmp = event.target; + if (tmp.tagName != 'TD') tmp = $(tmp).parents('td')[0]; + column = parseInt($(tmp).attr('col')); + } + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'dblClick', recid: recid, column: column, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + this.selectNone(); + var col = this.columns[column]; + if (col && $.isPlainObject(col.editable)) { + this.editField(recid, column, null, event); + } else { + this.select({ recid: recid, column: column }); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + contextMenu: function (recid, event) { + var obj = this; + if (typeof event.offsetX === 'undefined') { + event.offsetX = event.layerX - event.target.offsetLeft; + event.offsetY = event.layerY - event.target.offsetTop; + } + if (w2utils.isFloat(recid)) recid = parseFloat(recid); + if (this.getSelection().indexOf(recid) == -1) obj.click(recid); + // need timeout to allow click to finish first + setTimeout(function () { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: obj.name, originalEvent: event, recid: recid }); + if (eventData.isCancelled === true) return; + // default action + if (obj.menu.length > 0) { + $(obj.box).find(event.target) + .w2menu(obj.menu, { + left : event.offsetX, + onSelect: function (event) { + obj.menuClick(recid, parseInt(event.index), event.originalEvent); + } + } + ); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 150); // need timer 150 for FF + }, + + menuClick: function (recid, index, event) { + var obj = this; + // event before + var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: obj.name, originalEvent: event, + recid: recid, menuIndex: index, menuItem: obj.menu[index] }); + if (eventData.isCancelled === true) return; + // default action + // -- empty + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + toggle: function (recid) { + var rec = this.get(recid); + if (rec.expanded === true) return this.collapse(recid); else return this.expand(recid); + }, + + expand: function (recid) { + var rec = this.get(recid); + var obj = this; + var id = w2utils.escapeId(recid); + if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length > 0) return false; + if (rec.expanded == 'none') return false; + // insert expand row + var tmp = 1 + (this.show.selectColumn ? 1 : 0); + var addClass = ''; // ($('#grid_'+this.name +'_rec_'+ w2utils.escapeId(recid)).hasClass('w2ui-odd') ? 'w2ui-odd' : 'w2ui-even'); + $('#grid_'+ this.name +'_rec_'+ id).after( + ''+ + (this.show.lineNumbers ? '' : '') + + '
      '+ + ' '+ + '
      '+ + ' '+ + ''); + // event before + var eventData = this.trigger({ phase: 'before', type: 'expand', target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded', ready: ready }); + if (eventData.isCancelled === true) { + $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove(); + return; + } + // default action + $('#grid_'+ this.name +'_rec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded'); + $('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').show(); + $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('
      '); + rec.expanded = true; + // check if height of expanded row > 5 then remove spinner + setTimeout(ready, 300); + function ready() { + var div1 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded'); + var div2 = $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row .w2ui-expanded1 > div'); + if (div1.height() < 5) return; + div1.css('opacity', 1); + div2.show().css('opacity', 1); + $('#grid_'+ obj.name +'_cell_'+ obj.get(recid, true) +'_expand div').html('-'); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.resizeRecords(); + return true; + }, + + collapse: function (recid) { + var rec = this.get(recid); + var obj = this; + var id = w2utils.escapeId(recid); + if ($('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length == 0) return false; + // event before + var eventData = this.trigger({ phase: 'before', type: 'collapse', target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ id +'_expanded' }); + if (eventData.isCancelled === true) return; + // default action + $('#grid_'+ this.name +'_rec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded'); + $('#grid_'+ this.name +'_rec_'+ id +'_expanded').css('opacity', 0); + $('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('+'); + setTimeout(function () { + $('#grid_'+ obj.name +'_rec_'+ id +'_expanded').height('0px'); + setTimeout(function () { + $('#grid_'+ obj.name +'_rec_'+ id +'_expanded_row').remove(); + delete rec.expanded; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resizeRecords(); + }, 300); + }, 200); + return true; + }, + + sort: function (field, direction, multiField) { // if no params - clears sort + // event before + var eventData = this.trigger({ phase: 'before', type: 'sort', target: this.name, field: field, direction: direction, multiField: multiField }); + if (eventData.isCancelled === true) return; + // check if needed to quit + if (typeof field != 'undefined') { + // default action + var sortIndex = this.sortData.length; + for (var s in this.sortData) { + if (this.sortData[s].field == field) { sortIndex = s; break; } + } + if (typeof direction == 'undefined' || direction == null) { + if (typeof this.sortData[sortIndex] == 'undefined') { + direction = 'asc'; + } else { + switch (String(this.sortData[sortIndex].direction)) { + case 'asc' : direction = 'desc'; break; + case 'desc' : direction = 'asc'; break; + default : direction = 'asc'; break; + } + } + } + if (this.multiSort === false) { this.sortData = []; sortIndex = 0; } + if (multiField != true) { this.sortData = []; sortIndex = 0; } + // set new sort + if (typeof this.sortData[sortIndex] == 'undefined') this.sortData[sortIndex] = {}; + this.sortData[sortIndex].field = field; + this.sortData[sortIndex].direction = direction; + } else { + this.sortData = []; + } + this.selectNone(); + // if local + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (!url) { + this.localSort(); + if (this.searchData.length > 0) this.localSearch(true); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(); + } else { + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.last.xhr_offset = 0; + this.reload(); + } + }, + + copy: function () { + var sel = this.getSelection(); + if (sel.length == 0) return ''; + var text = ''; + if (typeof sel[0] == 'object') { // cell copy + // find min/max column + var minCol = sel[0].column; + var maxCol = sel[0].column; + var recs = []; + for (var s in sel) { + if (sel[s].column < minCol) minCol = sel[s].column; + if (sel[s].column > maxCol) maxCol = sel[s].column; + if (recs.indexOf(sel[s].index) == -1) recs.push(sel[s].index); + } + recs.sort(); + for (var r in recs) { + var ind = recs[r]; + for (var c = minCol; c <= maxCol; c++) { + var col = this.columns[c]; + if (col.hidden === true) continue; + text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + } + } else { // row copy + for (var s in sel) { + var ind = this.get(sel[s], true); + for (var c in this.columns) { + var col = this.columns[c]; + if (col.hidden === true) continue; + text += w2utils.stripTags(this.getCellHTML(ind, c)) + '\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + } + } + text = text.substr(0, text.length - 1); + // before event + var eventData = this.trigger({ phase: 'before', type: 'copy', target: this.name, text: text }); + if (eventData.isCancelled === true) return ''; + text = eventData.text; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return text; + }, + + paste: function (text) { + var sel = this.getSelection(); + var ind = this.get(sel[0].recid, true); + var col = sel[0].column; + // before event + var eventData = this.trigger({ phase: 'before', type: 'paste', target: this.name, text: text, index: ind, column: col }); + if (eventData.isCancelled === true) return; + text = eventData.text; + // default action + if (this.selectType == 'row' || sel.length == 0) { + console.log('ERROR: You can paste only if grid.selectType = \'cell\' and when at least one cell selected.'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return; + } + var newSel = []; + var text = text.split('\n'); + for (var t in text) { + var tmp = text[t].split('\t'); + var cnt = 0; + var rec = this.records[ind]; + var cols = []; + for (var dt in tmp) { + if (!this.columns[col + cnt]) continue; + var field = this.columns[col + cnt].field; + rec.changes = rec.changes || {}; + rec.changes[field] = tmp[dt]; + cols.push(col + cnt); + cnt++; + } + for (var c in cols) newSel.push({ recid: rec.recid, column: cols[c] }); + ind++; + } + this.selectNone(); + this.select.apply(this, newSel); + this.refresh(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + // ================================================== + // --- Common functions + + resize: function () { + var obj = this; + var time = (new Date()).getTime(); + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // make sure the box is right + if (!this.box || $(this.box).attr('name') != this.name) return; + // determine new width and height + $(this.box).find('> div') + .css('width', $(this.box).width()) + .css('height', $(this.box).height()); + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; + // resize + obj.resizeBoxes(); + obj.resizeRecords(); + // init editable + // $('#grid_'+ obj.name + '_records .w2ui-editable input').each(function (index, el) { + // var column = obj.columns[$(el).attr('column')]; + // if (column && column.editable) $(el).w2field(column.editable); + // }); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + refreshCell: function (recid, field) { + var index = this.get(recid, true); + var col_ind = this.getColumn(field, true); + var rec = this.records[index]; + var col = this.columns[col_ind]; + var cell = $('#grid_'+ this.name + '_rec_'+ recid +' [col='+ col_ind +']'); + // set cell html and changed flag + cell.html(this.getCellHTML(index, col_ind)); + if (rec.changes && typeof rec.changes[col.field] != 'undefined') { + cell.addClass('w2ui-changed'); + } else { + cell.removeClass('w2ui-changed'); + } + }, + + refreshRow: function (recid) { + var tr = $('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)); + if (tr.length != 0) { + var ind = this.get(recid, true); + var line = tr.attr('line'); + // if it is searched, find index in search array + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.searchData.length > 0 && !url) for (var s in this.last.searchIds) if (this.last.searchIds[s] == ind) ind = s; + $(tr).replaceWith(this.getRecordHTML(ind, line)); + } + + }, + + refresh: function () { + var obj = this; + var time = (new Date()).getTime(); + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (this.total <= 0 && !url && this.searchData.length == 0) { + this.total = this.records.length; + this.buffered = this.total; + } + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + this.toolbar.disable('w2ui-edit', 'w2ui-delete'); + if (!this.box) return; + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'refresh' }); + if (eventData.isCancelled === true) return; + // -- header + if (this.show.header) { + $('#grid_'+ this.name +'_header').html(this.header +' ').show(); + } else { + $('#grid_'+ this.name +'_header').hide(); + } + // -- toolbar + if (this.show.toolbar) { + // if select-collumn is checked - no toolbar refresh + if (this.toolbar && this.toolbar.get('w2ui-column-on-off') && this.toolbar.get('w2ui-column-on-off').checked) { + // no action + } else { + $('#grid_'+ this.name +'_toolbar').show(); + // refresh toolbar all but search field + if (typeof this.toolbar == 'object') { + var tmp = this.toolbar.items; + for (var t in tmp) { + if (tmp[t].id == 'w2ui-search' || tmp[t].type == 'break') continue; + this.toolbar.refresh(tmp[t].id); + } + } + } + } else { + $('#grid_'+ this.name +'_toolbar').hide(); + } + // -- make sure search is closed + this.searchClose(); + // search placeholder + var el = $('#grid_'+ obj.name +'_search_all'); + if (!this.multiSearch && this.last.field == 'all' && this.searches.length > 0) { + this.last.field = this.searches[0].field; + this.last.caption = this.searches[0].caption; + } + for (var s in this.searches) { + if (this.searches[s].field == this.last.field) this.last.caption = this.searches[s].caption; + } + if (this.last.multi) { + el.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']'); + } else { + el.attr('placeholder', this.last.caption); + } + if (el.val() != this.last.search) { + var val = this.last.search; + var tmp = el.data('w2field'); + if (tmp) val = tmp.format(val); + el.val(val); + } + + // -- separate summary + var tmp = this.find({ summary: true }, true); + if (tmp.length > 0) { + for (var t in tmp) this.summary.push(this.records[tmp[t]]); + for (var t=tmp.length-1; t>=0; t--) this.records.splice(tmp[t], 1); + this.total = this.total - tmp.length; + this.buffered = this.buffered - tmp.length; + } + + // -- body + var bodyHTML = ''; + bodyHTML += '
      '+ + this.getRecordsHTML() + + '
      '+ + '
      '+ + ' '+ this.getColumnsHTML() +'
      '+ + '
      '; // Columns need to be after to be able to overlap + $('#grid_'+ this.name +'_body').html(bodyHTML); + // show summary records + if (this.summary.length > 0) { + $('#grid_'+ this.name +'_summary').html(this.getSummaryHTML()).show(); + } else { + $('#grid_'+ this.name +'_summary').hide(); + } + // -- footer + if (this.show.footer) { + $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()).show(); + } else { + $('#grid_'+ this.name +'_footer').hide(); + } + // show/hide clear search link + if (this.searchData.length > 0) { + $('#grid_'+ this.name +'_searchClear').show(); + } else { + $('#grid_'+ this.name +'_searchClear').hide(); + } + // all selected? + var sel = this.last.selection; + if (sel.indexes.length == this.records.length || (this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length)) { + $('#grid_'+ this.name +'_check_all').prop('checked', true); + } else { + $('#grid_'+ this.name +'_check_all').prop('checked', false); + } + // show number of selected + this.status(); + // collapse all records + var rows = obj.find({ expanded: true }, true); + for (var r in rows) obj.records[rows[r]].expanded = false; + // mark selection + setTimeout(function () { + var str = $.trim($('#grid_'+ obj.name +'_search_all').val()); + if (str != '') $(obj.box).find('.w2ui-grid-data > div').w2marker(str); + }, 50); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + obj.addRange('selection'); + setTimeout(function () { obj.resize(); obj.scroll(); }, 1); // allow to render first + + if ( obj.reorderColumns && !obj.last.columnDrag ) { + obj.last.columnDrag = obj.initColumnDrag(); + } else if ( !obj.reorderColumns && obj.last.columnDrag ) { + obj.last.columnDrag.remove(); + } + + return (new Date()).getTime() - time; + }, + + render: function (box) { + var obj = this; + var time = (new Date()).getTime(); + //if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (typeof box != 'undefined' && box != null) { + if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid') + .html(''); + } + this.box = box; + } + if (!this.box) return; + if (this.last.sortData == null) this.last.sortData = this.sortData; + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'render', box: box }); + if (eventData.isCancelled === true) return; + // insert Elements + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-grid') + .html('
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + ' '+ + '
      '); + if (this.selectType != 'row') $(this.box).addClass('w2ui-ss'); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // init toolbar + this.initToolbar(); + if (this.toolbar != null) this.toolbar.render($('#grid_'+ this.name +'_toolbar')[0]); + // reinit search_all + if (this.last.field && this.last.field != 'all') { + var sd = this.searchData; + this.initAllField(this.last.field, (sd.length == 1 ? sd[0].value : null)); + } + // init footer + $('#grid_'+ this.name +'_footer').html(this.getFooterHTML()); + // refresh + if (this.url) this.refresh(); // show empty grid (need it) - should it be only for remote data source + this.reload(); + + // init mouse events for mouse selection + $(this.box).on('mousedown', mouseStart); + $(this.box).on('selectstart', function () { return false; }); // fixes chrome cursor bug + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + // attach to resize event + if ($('.w2ui-layout').length == 0) { // if there is layout, it will send a resize event + this.tmp_resize = function (event) { w2ui[obj.name].resize(); } + $(window).off('resize', this.tmp_resize).on('resize', this.tmp_resize); + } + return (new Date()).getTime() - time; + + function mouseStart (event) { + if ($(event.target).parents().hasClass('w2ui-head') || $(event.target).hasClass('w2ui-head')) return; + if (obj.last.move && obj.last.move.type == 'expand') return; + if (!obj.multiSelect) return; + obj.last.move = { + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + recid : $(event.target).parents('tr').attr('recid'), + column : (event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')), + type : 'select', + ghost : false, + start : true + }; + $(document).on('mousemove', mouseMove); + $(document).on('mouseup', mouseStop); + } + + function mouseMove (event) { + var mv = obj.last.move; + if (!mv || mv.type != 'select') return; + mv.divX = (event.screenX - mv.x); + mv.divY = (event.screenY - mv.y); + if (Math.abs(mv.divX) <= 1 && Math.abs(mv.divY) <= 1) return; // only if moved more then 1px + obj.last.cancelClick = true; + if (obj.reorderRows == true) { + if (!mv.ghost) { + var row = $('#grid_'+ obj.name + '_rec_'+ mv.recid); + var tmp = row.parents('table').find('tr:first-child').clone(); + mv.offsetY = event.offsetY; + mv.from = mv.recid; + mv.pos = row.position(); + mv.ghost = $(row).clone(true); + mv.ghost.removeAttr('id'); + row.find('td:first-child').replaceWith(''); + var recs = $(obj.box).find('.w2ui-grid-records'); + recs.append('
      '); + $('#grid_'+ obj.name + '_ghost').append(tmp).append(mv.ghost); + } + var recid = $(event.target).parents('tr').attr('recid'); + if (recid != mv.from) { + var row1 = $('#grid_'+ obj.name + '_rec_'+ mv.recid); + var row2 = $('#grid_'+ obj.name + '_rec_'+ recid); + if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); + mv.lastY = event.screenY; + mv.to = recid; + } + var ghost = $('#grid_'+ obj.name + '_ghost'); + var recs = $(obj.box).find('.w2ui-grid-records'); + ghost.css({ + top : mv.pos.top + mv.divY + recs.scrollTop(), // + mv.offsetY - obj.recordHeight / 2, + left : mv.pos.left + }); + return; + } + if (mv.start && mv.recid) { + obj.selectNone(); + mv.start = false; + } + var newSel= []; + var recid = (event.target.tagName == 'TR' ? $(event.target).attr('recid') : $(event.target).parents('tr').attr('recid')); + if (typeof recid == 'undefined') return; + var ind1 = obj.get(mv.recid, true); + // |:wolfmanx:| this happens when selection is started on summary row + if (ind1 === null) return; + var ind2 = obj.get(recid, true); + // this happens when selection is extended into summary row (a good place to implement scrolling) + if (ind2 === null) return; + var col1 = parseInt(mv.column); + var col2 = parseInt(event.target.tagName == 'TD' ? $(event.target).attr('col') : $(event.target).parents('td').attr('col')); + if (ind1 > ind2) { var tmp = ind1; ind1 = ind2; ind2 = tmp; } + // check if need to refresh + var tmp = 'ind1:'+ ind1 +',ind2;'+ ind2 +',col1:'+ col1 +',col2:'+ col2; + if (mv.range == tmp) return; + mv.range = tmp; + for (var i = ind1; i <= ind2; i++) { + if (obj.last.searchIds.length > 0 && obj.last.searchIds.indexOf(i) == -1) continue; + if (obj.selectType != 'row') { + if (col1 > col2) { var tmp = col1; col1 = col2; col2 = tmp; } + var tmp = []; + for (var c = col1; c <= col2; c++) { + if (obj.columns[c].hidden) continue; + newSel.push({ recid: obj.records[i].recid, column: parseInt(c) }); + } + } else { + newSel.push(obj.records[i].recid); + } + } + if (obj.selectType != 'row') { + var sel = obj.getSelection(); + // add more items + var tmp = []; + for (var ns in newSel) { + var flag = false; + for (var s in sel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; + if (!flag) tmp.push({ recid: newSel[ns].recid, column: newSel[ns].column }); + } + obj.select.apply(obj, tmp); + // remove items + var tmp = []; + for (var s in sel) { + var flag = false; + for (var ns in newSel) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true; + if (!flag) tmp.push({ recid: sel[s].recid, column: sel[s].column }); + } + obj.unselect.apply(obj, tmp); + } else { + if (obj.multiSelect) { + var sel = obj.getSelection(); + for (var ns in newSel) if (sel.indexOf(newSel[ns]) == -1) obj.select(newSel[ns]); // add more items + for (var s in sel) if (newSel.indexOf(sel[s]) == -1) obj.unselect(sel[s]); // remove items + } + } + } + + function mouseStop (event) { + var mv = obj.last.move; + setTimeout(function () { delete obj.last.cancelClick; }, 1); + if ($(event.target).parents().hasClass('.w2ui-head') || $(event.target).hasClass('.w2ui-head')) return; + if (!mv || mv.type != 'select') return; + if (obj.reorderRows == true) { + var ind1 = obj.get(mv.from, true); + var tmp = obj.records[ind1]; + obj.records.splice(ind1, 1); + var ind2 = obj.get(mv.to, true); + if (ind1 > ind2) obj.records.splice(ind2, 0, tmp); else obj.records.splice(ind2+1, 0, tmp); + $('#grid_'+ obj.name + '_ghost').remove(); + obj.refresh(); + } + delete obj.last.move; + $(document).off('mousemove', mouseMove); + $(document).off('mouseup', mouseStop); + } + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'destroy' }); + if (eventData.isCancelled === true) return; + // remove events + $(window).off('resize', this.tmp_resize); + // clean up + if (typeof this.toolbar == 'object' && this.toolbar.destroy) this.toolbar.destroy(); + if ($(this.box).find('#grid_'+ this.name +'_body').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + // =========================================== + // --- Internal Functions + + initColumnOnOff: function () { + if (!this.show.toolbarColumns) return; + var obj = this; + var col_html = '
      '+ + ''; + for (var c in this.columns) { + var col = this.columns[c]; + var tmp = this.columns[c].caption; + if (!tmp && this.columns[c].hint) tmp = this.columns[c].hint; + if (!tmp) tmp = '- column '+ (parseInt(c) + 1) +' -'; + col_html += ''+ + ''+ + ''+ + ''; + } + col_html += ''; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (url) { + col_html += + ''; + } + col_html += ''+ + ''; + col_html += "
      '+ + ' '+ + ''+ + ' '+ + '
      '+ + '
      '+ w2utils.lang('Skip') + + ' '+ w2utils.lang('Records')+ + '
      '+ + '
      '+ + '
      '+ w2utils.lang('Toggle Line Numbers') +'
      '+ + '
      '+ + '
      '+ w2utils.lang('Reset Column Size') + '
      '+ + '
      "; + this.toolbar.get('w2ui-column-on-off').html = col_html; + }, + + /** + * + * @param box, grid object + * @returns {{remove: Function}} contains a closure around all events to ensure they are removed from the dom + */ + initColumnDrag: function( box ){ + //throw error if using column groups + if ( this.columnGroups && this.columnGroups.length ) throw 'Draggable columns are not currently supported with column groups.'; + + var obj = this, + _dragData = {}; + _dragData.lastInt = null; + _dragData.pressed = false; + _dragData.timeout = null;_dragData.columnHead = null; + + //attach orginal event listener + $( obj.box).on( 'mousedown', dragColStart ); + $( obj.box ).on( 'mouseup', catchMouseup ); + + function catchMouseup(){ + _dragData.pressed = false; + clearTimeout( _dragData.timeout ); + } + /** + * + * @param event, mousedown + * @returns {boolean} false, preventsDefault + */ + function dragColStart ( event ) { + if ( _dragData.timeout ) clearTimeout( _dragData.timeout ); + var self = this; + _dragData.pressed = true; + + _dragData.timeout = setTimeout(function(){ + if ( !_dragData.pressed ) return; + + var eventData, + columns, + selectedCol, + origColumn, + origColumnNumber, + invalidPreColumns = [ 'w2ui-col-number', 'w2ui-col-expand', 'w2ui-col-select' ], + invalidPostColumns = [ 'w2ui-head-last' ], + invalidColumns = invalidPreColumns.concat( invalidPostColumns ), + preColumnsSelector = '.w2ui-col-number, .w2ui-col-expand, .w2ui-col-select', + preColHeadersSelector = '.w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select'; + + // do nothing if it is not a header + if ( !$( event.originalEvent.target ).parents().hasClass( 'w2ui-head' ) ) return; + + // do nothing if it is an invalid column + for ( var i = 0, l = invalidColumns.length; i < l; i++ ){ + if ( $( event.originalEvent.target ).parents().hasClass( invalidColumns[ i ] ) ) return; + } + + _dragData.numberPreColumnsPresent = $( obj.box ).find( preColHeadersSelector ).length; + + //start event for drag start + _dragData.columnHead = origColumn = $( event.originalEvent.target ).parents( '.w2ui-head' ); + origColumnNumber = parseInt( origColumn.attr( 'col' ), 10); + eventData = obj.trigger({ type: 'columnDragStart', phase: 'before', originalEvent: event, origColumnNumber: origColumnNumber, target: origColumn[0] }); + if ( eventData.isCancelled === true ) return false; + + columns = _dragData.columns = $( obj.box ).find( '.w2ui-head:not(.w2ui-head-last)' ); + + //add events + $( document ).on( 'mouseup', dragColEnd ); + $( document ).on( 'mousemove', dragColOver ); + + _dragData.originalPos = parseInt( $( event.originalEvent.target ).parent( '.w2ui-head' ).attr( 'col' ), 10 ); + //_dragData.columns.css({ overflow: 'visible' }).children( 'div' ).css({ overflow: 'visible' }); + + //configure and style ghost image + _dragData.ghost = $( self ).clone( true ); + + //hide other elements on ghost except the grid body + $( _dragData.ghost ).find( '[col]:not([col="' + _dragData.originalPos + '"]), .w2ui-toolbar, .w2ui-grid-header' ).remove(); + $( _dragData.ghost ).find( preColumnsSelector ).remove(); + $( _dragData.ghost ).find( '.w2ui-grid-body' ).css({ top: 0 }); + + selectedCol = $( _dragData.ghost ).find( '[col="' + _dragData.originalPos + '"]' ); + $( document.body ).append( _dragData.ghost ); + + $( _dragData.ghost ).css({ + width: 0, + height: 0, + margin: 0, + position: 'fixed', + zIndex: 999999, + opacity: 0 + }).addClass( '.w2ui-grid-ghost' ).animate({ + width: selectedCol.width(), + height: $(obj.box).find('.w2ui-grid-body:first').height(), + left : event.pageX, + top : event.pageY, + opacity: .8 + }, 0 ); + + //establish current offsets + _dragData.offsets = []; + for ( var i = 0, l = columns.length; i < l; i++ ) { + _dragData.offsets.push( $( columns[ i ] ).offset().left ); + } + + //conclude event + obj.trigger( $.extend( eventData, { phase: 'after' } ) ); + }, 150 );//end timeout wrapper + } + + function dragColOver ( event ) { + if ( !_dragData.pressed ) return; + + var cursorX = event.originalEvent.pageX, + cursorY = event.originalEvent.pageY, + offsets = _dragData.offsets, + lastWidth = $( '.w2ui-head:not(.w2ui-head-last)' ).width(); + + _dragData.targetInt = targetIntersection( cursorX, offsets, lastWidth ); + markIntersection( _dragData.targetInt ); + trackGhost( cursorX, cursorY ); + } + + function dragColEnd ( event ) { + _dragData.pressed = false; + + var eventData, + target, + selected, + columnConfig, + columnNum, + targetColumn, + ghosts = $( '.w2ui-grid-ghost' ); + + //start event for drag start + eventData = obj.trigger({ type: 'columnDragEnd', phase: 'before', originalEvent: event, target: _dragData.columnHead[0] }); + if ( eventData.isCancelled === true ) return false; + + selected = obj.columns[ _dragData.originalPos ]; + columnConfig = obj.columns; + columnNum = ( _dragData.targetInt >= obj.columns.length ) ? obj.columns.length - 1 : + ( _dragData.targetInt < _dragData.originalPos ) ? _dragData.targetInt : _dragData.targetInt - 1; + target = ( _dragData.numberPreColumnsPresent ) ? + ( _dragData.targetInt - _dragData.numberPreColumnsPresent < 0 ) ? 0 : _dragData.targetInt - _dragData.numberPreColumnsPresent : + _dragData.targetInt; + targetColumn = $( '.w2ui-head[col="' + columnNum + '"]' ); + + if ( target !== _dragData.originalPos + 1 && target !== _dragData.originalPos && targetColumn && targetColumn.length ) { + $( _dragData.ghost ).animate({ + top: $( obj.box ).offset().top, + left: targetColumn.offset().left, + width: 0, + height: 0, + opacity:.2 + }, 300, function(){ + $( this ).remove(); + ghosts.remove(); + }); + + columnConfig.splice( target, 0, $.extend( {}, selected ) ); + columnConfig.splice( columnConfig.indexOf( selected ), 1); + } else { + $( _dragData.ghost ).remove(); + ghosts.remove(); + } + + //_dragData.columns.css({ overflow: '' }).children( 'div' ).css({ overflow: '' }); + + $( document ).off( 'mouseup', dragColEnd ); + $( document ).off( 'mousemove', dragColOver ); + if ( _dragData.marker ) _dragData.marker.remove(); + _dragData = {}; + + obj.refresh(); + + //conclude event + obj.trigger( $.extend( eventData, { phase: 'after', targetColumnNumber: target - 1 } ) ); + } + + function markIntersection( intersection ){ + if ( !_dragData.marker && !_dragData.markerLeft ) { + _dragData.marker = $('
      ' + + '
      ' + + '
      ' + + '
      '); + _dragData.markerLeft = $('
      ' + + '
      ' + + '
      ' + + '
      '); + } + + if ( !_dragData.lastInt || _dragData.lastInt !== intersection ){ + _dragData.lastInt = intersection; + _dragData.marker.remove(); + _dragData.markerLeft.remove(); + $('.w2ui-head').removeClass('w2ui-col-intersection'); + + //if the current intersection is greater than the number of columns add the marker to the end of the last column only + if ( intersection >= _dragData.columns.length ) { + $( _dragData.columns[ _dragData.columns.length - 1 ] ).children( 'div:last' ).append( _dragData.marker.addClass( 'right' ).removeClass( 'left' ) ); + $( _dragData.columns[ _dragData.columns.length - 1 ] ).addClass('w2ui-col-intersection'); + } else if ( intersection <= _dragData.numberPreColumnsPresent ) { + //if the current intersection is on the column numbers place marker on first available column only + $( '.w2ui-head[col="0"]' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ).css({ position: 'relative' }); + $( '.w2ui-head[col="0"]').prev().addClass('w2ui-col-intersection'); + } else { + //otherwise prepend the marker to the targeted column and append it to the previous column + $( _dragData.columns[intersection] ).children( 'div:last' ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ); + $( _dragData.columns[intersection] ).prev().children( 'div:last' ).append( _dragData.markerLeft.addClass( 'right' ).removeClass( 'left' ) ).css({ position: 'relative' }); + $( _dragData.columns[intersection - 1] ).addClass('w2ui-col-intersection'); + } + } + } + + function targetIntersection( cursorX, offsets, lastWidth ){ + if ( cursorX <= offsets[0] ) { + return 0; + } else if ( cursorX >= offsets[offsets.length - 1] + lastWidth ) { + return offsets.length; + } else { + for ( var i = 0, l = offsets.length; i < l; i++ ) { + var thisOffset = offsets[ i ]; + var nextOffset = offsets[ i + 1 ] || offsets[ i ] + lastWidth; + var midpoint = ( nextOffset - offsets[ i ]) / 2 + offsets[ i ]; + + if ( cursorX > thisOffset && cursorX <= midpoint ) { + return i; + } else if ( cursorX > midpoint && cursorX <= nextOffset ) { + return i + 1; + } + } + return intersection; + } + } + + function trackGhost( cursorX, cursorY ){ + $( _dragData.ghost ).css({ + left: cursorX - 10, + top: cursorY - 10 + }); + } + + //return an object to remove drag if it has ever been enabled + return { + remove: function(){ + $( obj.box ).off( 'mousedown', dragColStart ); + $( obj.box ).off( 'mouseup', catchMouseup ); + $( obj.box ).find( '.w2ui-head' ).removeAttr( 'draggable' ); + obj.last.columnDrag = false; + } + } + }, + + columnOnOff: function (el, event, field, value) { + // event before + var eventData = this.trigger({ phase: 'before', target: this.name, type: 'columnOnOff', checkbox: el, field: field, originalEvent: event }); + if (eventData.isCancelled === true) return; + // regular processing + var obj = this; + // collapse expanded rows + for (var r in this.records) { + if (this.records[r].expanded === true) this.records[r].expanded = false + } + // show/hide + var hide = true; + if (field == 'line-numbers') { + this.show.lineNumbers = !this.show.lineNumbers; + this.refresh(); + } else if (field == 'skip') { + if (!w2utils.isInt(value)) value = 0; + obj.skip(value); + } else if (field == 'resize') { + // restore sizes + for (var c in this.columns) { + if (typeof this.columns[c].sizeOriginal != 'undefined') { + this.columns[c].size = this.columns[c].sizeOriginal; + } + } + this.initResize(); + this.resize(); + } else { + var col = this.getColumn(field); + if (col.hidden) { + $(el).prop('checked', true); + this.showColumn(col.field); + } else { + $(el).prop('checked', false); + this.hideColumn(col.field); + } + hide = false; + } + this.initColumnOnOff(); + if (hide) { + setTimeout(function () { + $().w2overlay('', { name: 'searches-'+ this.name }); + obj.toolbar.uncheck('column-on-off'); + }, 100); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + initToolbar: function () { + // -- if toolbar is true + if (typeof this.toolbar['render'] == 'undefined') { + var tmp_items = this.toolbar.items; + this.toolbar.items = []; + this.toolbar = $().w2toolbar($.extend(true, {}, this.toolbar, { name: this.name +'_toolbar', owner: this })); + + // ============================================= + // ------ Toolbar Generic buttons + + if (this.show.toolbarReload) { + this.toolbar.items.push($.extend(true, {}, this.buttons['reload'])); + } + if (this.show.toolbarColumns) { + this.toolbar.items.push($.extend(true, {}, this.buttons['columns'])); + this.initColumnOnOff(); + } + if (this.show.toolbarReload || this.show.toolbarColumn) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break0' }); + } + if (this.show.toolbarSearch) { + var html = + ''; + this.toolbar.items.push({ type: 'html', id: 'w2ui-search', html: html }); + if (this.multiSearch && this.searches.length > 0) { + this.toolbar.items.push($.extend(true, {}, this.buttons['search-go'])); + } + } + if (this.show.toolbarSearch && (this.show.toolbarAdd || this.show.toolbarEdit || this.show.toolbarDelete || this.show.toolbarSave)) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break1' }); + } + if (this.show.toolbarAdd) { + this.toolbar.items.push($.extend(true, {}, this.buttons['add'])); + } + if (this.show.toolbarEdit) { + this.toolbar.items.push($.extend(true, {}, this.buttons['edit'])); + } + if (this.show.toolbarDelete) { + this.toolbar.items.push($.extend(true, {}, this.buttons['delete'])); + } + if (this.show.toolbarSave) { + if (this.show.toolbarAdd || this.show.toolbarDelete || this.show.toolbarEdit) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break2' }); + } + this.toolbar.items.push($.extend(true, {}, this.buttons['save'])); + } + // add original buttons + for (var i in tmp_items) this.toolbar.items.push(tmp_items[i]); + + // ============================================= + // ------ Toolbar onClick processing + + var obj = this; + this.toolbar.on('click', function (event) { + var eventData = obj.trigger({ phase: 'before', type: 'toolbar', target: event.target, originalEvent: event }); + if (eventData.isCancelled === true) return; + var id = event.target; + switch (id) { + case 'w2ui-reload': + var eventData2 = obj.trigger({ phase: 'before', type: 'reload', target: obj.name }); + if (eventData2.isCancelled === true) return false; + obj.reload(); + obj.trigger($.extend(eventData2, { phase: 'after' })); + break; + case 'w2ui-column-on-off': + for (var c in obj.columns) { + if (obj.columns[c].hidden) { + $("#grid_"+ obj.name +"_column_"+ c + "_check").prop("checked", false); + } else { + $("#grid_"+ obj.name +"_column_"+ c + "_check").prop('checked', true); + } + } + obj.initResize(); + obj.resize(); + break; + case 'w2ui-search-advanced': + var tb = this; + var it = this.get(id); + if (it.checked) { + obj.searchClose(); + setTimeout(function () { tb.uncheck(id); }, 1); + } else { + obj.searchOpen(); + event.originalEvent.stopPropagation(); + function tmp_close() { + if ($('#w2ui-overlay-searches-'+ obj.name).data('keepOpen') === true) return; + tb.uncheck(id); + $(document).off('click', 'body', tmp_close); + } + $(document).on('click', 'body', tmp_close); + } + break; + case 'w2ui-add': + // events + var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'add', recid: null }); + obj.trigger($.extend(eventData, { phase: 'after' })); + break; + case 'w2ui-edit': + var sel = obj.getSelection(); + var recid = null; + if (sel.length == 1) recid = sel[0]; + // events + var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'edit', recid: recid }); + obj.trigger($.extend(eventData, { phase: 'after' })); + break; + case 'w2ui-delete': + obj.delete(); + break; + case 'w2ui-save': + obj.save(); + break; + } + // no default action + obj.trigger($.extend(eventData, { phase: 'after' })); + }); + } + return; + }, + + initResize: function () { + var obj = this; + //if (obj.resizing === true) return; + $(this.box).find('.w2ui-resizer') + .off('click') + .on('click', function (event) { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + }) + .off('mousedown') + .on('mousedown', function (event) { + if (!event) event = window.event; + if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } + obj.resizing = true; + obj.last.tmp = { + x : event.screenX, + y : event.screenY, + gx : event.screenX, + gy : event.screenY, + col : parseInt($(this).attr('name')) + }; + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + if (event.preventDefault) event.preventDefault(); + // fix sizes + for (var c in obj.columns) { + if (typeof obj.columns[c].sizeOriginal == 'undefined') obj.columns[c].sizeOriginal = obj.columns[c].size; + obj.columns[c].size = obj.columns[c].sizeCalculated; + } + var eventData = { phase: 'before', type: 'columnResize', target: obj.name, column: obj.last.tmp.col, field: obj.columns[obj.last.tmp.col].field }; + eventData = obj.trigger($.extend(eventData, { resizeBy: 0, originalEvent: event })); + // set move event + var mouseMove = function (event) { + if (obj.resizing != true) return; + if (!event) event = window.event; + // event before + eventData = obj.trigger($.extend(eventData, { resizeBy: (event.screenX - obj.last.tmp.gx), originalEvent: event })); + if (eventData.isCancelled === true) { eventData.isCancelled = false; return; } + // default action + obj.last.tmp.x = (event.screenX - obj.last.tmp.x); + obj.last.tmp.y = (event.screenY - obj.last.tmp.y); + obj.columns[obj.last.tmp.col].size = (parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px'; + obj.resizeRecords(); + // reset + obj.last.tmp.x = event.screenX; + obj.last.tmp.y = event.screenY; + } + var mouseUp = function (event) { + delete obj.resizing; + $(document).off('mousemove', 'body'); + $(document).off('mouseup', 'body'); + obj.resizeRecords(); + // event before + obj.trigger($.extend(eventData, { phase: 'after', originalEvent: event })); + } + $(document).on('mousemove', 'body', mouseMove); + $(document).on('mouseup', 'body', mouseUp); + }) + .each(function (index, el) { + var td = $(el).parent(); + $(el).css({ + "height" : '25px', + "margin-left" : (td.width() - 3) + 'px' + }) + }); + }, + + resizeBoxes: function () { + // elements + var main = $(this.box).find('> div'); + var header = $('#grid_'+ this.name +'_header'); + var toolbar = $('#grid_'+ this.name +'_toolbar'); + var summary = $('#grid_'+ this.name +'_summary'); + var footer = $('#grid_'+ this.name +'_footer'); + var body = $('#grid_'+ this.name +'_body'); + var columns = $('#grid_'+ this.name +'_columns'); + var records = $('#grid_'+ this.name +'_records'); + + if (this.show.header) { + header.css({ + top: '0px', + left: '0px', + right: '0px' + }); + } + + if (this.show.toolbar) { + toolbar.css({ + top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + } + if (this.show.footer) { + footer.css({ + bottom: '0px', + left: '0px', + right: '0px' + }); + } + if (this.summary.length > 0) { + summary.css({ + bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + } + body.css({ + top: ( 0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) ) + 'px', + bottom: ( 0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + (this.summary.length > 0 ? w2utils.getSize(summary, 'height') : 0) ) + 'px', + left: '0px', + right: '0px' + }); + }, + + resizeRecords: function () { + var obj = this; + // remove empty records + $(this.box).find('.w2ui-empty-record').remove(); + // -- Calculate Column size in PX + var box = $(this.box); + var grid = $(this.box).find('> div'); + var header = $('#grid_'+ this.name +'_header'); + var toolbar = $('#grid_'+ this.name +'_toolbar'); + var summary = $('#grid_'+ this.name +'_summary'); + var footer = $('#grid_'+ this.name +'_footer'); + var body = $('#grid_'+ this.name +'_body'); + var columns = $('#grid_'+ this.name +'_columns'); + var records = $('#grid_'+ this.name +'_records'); + + // body might be expanded by data + if (!this.fixedBody) { + // allow it to render records, then resize + var calculatedHeight = w2utils.getSize(columns, 'height') + + w2utils.getSize($('#grid_'+ obj.name +'_records table'), 'height'); + obj.height = calculatedHeight + + w2utils.getSize(grid, '+height') + + (obj.show.header ? w2utils.getSize(header, 'height') : 0) + + (obj.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + + (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + + (obj.show.footer ? w2utils.getSize(footer, 'height') : 0); + grid.css('height', obj.height); + body.css('height', calculatedHeight); + box.css('height', w2utils.getSize(grid, 'height') + w2utils.getSize(box, '+height')); + } else { + // fixed body height + var calculatedHeight = grid.height() + - (this.show.header ? w2utils.getSize(header, 'height') : 0) + - (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + - (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + - (this.show.footer ? w2utils.getSize(footer, 'height') : 0); + body.css('height', calculatedHeight); + } + + // check overflow + var bodyOverflowX = false; + var bodyOverflowY = false; + if (body.width() < $(records).find('>table').width()) bodyOverflowX = true; + if (body.height() - columns.height() < $(records).find('>table').height() + (bodyOverflowX ? w2utils.scrollBarSize() : 0)) bodyOverflowY = true; + if (!this.fixedBody) { bodyOverflowY = false; bodyOverflowX = false; } + if (bodyOverflowX || bodyOverflowY) { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + "-webkit-overflow-scrolling": "touch", + "overflow-x": (bodyOverflowX ? 'auto' : 'hidden'), + "overflow-y": (bodyOverflowY ? 'auto' : 'hidden') }); + } else { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').hide(); + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + overflow: 'hidden' + }); + if (records.length > 0) { this.last.scrollTop = 0; this.last.scrollLeft = 0; } // if no scrollbars, always show top + } + if (this.show.emptyRecords && !bodyOverflowY) { + var max = Math.floor(records.height() / this.recordHeight) + 1; + if (this.fixedBody) { + for (var di = this.buffered; di <= max; di++) { + var html = ''; + html += ''; + if (this.show.lineNumbers) html += ''; + if (this.show.selectColumn) html += ''; + if (this.show.expandColumn) html += ''; + var j = 0; + while (true && this.columns.length > 0) { + var col = this.columns[j]; + if (col.hidden) { j++; if (typeof this.columns[j] == 'undefined') break; else continue; } + html += ''; + j++; + if (typeof this.columns[j] == 'undefined') break; + } + html += ''; + html += ''; + $('#grid_'+ this.name +'_records > table').append(html); + } + } + } + if (body.length > 0) { + var width_max = parseInt(body.width()) + - (bodyOverflowY ? w2utils.scrollBarSize() : 0) + - (this.show.lineNumbers ? 34 : 0) + - (this.show.selectColumn ? 26 : 0) + - (this.show.expandColumn ? 26 : 0); + var width_box = width_max; + var percent = 0; + // gridMinWidth processiong + var restart = false; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (typeof col.gridMinWidth != 'undefined') { + if (col.gridMinWidth > width_box && col.hidden !== true) { + col.hidden = true; + restart = true; + } + if (col.gridMinWidth < width_box && col.hidden === true) { + col.hidden = false; + restart = true; + } + } + } + if (restart === true) { + this.refresh(); + return; + } + // assign PX column s + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (String(col.size).substr(String(col.size).length-2).toLowerCase() == 'px') { + width_max -= parseFloat(col.size); + this.columns[i].sizeCalculated = col.size; + this.columns[i].sizeType = 'px'; + } else { + percent += parseFloat(col.size); + this.columns[i].sizeType = '%'; + delete col.sizeCorrected; + } + } + // if sum != 100% -- reassign proportionally + if (percent != 100 && percent > 0) { + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (col.sizeType == '%') { + col.sizeCorrected = Math.round(parseFloat(col.size) * 100 * 100 / percent) / 100 + '%'; + } + } + } + // calculate % columns + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (col.sizeType == '%') { + if (typeof this.columns[i].sizeCorrected != 'undefined') { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.sizeCorrected) / 100) - 1 + 'px'; + } else { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.size) / 100) - 1 + 'px'; + } + } + } + } + // fix margin of error that is due percentage calculations + var width_cols = 0; + for (var i = 0; i < this.columns.length; i++) { + var col = this.columns[i]; + if (col.hidden) continue; + if (typeof col.min == 'undefined') col.min = 20; + if (parseInt(col.sizeCalculated) < parseInt(col.min)) col.sizeCalculated = col.min + 'px'; + if (parseInt(col.sizeCalculated) > parseInt(col.max)) col.sizeCalculated = col.max + 'px'; + width_cols += parseInt(col.sizeCalculated); + } + var width_diff = parseInt(width_box) - parseInt(width_cols); + if (width_diff > 0 && percent > 0) { + var i = 0; + while (true) { + var col = this.columns[i]; + if (typeof col == 'undefined') { i = 0; continue; } + if (col.hidden || col.sizeType == 'px') { i++; continue; } + col.sizeCalculated = (parseInt(col.sizeCalculated) + 1) + 'px'; + width_diff--; + if (width_diff == 0) break; + i++; + } + } else if (width_diff > 0) { + columns.find('> table > tbody > tr:nth-child(1) td.w2ui-head-last').css('width', w2utils.scrollBarSize()).show(); + } + // resize columns + columns.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { + var ind = $(el).attr('col'); + if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + // last column + if ($(el).hasClass('w2ui-head-last')) { + $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); + } + }); + // if there are column groups - hide first row (needed for sizing) + if (columns.find('> table > tbody > tr').length == 3) { + columns.find('> table > tbody > tr:nth-child(1) td').html('').css({ + 'height' : '0px', + 'border' : '0px', + 'padding': '0px', + 'margin' : '0px' + }); + } + // resize records + records.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { + var ind = $(el).attr('col'); + if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + // last column + if ($(el).hasClass('w2ui-grid-data-last')) { + $(el).css('width', (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); + } + }); + // resize summary + summary.find('> table > tbody > tr:nth-child(1) td').each(function (index, el) { + var ind = $(el).attr('col'); + if (typeof ind != 'undefined' && obj.columns[ind]) $(el).css('width', obj.columns[ind].sizeCalculated); + // last column + if ($(el).hasClass('w2ui-grid-data-last')) { + $(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent == 0 ? width_diff : 0) + 'px'); + } + }); + this.initResize(); + this.refreshRanges(); + // apply last scroll if any + if (this.last.scrollTop != '' && records.length > 0) { + columns.prop('scrollLeft', this.last.scrollLeft); + records.prop('scrollTop', this.last.scrollTop); + records.prop('scrollLeft', this.last.scrollLeft); + } + }, + + getSearchesHTML: function () { + var html = ''; + var showBtn = false; + for (var i = 0; i < this.searches.length; i++) { + var s = this.searches[i]; + s.type = String(s.type).toLowerCase(); + if (s.hidden) continue; + var btn = ''; + if (showBtn == false) { + btn = ''+ + ' ' + + ' ' + + ' '+ + ' ' + + ''; + } + html += ''+ + ' '+ + '
      '+ btn +''+ s.caption +''+ operator + + '
      '+ + '
      '; + + switch (s.type) { + case 'text': + case 'alphanumeric': + case 'hex': + case 'list': + case 'combo': + case 'enum': + html += ''; + break; + + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + html += ''+ + ''; + break; + + case 'select': + html += ''; + break; + + } + html += s.outTag + + '
      '+ + '
      '+ + ' '+ + ' '+ + '
      '+ + '
      '; + return html; + }, + + initOperator: function (el, search_ind) { + var obj = this; + var search = obj.searches[search_ind]; + var range = $('#grid_'+ obj.name + '_range_'+ search_ind); + var fld1 = $('#grid_'+ obj.name +'_field_'+ search_ind); + var fld2 = fld1.parent().find('span input'); + if ($(el).val() == 'in') { fld1.w2field('clear'); } else { fld1.w2field(search.type); } + if ($(el).val() == 'between') { range.show(); fld2.w2field(search.type); } else { range.hide(); } + }, + + initSearches: function () { + var obj = this; + // init searches + for (var s in this.searches) { + var search = this.searches[s]; + var sdata = this.getSearchData(search.field); + search.type = String(search.type).toLowerCase(); + if (typeof search.options != 'object') search.options = {}; + // init types + switch (search.type) { + case 'text': + case 'alphanumeric': + $('#grid_'+ this.name +'_operator_'+s).val('begins'); + if (['alphanumeric', 'hex'].indexOf(search.type) != -1) { + $('#grid_'+ this.name +'_field_' + s).w2field(search.type, search.options); + } + break; + + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + if (sdata && sdata.type == 'int' && sdata.operator == 'in') break; + $('#grid_'+ this.name +'_field_'+s).w2field(search.type, search.options); + $('#grid_'+ this.name +'_field2_'+s).w2field(search.type, search.options); + setTimeout(function () { // convert to date if it is number + $('#grid_'+ obj.name +'_field_'+s).keydown(); + $('#grid_'+ obj.name +'_field2_'+s).keydown(); + }, 1); + break; + + case 'hex': + break; + + case 'list': + case 'combo': + case 'enum': + var options = search.options; + if (search.type == 'list') options.selected = {}; + if (search.type == 'enum') options.selected = []; + if (sdata) options.selected = sdata.value; + $('#grid_'+ this.name +'_field_'+s).w2field(search.type, options); + if (search.type == 'combo') { + $('#grid_'+ this.name +'_operator_'+s).val('begins'); + } + break; + + case 'select': + // build options + var options = ''; + for (var i in search.options.items) { + var si = search.options.items[i]; + if ($.isPlainObject(search.options.items[i])) { + var val = si.id; + var txt = si.text; + if (typeof val == 'undefined' && typeof si.value != 'undefined') val = si.value; + if (typeof txt == 'undefined' && typeof si.caption != 'undefined') txt = si.caption; + if (val == null) val = ''; + options += ''; + } else { + options += ''; + } + } + $('#grid_'+ this.name +'_field_'+s).html(options); + break; + } + if (sdata != null) { + if (sdata.type == 'int' && sdata.operator == 'in') { + $('#grid_'+ this.name +'_field_'+ s).w2field('clear').val(sdata.value); + } + $('#grid_'+ this.name +'_operator_'+ s).val(sdata.operator).trigger('change'); + if (!$.isArray(sdata.value)) { + if (typeof sdata.value != 'udefined') $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); + } else { + if (sdata.operator == 'in') { + $('#grid_'+ this.name +'_field_'+ s).val(sdata.value).trigger('change'); + } else { + $('#grid_'+ this.name +'_field_'+ s).val(sdata.value[0]).trigger('change'); + $('#grid_'+ this.name +'_field2_'+ s).val(sdata.value[1]).trigger('change'); + } + } + } + } + // add on change event + $('#w2ui-overlay-searches-'+ this.name +' .w2ui-grid-searches *[rel=search]').on('keypress', function (evnt) { + if (evnt.keyCode == 13 && (evnt.ctrlKey || evnt.metaKey)) { + obj.search(); + $().w2overlay(); + } + }); + }, + + getColumnsHTML: function () { + var obj = this; + var html = ''; + if (this.show.columnHeaders) { + if (this.columnGroups.length > 0) { + html = getColumns(true) + getGroups() + getColumns(false); + } else { + html = getColumns(true); + } + } + return html; + + function getGroups () { + var html = ''; + // add empty group at the end + if (obj.columnGroups[obj.columnGroups.length-1].caption != '') obj.columnGroups.push({ caption: '' }); + + if (obj.show.lineNumbers) { + html += ''+ + '
       
      '+ + ''; + } + if (obj.show.selectColumn) { + html += ''+ + '
       
      '+ + ''; + } + if (obj.show.expandColumn) { + html += ''+ + '
       
      '+ + ''; + } + var ii = 0; + for (var i=0; i
      '; + } + html += ''+ + resizer + + '
      '+ + '
      '+ + (!col.caption ? ' ' : col.caption) + + '
      '+ + ''; + } else { + html += ''+ + '
      '+ + (!colg.caption ? ' ' : colg.caption) + + '
      '+ + ''; + } + ii += colg.span; + } + html += ''; + return html; + } + + function getColumns (master) { + var html = '', + reorderCols = (obj.reorderColumns && (!obj.columnGroups || !obj.columnGroups.length)) ? ' w2ui-reorder-cols-head ' : ''; + if (obj.show.lineNumbers) { + html += ''+ + '
      #
      '+ + ''; + } + if (obj.show.selectColumn) { + html += ''+ + '
      '+ + ' '+ + '
      '+ + ''; + } + if (obj.show.expandColumn) { + html += ''+ + '
       
      '+ + ''; + } + var ii = 0; + var id = 0; + for (var i=0; i
      '; + } + html += ''+ + resizer + + '
      '+ + '
      '+ + (!col.caption ? ' ' : col.caption) + + '
      '+ + ''; + } + } + html += '
       
      '; + html += ''; + return html; + } + }, + + getRecordsHTML: function () { + // larget number works better with chrome, smaller with FF. + if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; + var records = $('#grid_'+ this.name +'_records'); + var limit = Math.floor(records.height() / this.recordHeight) + this.show_extra + 1; + if (!this.fixedBody) limit = this.buffered; + // always need first record for resizing purposes + var html = '' + this.getRecordHTML(-1, 0); + // first empty row with height + html += ''+ + ' '+ + ''; + for (var i = 0; i < limit; i++) { + html += this.getRecordHTML(i, i+1); + } + html += ''+ + ' '+ + ''+ + ''+ + ' '+ + ''+ + '
      '; + this.last.range_start = 0; + this.last.range_end = limit; + return html; + }, + + getSummaryHTML: function () { + if (this.summary.length == 0) return; + var html = ''; + for (var i = 0; i < this.summary.length; i++) { + html += this.getRecordHTML(i, i+1, true); + } + html += '
      '; + return html; + }, + + scroll: function (event) { + var time = (new Date()).getTime(); + var obj = this; + var records = $('#grid_'+ this.name +'_records'); + if (this.records.length == 0 || records.length == 0 || records.height() == 0) return; + if (this.buffered > 300) this.show_extra = 30; else this.show_extra = 300; + // need this to enable scrolling when this.limit < then a screen can fit + if (records.height() < this.buffered * this.recordHeight && records.css('overflow-y') == 'hidden') { + if (this.total > 0) this.refresh(); + return; + } + // update footer + var t1 = Math.round(records[0].scrollTop / this.recordHeight + 1); + var t2 = t1 + (Math.round(records.height() / this.recordHeight) - 1); + if (t1 > this.buffered) t1 = this.buffered; + if (t2 > this.buffered) t2 = this.buffered; + var url = (typeof this.url != 'object' ? this.url : this.url.get); + $('#grid_'+ this.name + '_footer .w2ui-footer-right').html(w2utils.formatNumber(this.offset + t1) + '-' + w2utils.formatNumber(this.offset + t2) + ' ' + w2utils.lang('of') + ' ' + w2utils.formatNumber(this.total) + + (url ? ' ('+ w2utils.lang('buffered') + ' '+ w2utils.formatNumber(this.buffered) + (this.offset > 0 ? ', skip ' + w2utils.formatNumber(this.offset) : '') + ')' : '') + ); + // only for local data source, else no extra records loaded + if (!url && (!this.fixedBody || this.total <= 300)) return; + // regular processing + var start = Math.floor(records[0].scrollTop / this.recordHeight) - this.show_extra; + var end = start + Math.floor(records.height() / this.recordHeight) + this.show_extra * 2 + 1; + // var div = start - this.last.range_start; + if (start < 1) start = 1; + if (end > this.total) end = this.total; + var tr1 = records.find('#grid_'+ this.name +'_rec_top'); + var tr2 = records.find('#grid_'+ this.name +'_rec_bottom'); + // if row is expanded + if (String(tr1.next().prop('id')).indexOf('_expanded_row') != -1) tr1.next().remove(); + if (this.total > end && String(tr2.prev().prop('id')).indexOf('_expanded_row') != -1) tr2.prev().remove(); + var first = parseInt(tr1.next().attr('line')); + var last = parseInt(tr2.prev().attr('line')); + //$('#log').html('buffer: '+ this.buffered +' start-end: ' + start + '-'+ end + ' ===> first-last: ' + first + '-' + last); + if (first < start || first == 1 || this.last.pull_refresh) { // scroll down + // console.log('end', end, 'last', last, 'show_extre', this.show_extra, this.last.pull_refresh); + if (end <= last + this.show_extra - 2 && end != this.total) return; + this.last.pull_refresh = false; + // remove from top + while (true) { + var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); + if (tmp.attr('line') == 'bottom') break; + if (parseInt(tmp.attr('line')) < start) tmp.remove(); else break; + } + // add at bottom + var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); + var rec_start = tmp.attr('line'); + if (rec_start == 'top') rec_start = start; + for (var i = parseInt(rec_start) + 1; i <= end; i++) { + if (!this.records[i-1]) continue; + if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; + tr2.before(this.getRecordHTML(i-1, i)); + } + markSearch(); + setTimeout(function() { obj.refreshRanges(); }, 0); + } else { // scroll up + if (start >= first - this.show_extra + 2 && start > 1) return; + // remove from bottom + while (true) { + var tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev(); + if (tmp.attr('line') == 'top') break; + if (parseInt(tmp.attr('line')) > end) tmp.remove(); else break; + } + // add at top + var tmp = records.find('#grid_'+ this.name +'_rec_top').next(); + var rec_start = tmp.attr('line'); + if (rec_start == 'bottom') rec_start = end; + for (var i = parseInt(rec_start) - 1; i >= start; i--) { + if (!this.records[i-1]) continue; + if (this.records[i-1].expanded === true) this.records[i-1].expanded = false; + tr1.after(this.getRecordHTML(i-1, i)); + } + markSearch(); + setTimeout(function() { obj.refreshRanges(); }, 0); + } + // first/last row size + var h1 = (start - 1) * obj.recordHeight; + var h2 = (this.buffered - end) * obj.recordHeight; + if (h2 < 0) h2 = 0; + tr1.css('height', h1 + 'px'); + tr2.css('height', h2 + 'px'); + obj.last.range_start = start; + obj.last.range_end = end; + // load more if needed + var s = Math.floor(records[0].scrollTop / this.recordHeight); + var e = s + Math.floor(records.height() / this.recordHeight); + if (e + 10 > this.buffered && this.last.pull_more !== true && this.buffered < this.total - this.offset) { + if (this.autoLoad === true) { + this.last.pull_more = true; + this.last.xhr_offset += this.limit; + this.request('get-records'); + } else { + var more = $('#grid_'+ this.name +'_rec_more'); + if (more.css('display') == 'none') { + more.show() + .on('click', function () { + obj.last.pull_more = true; + obj.last.xhr_offset += obj.limit; + obj.request('get-records'); + // show spinner the last + $(this).find('td').html('
      '); + }); + } + if (more.find('td').text().indexOf('Load') == -1) { + more.find('td').html('
      '+ w2utils.lang('Load') + ' ' + obj.limit + ' ' + w2utils.lang('More') + '...
      '); + } + } + } + // check for grid end + if (this.buffered >= this.total - this.offset) $('#grid_'+ this.name +'_rec_more').hide(); + return; + + function markSearch() { + // mark search + if(obj.markSearch === false) return; + clearTimeout(obj.last.marker_timer); + obj.last.marker_timer = setTimeout(function () { + // mark all search strings + var str = []; + for (var s in obj.searchData) { + var tmp = obj.searchData[s]; + if ($.inArray(tmp.value, str) == -1) str.push(tmp.value); + } + if (str.length > 0) $(obj.box).find('.w2ui-grid-data > div').w2marker(str); + }, 50); + } + }, + + getRecordHTML: function (ind, lineNum, summary) { + var rec_html = ''; + var sel = this.last.selection; + var record; + // first record needs for resize purposes + if (ind == -1) { + rec_html += ''; + if (this.show.lineNumbers) rec_html += ''; + if (this.show.selectColumn) rec_html += ''; + if (this.show.expandColumn) rec_html += ''; + for (var i in this.columns) { + if (this.columns[i].hidden) continue; + rec_html += ''; + } + rec_html += ''; + rec_html += ''; + return rec_html; + } + // regular record + var url = (typeof this.url != 'object' ? this.url : this.url.get); + if (summary !== true) { + if (this.searchData.length > 0 && !url) { + if (ind >= this.last.searchIds.length) return ''; + ind = this.last.searchIds[ind]; + record = this.records[ind]; + } else { + if (ind >= this.records.length) return ''; + record = this.records[ind]; + } + } else { + if (ind >= this.summary.length) return ''; + record = this.summary[ind]; + } + if (!record) return ''; + var id = w2utils.escapeId(record.recid); + var isRowSelected = false; + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true; + // render TR + rec_html += ''; + if (this.show.lineNumbers) { + rec_html += ''+ + (summary !== true ? '
      '+ lineNum +'
      ' : '') + + ''; + } + if (this.show.selectColumn) { + rec_html += + ''+ + (summary !== true ? + '
      '+ + ' '+ + '
      ' + : + '' ) + + ''; + } + if (this.show.expandColumn) { + var tmp_img = ''; + if (record.expanded === true) tmp_img = '-'; else tmp_img = '+'; + if (record.expanded == 'none') tmp_img = ''; + if (record.expanded == 'spinner') tmp_img = '
      '; + rec_html += + ''+ + (summary !== true ? + '
      '+ + ' '+ tmp_img +'
      ' + : + '' ) + + ''; + } + var col_ind = 0; + while (true) { + var col = this.columns[col_ind]; + if (col.hidden) { col_ind++; if (typeof this.columns[col_ind] == 'undefined') break; else continue; } + var isChanged = !summary && record.changes && typeof record.changes[col.field] != 'undefined'; + var rec_cell = this.getCellHTML(ind, col_ind, summary); + var addStyle = ''; + if (typeof col.render == 'string') { + var tmp = col.render.toLowerCase().split(':'); + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) addStyle += 'text-align: right;'; + } + if (typeof record.style == 'object' && typeof record.style[col_ind] == 'string') { + addStyle += record.style[col_ind] + ';'; + } + var isCellSelected = false; + if (isRowSelected && $.inArray(col_ind, sel.columns[ind]) != -1) isCellSelected = true; + rec_html += ''+ + rec_cell + + ''; + col_ind++; + if (typeof this.columns[col_ind] == 'undefined') break; + } + rec_html += ''; + rec_html += ''; + return rec_html; + }, + + getCellHTML: function (ind, col_ind, summary) { + var col = this.columns[col_ind]; + var record = (summary !== true ? this.records[ind] : this.summary[ind]); + var data = this.getCellValue(ind, col_ind, summary); + var edit = col.editable; + // various renderers + if (typeof col.render != 'undefined') { + if (typeof col.render == 'function') { + data = $.trim(col.render.call(this, record, ind, col_ind)); + if (data.length < 4 || data.substr(0, 4).toLowerCase() != ''; + } + if (typeof col.render == 'object') data = '
      ' + col.render[data] + '
      '; + if (typeof col.render == 'string') { + var tmp = col.render.toLowerCase().split(':'); + var prefix = ''; + var suffix = ''; + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(tmp[0]) != -1) { + if (typeof tmp[1] == 'undefined' || !w2utils.isInt(tmp[1])) tmp[1] = 0; + if (tmp[1] > 20) tmp[1] = 20; + if (tmp[1] < 0) tmp[1] = 0; + if (['money', 'currency'].indexOf(tmp[0]) != -1) { tmp[1] = w2utils.settings.currencyPrecision; prefix = w2utils.settings.currencyPrefix; suffix = w2utils.settings.currencySuffix } + if (tmp[0] == 'percent') { suffix = '%'; if (tmp[1] !== '0') tmp[1] = 1; } + if (tmp[0] == 'int') { tmp[1] = 0; } + // format + data = '
      ' + (data !== '' ? prefix + w2utils.formatNumber(Number(data).toFixed(tmp[1])) + suffix : '') + '
      '; + } + if (tmp[0] == 'time') { + if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.time_format; + data = '
      ' + prefix + w2utils.formatTime(data, tmp[1] == 'h12' ? 'hh:mi pm': 'h24:min') + suffix + '
      '; + } + if (tmp[0] == 'date') { + if (typeof tmp[1] == 'undefined' || tmp[1] == '') tmp[1] = w2utils.settings.date_display; + data = '
      ' + prefix + w2utils.formatDate(data, tmp[1]) + suffix + '
      '; + } + if (tmp[0] == 'age') { + data = '
      ' + prefix + w2utils.age(data) + suffix + '
      '; + } + } + } else { + // if editable checkbox + var addStyle = ''; + if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { + var changeInd = summary ? -(ind + 1) : ind; + addStyle = 'text-align: center'; + data = ''; + } + if (!this.show.recordTitles) { + var data = '
      '+ data +'
      '; + } else { + // title overwrite + var title = String(data).replace(/"/g, "''"); + if (typeof col.title != 'undefined') { + if (typeof col.title == 'function') title = col.title.call(this, record, ind, col_ind); + if (typeof col.title == 'string') title = col.title; + } + var data = '
      '+ data +'
      '; + } + } + if (data == null || typeof data == 'undefined') data = ''; + return data; + }, + + getCellValue: function (ind, col_ind, summary) { + var col = this.columns[col_ind]; + var record = (summary !== true ? this.records[ind] : this.summary[ind]); + var data = this.parseField(record, col.field); + if (record.changes && typeof record.changes[col.field] != 'undefined') data = record.changes[col.field]; + if (data == null || typeof data == 'undefined') data = ''; + return data; + }, + + getFooterHTML: function () { + return '
      '+ + ' '+ + ' '+ + ' '+ + '
      '; + }, + + status: function (msg) { + if (typeof msg != 'undefined') { + $('#grid_'+ this.name +'_footer').find('.w2ui-footer-left').html(msg); + } else { + // show number of selected + var msgLeft = ''; + var sel = this.getSelection(); + if (sel.length > 0) { + msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") + ' ' + w2utils.lang('selected'); + var tmp = sel[0]; + if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column; + if (sel.length == 1) msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' '; + } + $('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft); + // toolbar + if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); + if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); + } + }, + + lock: function (msg, showSpinner) { + var box = $(this.box).find('> div:first-child'); + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(box); + setTimeout(function () { w2utils.lock.apply(window, args); }, 10); + }, + + unlock: function () { + var box = this.box; + setTimeout(function () { w2utils.unlock(box); }, 25); // needed timer so if server fast, it will not flash + }, + + parseField: function (obj, field) { + var val = ''; + try { // need this to make sure no error in fields + val = obj; + var tmp = String(field).split('.'); + for (var i in tmp) { + val = val[tmp[i]]; + } + } catch (event) { + val = ''; + } + return val; + }, + + prepareData: function () { + // loops thru records and prepares date and time objects + for (var r in this.records) { + var rec = this.records[r]; + for (var c in this.columns) { + var column = this.columns[c]; + if (rec[column.field] == null || typeof column.render != 'string') continue; + // number + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { + if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]); + } + // date + if (['date', 'age'].indexOf(column.render) != -1) { + if (!rec[column.field + '_']) { + var dt = rec[column.field]; + if (w2utils.isInt(dt)) dt = parseInt(dt); + rec[column.field + '_'] = new Date(dt); + } + } + // time + if (['time'].indexOf(column.render) != -1) { + if (w2utils.isTime(rec[column.field])) { // if string + var tmp = w2utils.isTime(rec[column.field], true); + var dt = new Date(); + dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0); // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt; + } else { // if date object + var tmp = rec[column.field]; + if (w2utils.isInt(tmp)) tmp = parseInt(tmp); + var tmp = (tmp != null ? new Date(tmp) : new Date()); + var dt = new Date(); + dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0); // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt; + } + } + } + } + }, + + nextCell: function (col_ind, editable) { + var check = col_ind + 1; + if (this.columns.length == check) return false; + if (editable === true) { + var edit = this.columns[check].editable; + if (this.columns[check].hidden || typeof edit == 'undefined' + || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.nextCell(check, editable); + } + return check; + }, + + prevCell: function (col_ind, editable) { + var check = col_ind - 1; + if (check < 0) return false; + if (editable === true) { + var edit = this.columns[check].editable; + if (this.columns[check].hidden || typeof edit == 'undefined' + || (edit && ['checkbox', 'check'].indexOf(edit.type) != -1)) return this.prevCell(check, editable); + } + return check; + }, + + nextRow: function (ind) { + if ((ind + 1 < this.records.length && this.last.searchIds.length == 0) // if there are more records + || (this.last.searchIds.length > 0 && ind < this.last.searchIds[this.last.searchIds.length-1])) { + ind++; + if (this.last.searchIds.length > 0) { + while (true) { + if ($.inArray(ind, this.last.searchIds) != -1 || ind > this.records.length) break; + ind++; + } + } + return ind; + } else { + return null; + } + }, + + prevRow: function (ind) { + if ((ind > 0 && this.last.searchIds.length == 0) // if there are more records + || (this.last.searchIds.length > 0 && ind > this.last.searchIds[0])) { + ind--; + if (this.last.searchIds.length > 0) { + while (true) { + if ($.inArray(ind, this.last.searchIds) != -1 || ind < 0) break; + ind--; + } + } + return ind; + } else { + return null; + } + } + }; + + $.extend(w2grid.prototype, w2utils.event); + w2obj.grid = w2grid; })(); diff --git a/src/w2layout.js b/src/w2layout.js index bd19fad6d..721955485 100644 --- a/src/w2layout.js +++ b/src/w2layout.js @@ -1,1079 +1,1079 @@ /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2layout - layout widget -* - $().w2layout - jQuery wrapper -* - Dependencies: jQuery, w2utils, w2toolbar, w2tabs +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2layout - layout widget +* - $().w2layout - jQuery wrapper +* - Dependencies: jQuery, w2utils, w2toolbar, w2tabs * * == NICE TO HAVE == -* - onResize for the panel -* - add more panel title positions (left=rotated, right=rotated, bottom) -* - bug: resizer is visible (and onHover) when panel is hidden. +* - onResize for the panel +* - add more panel title positions (left=rotated, right=rotated, bottom) +* - bug: resizer is visible (and onHover) when panel is hidden. * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - added panel title -* - added panel.maxSize property -* - fixed resize bugs -* - BUG resize problems (resizer flashes, not very snappy, % should stay in percent) -* - added onResizerClick event +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - added panel title +* - added panel.maxSize property +* - fixed resize bugs +* - BUG resize problems (resizer flashes, not very snappy, % should stay in percent) +* - added onResizerClick event * ************************************************************************/ (function () { - var w2layout = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.panels = []; - this.tmp = {}; + var w2layout = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.panels = []; + this.tmp = {}; - this.padding = 1; // panel padding - this.resizer = 4; // resizer width or height - this.style = ''; + this.padding = 1; // panel padding + this.resizer = 4; // resizer width or height + this.style = ''; - this.onShow = null; - this.onHide = null; - this.onResizing = null; - this.onResizerClick = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; + this.onShow = null; + this.onHide = null; + this.onResizing = null; + this.onResizerClick = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; - $.extend(true, this, w2obj.layout, options); - }; + $.extend(true, this, w2obj.layout, options); + }; - /* @const */ var w2layout_panels = ['top', 'left', 'main', 'preview', 'right', 'bottom']; + /* @const */ var w2layout_panels = ['top', 'left', 'main', 'preview', 'right', 'bottom']; - // ==================================================== - // -- Registers as a jQuery plugin + // ==================================================== + // -- Registers as a jQuery plugin - $.fn.w2layout = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2layout')) return; - var panels = method.panels || []; - var object = new w2layout(method); - $.extend(object, { handlers: [], panels: [] }); - // add defined panels - for (var p = 0, len = panels.length; p < len; p++) { - object.panels[p] = $.extend(true, {}, w2layout.prototype.panel, panels[p]); - if ($.isPlainObject(object.panels[p].tabs) || $.isArray(object.panels[p].tabs)) initTabs(object, panels[p].type); - if ($.isPlainObject(object.panels[p].toolbar) || $.isArray(object.panels[p].toolbar)) initToolbar(object, panels[p].type); - } - // add all other panels - for (var p1 in w2layout_panels) { - p1 = w2layout_panels[p1]; - if (object.get(p1) !== null) continue; - object.panels.push($.extend(true, {}, w2layout.prototype.panel, { type: p1, hidden: (p1 !== 'main'), size: 50 })); - } - if ($(this).length > 0) { - object.render($(this)[0]); - } - w2ui[object.name] = object; - return object; + $.fn.w2layout = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2layout')) return; + var panels = method.panels || []; + var object = new w2layout(method); + $.extend(object, { handlers: [], panels: [] }); + // add defined panels + for (var p = 0, len = panels.length; p < len; p++) { + object.panels[p] = $.extend(true, {}, w2layout.prototype.panel, panels[p]); + if ($.isPlainObject(object.panels[p].tabs) || $.isArray(object.panels[p].tabs)) initTabs(object, panels[p].type); + if ($.isPlainObject(object.panels[p].toolbar) || $.isArray(object.panels[p].toolbar)) initToolbar(object, panels[p].type); + } + // add all other panels + for (var p1 in w2layout_panels) { + p1 = w2layout_panels[p1]; + if (object.get(p1) !== null) continue; + object.panels.push($.extend(true, {}, w2layout.prototype.panel, { type: p1, hidden: (p1 !== 'main'), size: 50 })); + } + if ($(this).length > 0) { + object.render($(this)[0]); + } + w2ui[object.name] = object; + return object; - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2layout' ); - } + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2layout' ); + } - function initTabs(object, panel, tabs) { - var pan = object.get(panel); - if (pan !== null && typeof tabs == 'undefined') tabs = pan.tabs; - if (pan === null || tabs === null) return false; - // instanciate tabs - if ($.isArray(tabs)) tabs = { tabs: tabs }; - $().w2destroy(object.name + '_' + panel + '_tabs'); // destroy if existed - pan.tabs = $().w2tabs($.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })); - pan.show.tabs = true; - return true; - } + function initTabs(object, panel, tabs) { + var pan = object.get(panel); + if (pan !== null && typeof tabs == 'undefined') tabs = pan.tabs; + if (pan === null || tabs === null) return false; + // instanciate tabs + if ($.isArray(tabs)) tabs = { tabs: tabs }; + $().w2destroy(object.name + '_' + panel + '_tabs'); // destroy if existed + pan.tabs = $().w2tabs($.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })); + pan.show.tabs = true; + return true; + } - function initToolbar(object, panel, toolbar) { - var pan = object.get(panel); - if (pan !== null && typeof toolbar == 'undefined') toolbar = pan.toolbar; - if (pan === null || toolbar === null) return false; - // instanciate toolbar - if ($.isArray(toolbar)) toolbar = { items: toolbar }; - $().w2destroy(object.name + '_' + panel + '_toolbar'); // destroy if existed - pan.toolbar = $().w2toolbar($.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })); - pan.show.toolbar = true; - return true; - } - }; + function initToolbar(object, panel, toolbar) { + var pan = object.get(panel); + if (pan !== null && typeof toolbar == 'undefined') toolbar = pan.toolbar; + if (pan === null || toolbar === null) return false; + // instanciate toolbar + if ($.isArray(toolbar)) toolbar = { items: toolbar }; + $().w2destroy(object.name + '_' + panel + '_toolbar'); // destroy if existed + pan.toolbar = $().w2toolbar($.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })); + pan.show.toolbar = true; + return true; + } + }; - // ==================================================== - // -- Implementation of core functionality + // ==================================================== + // -- Implementation of core functionality - w2layout.prototype = { - // default setting for a panel - panel: { - title : '', - type : null, // left, right, top, bottom - size : 100, // width or height depending on panel name - minSize : 20, - maxSize : false, - hidden : false, - resizable : false, - overflow : 'auto', - style : '', - content : '', // can be String or Object with .render(box) method - tabs : null, - toolbar : null, - width : null, // read only - height : null, // read only - show : { - toolbar : false, - tabs : false - }, - onRefresh : null, - onShow : null, - onHide : null - }, + w2layout.prototype = { + // default setting for a panel + panel: { + title : '', + type : null, // left, right, top, bottom + size : 100, // width or height depending on panel name + minSize : 20, + maxSize : false, + hidden : false, + resizable : false, + overflow : 'auto', + style : '', + content : '', // can be String or Object with .render(box) method + tabs : null, + toolbar : null, + width : null, // read only + height : null, // read only + show : { + toolbar : false, + tabs : false + }, + onRefresh : null, + onShow : null, + onHide : null + }, - // alias for content - html: function (panel, data, transition) { - return this.content(panel, data, transition); - }, + // alias for content + html: function (panel, data, transition) { + return this.content(panel, data, transition); + }, - content: function (panel, data, transition) { - var obj = this; - var p = this.get(panel); - // if it is CSS panel - if (panel == 'css') { - $('#layout_'+ obj.name +'_panel_css').html(''); - return true; - } - if (p === null) return false; - if (typeof data == 'undefined' || data === null) { - return p.content; - } else { - if (data instanceof jQuery) { - console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); - return false; - } - var pname = '#layout_'+ this.name + '_panel_'+ p.type; - var current = $(pname + '> .w2ui-panel-content'); - var panelTop = 0; - if (current.length > 0) { - $(pname).scrollTop(0); - panelTop = $(current).position().top; - } - if (p.content === '') { - p.content = data; - this.refresh(panel); - } else { - p.content = data; - if (!p.hidden) { - if (transition !== null && transition !== '' && typeof transition != 'undefined') { - // apply transition - var div1 = $(pname + '> .w2ui-panel-content'); - div1.after('
      '); - var div2 = $(pname + '> .w2ui-panel-content.new-panel'); - div1.css('top', panelTop); - div2.css('top', panelTop); - if (typeof data == 'object') { - data.box = div2[0]; // do not do .render(box); - data.render(); - } else { - div2.html(data); - } - w2utils.transition(div1[0], div2[0], transition, function () { - div1.remove(); - div2.removeClass('new-panel'); - div2.css('overflow', p.overflow); - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - }); - } - } - this.refresh(panel); - } - } - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - return true; - }, + content: function (panel, data, transition) { + var obj = this; + var p = this.get(panel); + // if it is CSS panel + if (panel == 'css') { + $('#layout_'+ obj.name +'_panel_css').html(''); + return true; + } + if (p === null) return false; + if (typeof data == 'undefined' || data === null) { + return p.content; + } else { + if (data instanceof jQuery) { + console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); + return false; + } + var pname = '#layout_'+ this.name + '_panel_'+ p.type; + var current = $(pname + '> .w2ui-panel-content'); + var panelTop = 0; + if (current.length > 0) { + $(pname).scrollTop(0); + panelTop = $(current).position().top; + } + if (p.content === '') { + p.content = data; + this.refresh(panel); + } else { + p.content = data; + if (!p.hidden) { + if (transition !== null && transition !== '' && typeof transition != 'undefined') { + // apply transition + var div1 = $(pname + '> .w2ui-panel-content'); + div1.after('
      '); + var div2 = $(pname + '> .w2ui-panel-content.new-panel'); + div1.css('top', panelTop); + div2.css('top', panelTop); + if (typeof data == 'object') { + data.box = div2[0]; // do not do .render(box); + data.render(); + } else { + div2.html(data); + } + w2utils.transition(div1[0], div2[0], transition, function () { + div1.remove(); + div2.removeClass('new-panel'); + div2.css('overflow', p.overflow); + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + }); + } + } + this.refresh(panel); + } + } + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + return true; + }, - load: function (panel, url, transition, onLoad) { - var obj = this; - if (panel == 'css') { - $.get(url, function (data, status, xhr) { - obj.content(panel, xhr.responseText); - if (onLoad) onLoad(); - }); - return true; - } - if (this.get(panel) !== null) { - $.get(url, function (data, status, xhr) { - obj.content(panel, xhr.responseText, transition); - if (onLoad) onLoad(); - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - }); - return true; - } - return false; - }, + load: function (panel, url, transition, onLoad) { + var obj = this; + if (panel == 'css') { + $.get(url, function (data, status, xhr) { + obj.content(panel, xhr.responseText); + if (onLoad) onLoad(); + }); + return true; + } + if (this.get(panel) !== null) { + $.get(url, function (data, status, xhr) { + obj.content(panel, xhr.responseText, transition); + if (onLoad) onLoad(); + // IE Hack + obj.resize(); + if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); + }); + return true; + } + return false; + }, - sizeTo: function (panel, size) { - var obj = this; - var pan = obj.get(panel); - if (pan === null) return false; - // resize - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s' - }); - setTimeout(function () { - obj.set(panel, { size: size }); - }, 1); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '0s', - '-moz-transition' : '0s', - '-ms-transition' : '0s', - '-o-transition' : '0s' - }); - obj.resize(); - }, 500); - return true; - }, + sizeTo: function (panel, size) { + var obj = this; + var pan = obj.get(panel); + if (pan === null) return false; + // resize + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s' + }); + setTimeout(function () { + obj.set(panel, { size: size }); + }, 1); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '0s', + '-moz-transition' : '0s', + '-ms-transition' : '0s', + '-o-transition' : '0s' + }); + obj.resize(); + }, 500); + return true; + }, - show: function (panel, immediate) { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', type: 'show', target: panel, object: this.get(panel), immediate: immediate }); - if (eventData.isCancelled === true) return; + show: function (panel, immediate) { + var obj = this; + // event before + var eventData = this.trigger({ phase: 'before', type: 'show', target: panel, object: this.get(panel), immediate: immediate }); + if (eventData.isCancelled === true) return; - var p = obj.get(panel); - if (p === null) return false; - p.hidden = false; - if (immediate === true) { - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '1' }); - if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - } else { - if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); - // resize - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s' - }); - setTimeout(function () { obj.resize(); }, 1); - // show - setTimeout(function() { - $('#layout_'+ obj.name +'_panel_'+ panel).css({ 'opacity': '1' }); - }, 250); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '0s', - '-moz-transition' : '0s', - '-ms-transition' : '0s', - '-o-transition' : '0s' - }); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - }, 500); - } - return true; - }, + var p = obj.get(panel); + if (p === null) return false; + p.hidden = false; + if (immediate === true) { + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '1' }); + if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + } else { + if (p.resizable) $('#layout_'+ obj.name +'_resizer_'+panel).show(); + // resize + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s' + }); + setTimeout(function () { obj.resize(); }, 1); + // show + setTimeout(function() { + $('#layout_'+ obj.name +'_panel_'+ panel).css({ 'opacity': '1' }); + }, 250); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '0s', + '-moz-transition' : '0s', + '-ms-transition' : '0s', + '-o-transition' : '0s' + }); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + }, 500); + } + return true; + }, - hide: function (panel, immediate) { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', type: 'hide', target: panel, object: this.get(panel), immediate: immediate }); - if (eventData.isCancelled === true) return; + hide: function (panel, immediate) { + var obj = this; + // event before + var eventData = this.trigger({ phase: 'before', type: 'hide', target: panel, object: this.get(panel), immediate: immediate }); + if (eventData.isCancelled === true) return; - var p = obj.get(panel); - if (p === null) return false; - p.hidden = true; - if (immediate === true) { - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - $('#layout_'+ obj.name +'_resizer_'+panel).hide(); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - } else { - $('#layout_'+ obj.name +'_resizer_'+panel).hide(); - // hide - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s' - }); - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - setTimeout(function () { obj.resize(); }, 1); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css({ - '-webkit-transition': '0s', - '-moz-transition' : '0s', - '-ms-transition' : '0s', - '-o-transition' : '0s' - }); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - }, 500); - } - return true; - }, + var p = obj.get(panel); + if (p === null) return false; + p.hidden = true; + if (immediate === true) { + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + $('#layout_'+ obj.name +'_resizer_'+panel).hide(); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + } else { + $('#layout_'+ obj.name +'_resizer_'+panel).hide(); + // hide + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s' + }); + $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); + setTimeout(function () { obj.resize(); }, 1); + // clean + setTimeout(function () { + $(obj.box).find(' > div > .w2ui-panel').css({ + '-webkit-transition' : '0s', + '-moz-transition' : '0s', + '-ms-transition' : '0s', + '-o-transition' : '0s' + }); + obj.trigger($.extend(eventData, { phase: 'after' })); + obj.resize(); + }, 500); + } + return true; + }, - toggle: function (panel, immediate) { - var p = this.get(panel); - if (p === null) return false; - if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate); - }, + toggle: function (panel, immediate) { + var p = this.get(panel); + if (p === null) return false; + if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate); + }, - set: function (panel, options) { - var obj = this.get(panel, true); - if (obj === null) return false; - $.extend(this.panels[obj], options); - if (typeof options['content'] != 'undefined') this.refresh(panel); // refresh only when content changed - this.resize(); // resize is needed when panel size is changed - return true; - }, + set: function (panel, options) { + var obj = this.get(panel, true); + if (obj === null) return false; + $.extend(this.panels[obj], options); + if (typeof options['content'] != 'undefined') this.refresh(panel); // refresh only when content changed + this.resize(); // resize is needed when panel size is changed + return true; + }, - get: function (panel, returnIndex) { - for (var p in this.panels) { - if (this.panels[p].type == panel) { - if (returnIndex === true) return p; else return this.panels[p]; - } - } - return null; - }, + get: function (panel, returnIndex) { + for (var p in this.panels) { + if (this.panels[p].type == panel) { + if (returnIndex === true) return p; else return this.panels[p]; + } + } + return null; + }, - el: function (panel) { - var el = $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content'); - if (el.length != 1) return null; - return el[0]; - }, + el: function (panel) { + var el = $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content'); + if (el.length != 1) return null; + return el[0]; + }, - hideToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.toolbar = false; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide(); - this.resize(); - }, + hideToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.toolbar = false; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide(); + this.resize(); + }, - showToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.toolbar = true; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show(); - this.resize(); - }, + showToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.toolbar = true; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show(); + this.resize(); + }, - toggleToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel); - }, + toggleToolbar: function (panel) { + var pan = this.get(panel); + if (!pan) return; + if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel); + }, - hideTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.tabs = false; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide(); - this.resize(); - }, + hideTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.tabs = false; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide(); + this.resize(); + }, - showTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.tabs = true; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show(); - this.resize(); - }, + showTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + pan.show.tabs = true; + $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show(); + this.resize(); + }, - toggleTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel); - }, + toggleTabs: function (panel) { + var pan = this.get(panel); + if (!pan) return; + if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel); + }, - render: function (box) { - var obj = this; - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - var time = (new Date()).getTime(); - // event before - var eventData = obj.trigger({ phase: 'before', type: 'render', target: obj.name, box: box }); - if (eventData.isCancelled === true) return; + render: function (box) { + var obj = this; + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + var time = (new Date()).getTime(); + // event before + var eventData = obj.trigger({ phase: 'before', type: 'render', target: obj.name, box: box }); + if (eventData.isCancelled === true) return; - if (typeof box != 'undefined' && box !== null) { - if ($(obj.box).find('#layout_'+ obj.name +'_panel_main').length > 0) { - $(obj.box) - .removeAttr('name') - .removeClass('w2ui-layout') - .html(''); - } - obj.box = box; - } - if (!obj.box) return false; - $(obj.box) - .attr('name', obj.name) - .addClass('w2ui-layout') - .html('
      '); - if ($(obj.box).length > 0) $(obj.box)[0].style.cssText += obj.style; - // create all panels - for (var p1 in w2layout_panels) { - p1 = w2layout_panels[p1]; - var pan = obj.get(p1); - var html = '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '+ - '
      '; - $(obj.box).find(' > div').append(html); - // tabs are rendered in refresh() - } - $(obj.box).find(' > div') - .append('
      0) { + $(obj.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html(''); + } + obj.box = box; + } + if (!obj.box) return false; + $(obj.box) + .attr('name', obj.name) + .addClass('w2ui-layout') + .html('
      '); + if ($(obj.box).length > 0) $(obj.box)[0].style.cssText += obj.style; + // create all panels + for (var p1 in w2layout_panels) { + p1 = w2layout_panels[p1]; + var pan = obj.get(p1); + var html = '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '; + $(obj.box).find(' > div').append(html); + // tabs are rendered in refresh() + } + $(obj.box).find(' > div') + .append('
      panel.width) { - resize_x = panel.minSize - panel.width; - } - if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { - resize_x = panel.maxSize - panel.width; - } - if (mainPanel.minSize + resize_x > mainPanel.width) { - resize_x = mainPanel.width - mainPanel.minSize; - } - break; + switch (tmp.type) { + case 'left': + if (panel.minSize - resize_x > panel.width) { + resize_x = panel.minSize - panel.width; + } + if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { + resize_x = panel.maxSize - panel.width; + } + if (mainPanel.minSize + resize_x > mainPanel.width) { + resize_x = mainPanel.width - mainPanel.minSize; + } + break; - case 'right': - if (panel.minSize + resize_x > panel.width) { - resize_x = panel.width - panel.minSize; - } - if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { - resize_x = panel.width - panel.maxSize; - } - if (mainPanel.minSize - resize_x > mainPanel.width) { - resize_x = mainPanel.minSize - mainPanel.width; - } - break; + case 'right': + if (panel.minSize + resize_x > panel.width) { + resize_x = panel.width - panel.minSize; + } + if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { + resize_x = panel.width - panel.maxSize; + } + if (mainPanel.minSize - resize_x > mainPanel.width) { + resize_x = mainPanel.minSize - mainPanel.width; + } + break; - case 'top': - if (panel.minSize - resize_y > panel.height) { - resize_y = panel.minSize - panel.height; - } - if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { - resize_y = panel.maxSize - panel.height; - } - if (mainPanel.minSize + resize_y > mainPanel.height) { - resize_y = mainPanel.height - mainPanel.minSize; - } - break; + case 'top': + if (panel.minSize - resize_y > panel.height) { + resize_y = panel.minSize - panel.height; + } + if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { + resize_y = panel.maxSize - panel.height; + } + if (mainPanel.minSize + resize_y > mainPanel.height) { + resize_y = mainPanel.height - mainPanel.minSize; + } + break; - case 'preview': - case 'bottom': - if (panel.minSize + resize_y > panel.height) { - resize_y = panel.height - panel.minSize; - } - if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { - resize_y = panel.height - panel.maxSize; - } - if (mainPanel.minSize - resize_y > mainPanel.height) { - resize_y = mainPanel.minSize - mainPanel.height; - } - break; - } - tmp.diff_x = resize_x; - tmp.diff_y = resize_y; + case 'preview': + case 'bottom': + if (panel.minSize + resize_y > panel.height) { + resize_y = panel.height - panel.minSize; + } + if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { + resize_y = panel.height - panel.maxSize; + } + if (mainPanel.minSize - resize_y > mainPanel.height) { + resize_y = mainPanel.minSize - mainPanel.height; + } + break; + } + tmp.diff_x = resize_x; + tmp.diff_y = resize_y; - switch (tmp.type) { - case 'top': - case 'preview': - case 'bottom': - tmp.diff_x = 0; - if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px'; - break; + switch (tmp.type) { + case 'top': + case 'preview': + case 'bottom': + tmp.diff_x = 0; + if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px'; + break; - case 'left': - case 'right': - tmp.diff_y = 0; - if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px'; - break; - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - }, + case 'left': + case 'right': + tmp.diff_y = 0; + if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px'; + break; + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + }, - refresh: function (panel) { - var obj = this; - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (typeof panel == 'undefined') panel = null; - var time = (new Date()).getTime(); - // event before - var eventData = obj.trigger({ phase: 'before', type: 'refresh', target: (typeof panel != 'undefined' ? panel : obj.name), object: obj.get(panel) }); - if (eventData.isCancelled === true) return; - // obj.unlock(panel); - if (typeof panel == 'string') { - var p = obj.get(panel); - if (p === null) return; - var pname = '#layout_'+ obj.name + '_panel_'+ p.type; - var rname = '#layout_'+ obj.name +'_resizer_'+ p.type; - // apply properties to the panel - $(pname).css({ display: p.hidden ? 'none' : 'block' }); - if (p.resizable) $(rname).show(); else $(rname).hide(); - // insert content - if (typeof p.content == 'object' && typeof p.content.render === 'function') { - p.content.box = $(pname +'> .w2ui-panel-content')[0]; - setTimeout(function () { - // need to remove unnecessary classes - if ($(pname +'> .w2ui-panel-content').length > 0) { - $(pname +'> .w2ui-panel-content') - .removeClass() - .addClass('w2ui-panel-content') - .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; - } - p.content.render(); // do not do .render(box); - }, 1); - } else { - // need to remove unnecessary classes - if ($(pname +'> .w2ui-panel-content').length > 0) { - $(pname +'> .w2ui-panel-content') - .removeClass() - .addClass('w2ui-panel-content') - .html(p.content) - .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; - } - } - // if there are tabs and/or toolbar - render it - var tmp = $(obj.box).find(pname +'> .w2ui-panel-tabs'); - if (p.show.tabs) { - if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs !== null) tmp.w2render(p.tabs); else p.tabs.refresh(); - } else { - tmp.html('').removeClass('w2ui-tabs').hide(); - } - tmp = $(obj.box).find(pname +'> .w2ui-panel-toolbar'); - if (p.show.toolbar) { - if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar !== null) tmp.w2render(p.toolbar); else p.toolbar.refresh(); - } else { - tmp.html('').removeClass('w2ui-toolbar').hide(); - } - // show title - tmp = $(obj.box).find(pname +'> .w2ui-panel-title'); - if (p.title) { - tmp.html(p.title).show(); - } else { - tmp.html('').hide(); - } - } else { - if ($('#layout_'+ obj.name +'_panel_main').length == 0) { - obj.render(); - return; - } - obj.resize(); - // refresh all of them - for (var p1 in this.panels) { obj.refresh(this.panels[p1].type); } - } - obj.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, + refresh: function (panel) { + var obj = this; + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (typeof panel == 'undefined') panel = null; + var time = (new Date()).getTime(); + // event before + var eventData = obj.trigger({ phase: 'before', type: 'refresh', target: (typeof panel != 'undefined' ? panel : obj.name), object: obj.get(panel) }); + if (eventData.isCancelled === true) return; + // obj.unlock(panel); + if (typeof panel == 'string') { + var p = obj.get(panel); + if (p === null) return; + var pname = '#layout_'+ obj.name + '_panel_'+ p.type; + var rname = '#layout_'+ obj.name +'_resizer_'+ p.type; + // apply properties to the panel + $(pname).css({ display: p.hidden ? 'none' : 'block' }); + if (p.resizable) $(rname).show(); else $(rname).hide(); + // insert content + if (typeof p.content == 'object' && typeof p.content.render === 'function') { + p.content.box = $(pname +'> .w2ui-panel-content')[0]; + setTimeout(function () { + // need to remove unnecessary classes + if ($(pname +'> .w2ui-panel-content').length > 0) { + $(pname +'> .w2ui-panel-content') + .removeClass() + .addClass('w2ui-panel-content') + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; + } + p.content.render(); // do not do .render(box); + }, 1); + } else { + // need to remove unnecessary classes + if ($(pname +'> .w2ui-panel-content').length > 0) { + $(pname +'> .w2ui-panel-content') + .removeClass() + .addClass('w2ui-panel-content') + .html(p.content) + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; + } + } + // if there are tabs and/or toolbar - render it + var tmp = $(obj.box).find(pname +'> .w2ui-panel-tabs'); + if (p.show.tabs) { + if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs !== null) tmp.w2render(p.tabs); else p.tabs.refresh(); + } else { + tmp.html('').removeClass('w2ui-tabs').hide(); + } + tmp = $(obj.box).find(pname +'> .w2ui-panel-toolbar'); + if (p.show.toolbar) { + if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar !== null) tmp.w2render(p.toolbar); else p.toolbar.refresh(); + } else { + tmp.html('').removeClass('w2ui-toolbar').hide(); + } + // show title + tmp = $(obj.box).find(pname +'> .w2ui-panel-title'); + if (p.title) { + tmp.html(p.title).show(); + } else { + tmp.html('').hide(); + } + } else { + if ($('#layout_'+ obj.name +'_panel_main').length == 0) { + obj.render(); + return; + } + obj.resize(); + // refresh all of them + for (var p1 in this.panels) { obj.refresh(this.panels[p1].type); } + } + obj.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, - resize: function () { - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (!this.box) return false; - var time = (new Date()).getTime(); - // event before - var tmp = this.tmp.resize; - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name, - panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); - if (eventData.isCancelled === true) return; - if (this.padding < 0) this.padding = 0; + resize: function () { + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (!this.box) return false; + var time = (new Date()).getTime(); + // event before + var tmp = this.tmp.resize; + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); + if (eventData.isCancelled === true) return; + if (this.padding < 0) this.padding = 0; - // layout itself - var width = parseInt($(this.box).width()); - var height = parseInt($(this.box).height()); - $(this.box).find(' > div').css({ - width : width + 'px', - height : height + 'px' - }); - var obj = this; - // panels - var pmain = this.get('main'); - var pprev = this.get('preview'); - var pleft = this.get('left'); - var pright = this.get('right'); - var ptop = this.get('top'); - var pbottom = this.get('bottom'); - var smain = true; // main always on - var sprev = (pprev !== null && pprev.hidden !== true ? true : false); - var sleft = (pleft !== null && pleft.hidden !== true ? true : false); - var sright = (pright !== null && pright.hidden !== true ? true : false); - var stop = (ptop !== null && ptop.hidden !== true ? true : false); - var sbottom = (pbottom !== null && pbottom.hidden !== true ? true : false); - var l, t, w, h, e; - // calculate % - for (var p in w2layout_panels) { - p = w2layout_panels[p]; - if (p === 'main') continue; - var tmp = this.get(p); - if (!tmp) continue; - var str = String(tmp.size || 0); - if (str.substr(str.length-1) == '%') { - var tmph = height; - if (tmp.type == 'preview') { - tmph = tmph - - (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - - (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); - } - tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100); - } else { - tmp.sizeCalculated = parseInt(tmp.size); - } - tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)); - } - // top if any - if (ptop !== null && ptop.hidden !== true) { - l = 0; - t = 0; - w = width; - h = ptop.sizeCalculated; - $('#layout_'+ this.name +'_panel_top').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - ptop.width = w; - ptop.height = h; - // resizer - if (ptop.resizable) { - t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_top').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'top', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('top', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_top').hide(); - } - // left if any - if (pleft !== null && pleft.hidden !== true) { - l = 0; - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = pleft.sizeCalculated; - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0); - e = $('#layout_'+ this.name +'_panel_left'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pleft.width = w; - pleft.height = h; - // resizer - if (pleft.resizable) { - l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0); - w = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_left').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ew-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'left', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('left', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_left').hide(); - $('#layout_'+ this.name +'_resizer_left').hide(); - } - // right if any - if (pright !== null && pright.hidden !== true) { - l = width - pright.sizeCalculated; - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = pright.sizeCalculated; - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0); - $('#layout_'+ this.name +'_panel_right').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pright.width = w; - pright.height = h; - // resizer - if (pright.resizable) { - l = l - this.padding; - w = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_right').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ew-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'right', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('right', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_right').hide(); - } - // bottom if any - if (pbottom !== null && pbottom.hidden !== true) { - l = 0; - t = height - pbottom.sizeCalculated; - w = width; - h = pbottom.sizeCalculated; - $('#layout_'+ this.name +'_panel_bottom').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pbottom.width = w; - pbottom.height = h; - // resizer - if (pbottom.resizable) { - t = t - (this.padding === 0 ? 0 : this.padding); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_bottom').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'bottom', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('bottom', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_bottom').hide(); - } - // main - always there - l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding: 0); - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - - (sprev ? pprev.sizeCalculated + this.padding : 0); - e = $('#layout_'+ this.name +'_panel_main'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }); - pmain.width = w; - pmain.height = h; + // layout itself + var width = parseInt($(this.box).width()); + var height = parseInt($(this.box).height()); + $(this.box).find(' > div').css({ + width : width + 'px', + height : height + 'px' + }); + var obj = this; + // panels + var pmain = this.get('main'); + var pprev = this.get('preview'); + var pleft = this.get('left'); + var pright = this.get('right'); + var ptop = this.get('top'); + var pbottom = this.get('bottom'); + var smain = true; // main always on + var sprev = (pprev !== null && pprev.hidden !== true ? true : false); + var sleft = (pleft !== null && pleft.hidden !== true ? true : false); + var sright = (pright !== null && pright.hidden !== true ? true : false); + var stop = (ptop !== null && ptop.hidden !== true ? true : false); + var sbottom = (pbottom !== null && pbottom.hidden !== true ? true : false); + var l, t, w, h, e; + // calculate % + for (var p in w2layout_panels) { + p = w2layout_panels[p]; + if (p === 'main') continue; + var tmp = this.get(p); + if (!tmp) continue; + var str = String(tmp.size || 0); + if (str.substr(str.length-1) == '%') { + var tmph = height; + if (tmp.type == 'preview') { + tmph = tmph - + (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); + } + tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100); + } else { + tmp.sizeCalculated = parseInt(tmp.size); + } + tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)); + } + // top if any + if (ptop !== null && ptop.hidden !== true) { + l = 0; + t = 0; + w = width; + h = ptop.sizeCalculated; + $('#layout_'+ this.name +'_panel_top').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + ptop.width = w; + ptop.height = h; + // resizer + if (ptop.resizable) { + t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_top').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'top', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('top', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_top').hide(); + } + // left if any + if (pleft !== null && pleft.hidden !== true) { + l = 0; + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = pleft.sizeCalculated; + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0); + e = $('#layout_'+ this.name +'_panel_left'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pleft.width = w; + pleft.height = h; + // resizer + if (pleft.resizable) { + l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0); + w = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_left').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'left', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('left', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_left').hide(); + $('#layout_'+ this.name +'_resizer_left').hide(); + } + // right if any + if (pright !== null && pright.hidden !== true) { + l = width - pright.sizeCalculated; + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = pright.sizeCalculated; + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0); + $('#layout_'+ this.name +'_panel_right').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pright.width = w; + pright.height = h; + // resizer + if (pright.resizable) { + l = l - this.padding; + w = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_right').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'right', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('right', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_right').hide(); + } + // bottom if any + if (pbottom !== null && pbottom.hidden !== true) { + l = 0; + t = height - pbottom.sizeCalculated; + w = width; + h = pbottom.sizeCalculated; + $('#layout_'+ this.name +'_panel_bottom').css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pbottom.width = w; + pbottom.height = h; + // resizer + if (pbottom.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_bottom').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'bottom', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('bottom', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_bottom').hide(); + } + // main - always there + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding: 0); + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) - + (sprev ? pprev.sizeCalculated + this.padding : 0); + e = $('#layout_'+ this.name +'_panel_main'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }); + pmain.width = w; + pmain.height = h; - // preview if any - if (pprev !== null && pprev.hidden !== true) { - l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated; - w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding : 0); - h = pprev.sizeCalculated; - e = $('#layout_'+ this.name +'_panel_preview'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pprev.width = w; - pprev.height = h; - // resizer - if (pprev.resizable) { - t = t - (this.padding === 0 ? 0 : this.padding); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_preview').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'preview', originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('preview', event); - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_preview').hide(); - } + // preview if any + if (pprev !== null && pprev.hidden !== true) { + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); + t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated; + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding : 0); + h = pprev.sizeCalculated; + e = $('#layout_'+ this.name +'_panel_preview'); + if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack + e.css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }).show(); + pprev.width = w; + pprev.height = h; + // resizer + if (pprev.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding); + h = (this.resizer > this.padding ? this.resizer : this.padding); + $('#layout_'+ this.name +'_resizer_preview').show().css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }).off('mousedown').on('mousedown', function (event) { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'preview', originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + w2ui[obj.name].tmp.events.resizeStart('preview', event); + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + return false; + }); + } + } else { + $('#layout_'+ this.name +'_panel_preview').hide(); + } - // display tabs and toolbar if needed - for (var p1 in w2layout_panels) { - p1 = w2layout_panels[p1]; - var pan = this.get(p1); - var tmp2 = '#layout_'+ this.name +'_panel_'+ p1 +' > .w2ui-panel-'; - var tabHeight = 0; - if (pan) { - if (pan.title) { - tabHeight += w2utils.getSize($(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - if (pan.show.tabs) { - if (pan.tabs !== null && w2ui[this.name +'_'+ p1 +'_tabs']) w2ui[this.name +'_'+ p1 +'_tabs'].resize(); - tabHeight += w2utils.getSize($(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - if (pan.show.toolbar) { - if (pan.toolbar !== null && w2ui[this.name +'_'+ p1 +'_toolbar']) w2ui[this.name +'_'+ p1 +'_toolbar'].resize(); - tabHeight += w2utils.getSize($(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - } - $(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }); - } - // send resize to all objects - clearTimeout(this._resize_timer); - this._resize_timer = setTimeout(function () { - for (var e in w2ui) { - if (typeof w2ui[e].resize == 'function') { - // sent to all none-layouts - if (w2ui[e].panels == 'undefined') w2ui[e].resize(); - // only send to nested layouts - var parent = $(w2ui[e].box).parents('.w2ui-layout'); - if (parent.length > 0 && parent.attr('name') == obj.name) w2ui[e].resize(); - } - } - }, 100); - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, + // display tabs and toolbar if needed + for (var p1 in w2layout_panels) { + p1 = w2layout_panels[p1]; + var pan = this.get(p1); + var tmp2 = '#layout_'+ this.name +'_panel_'+ p1 +' > .w2ui-panel-'; + var tabHeight = 0; + if (pan) { + if (pan.title) { + tabHeight += w2utils.getSize($(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + if (pan.show.tabs) { + if (pan.tabs !== null && w2ui[this.name +'_'+ p1 +'_tabs']) w2ui[this.name +'_'+ p1 +'_tabs'].resize(); + tabHeight += w2utils.getSize($(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + if (pan.show.toolbar) { + if (pan.toolbar !== null && w2ui[this.name +'_'+ p1 +'_toolbar']) w2ui[this.name +'_'+ p1 +'_toolbar'].resize(); + tabHeight += w2utils.getSize($(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }), 'height'); + } + } + $(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }); + } + // send resize to all objects + clearTimeout(this._resize_timer); + this._resize_timer = setTimeout(function () { + for (var e in w2ui) { + if (typeof w2ui[e].resize == 'function') { + // sent to all none-layouts + if (w2ui[e].panels == 'undefined') w2ui[e].resize(); + // only send to nested layouts + var parent = $(w2ui[e].box).parents('.w2ui-layout'); + if (parent.length > 0 && parent.attr('name') == obj.name) w2ui[e].resize(); + } + } + }, 100); + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - if (typeof w2ui[this.name] == 'undefined') return false; - // clean up - if ($(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-layout') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - if (this.tmp.events && this.tmp.events.resize) $(window).off('resize', this.tmp.events.resize); - return true; - }, + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + if (typeof w2ui[this.name] == 'undefined') return false; + // clean up + if ($(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + if (this.tmp.events && this.tmp.events.resize) $(window).off('resize', this.tmp.events.resize); + return true; + }, - lock: function (panel, msg, showSpinner) { - if (w2layout_panels.indexOf(panel) == -1) { - console.log('ERROR: First parameter needs to be the a valid panel name.'); - return; - } - var args = Array.prototype.slice.call(arguments, 0); - args[0] = '#layout_'+ this.name + '_panel_' + panel; - w2utils.lock.apply(window, args); - }, + lock: function (panel, msg, showSpinner) { + if (w2layout_panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.'); + return; + } + var args = Array.prototype.slice.call(arguments, 0); + args[0] = '#layout_'+ this.name + '_panel_' + panel; + w2utils.lock.apply(window, args); + }, - unlock: function (panel) { - if (w2layout_panels.indexOf(panel) == -1) { - console.log('ERROR: First parameter needs to be the a valid panel name.'); - return; - } - var nm = '#layout_'+ this.name + '_panel_' + panel; - w2utils.unlock(nm); - } - }; + unlock: function (panel) { + if (w2layout_panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.'); + return; + } + var nm = '#layout_'+ this.name + '_panel_' + panel; + w2utils.unlock(nm); + } + }; - $.extend(w2layout.prototype, w2utils.event); - w2obj.layout = w2layout; + $.extend(w2layout.prototype, w2utils.event); + w2obj.layout = w2layout; })(); diff --git a/src/w2listview.js b/src/w2listview.js index c3b161f4a..bda678d2c 100644 --- a/src/w2listview.js +++ b/src/w2listview.js @@ -1,700 +1,700 @@ /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2listview - listview widget -* - $().w2listview - jQuery wrapper -* - Dependencies: jQuery, w2utils +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2listview - listview widget +* - $().w2listview - jQuery wrapper +* - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - images support via 'src' attribute +* - images support via 'src' attribute * ************************************************************************/ (function () { - var w2listview = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.vType = null; - this.extraCols = []; - this.itemExtra = {}; - this.items = []; - this.menu = []; - this.multiselect = true; // multiselect support - this.keyboard = true; // keyboard support - this.curFocused = null; // currently focused item - this.selStart = null; // item to start selection from (used in selection with "shift" key) - this.onClick = null; - this.onDblClick = null; - this.onKeydown = null; - this.onContextMenu = null; - this.onMenuClick = null; // when context menu item selected - this.onRender = null; - this.onRefresh = null; - this.onDestroy = null; - - $.extend(this, { handlers: [] }); - $.extend(true, this, w2obj.listview, options); - for (var i = 0; i < this.extraCols.length; i++) { - this.itemExtra[this.extraCols[i].name] = ''; - } - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2listview = function(method) { - var obj; - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2listview')) return undefined; - if (typeof method.viewType !== 'undefined') { - method.vType = method.viewType; - delete method.viewType; - } - var itms = method.items; - obj = new w2listview(method); - if ($.isArray(itms)) { - for (var i = 0; i < itms.length; i++) { - obj.items[i] = $.extend({}, w2listview.prototype.item, obj.itemExtra, itms[i]); - } - } - if ($(this).length !== 0) { - obj.render($(this)[0]); - } - // register new object - w2ui[obj.name] = obj; - return obj; - } else if (w2ui[$(this).attr('name')]) { - obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2listview' ); - return undefined; - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2listview.prototype = { - item : { - id : null, // param to be sent to all event handlers - caption : '', - description : '', - icon : null, - img : null, - selected : false, - onClick : null, - onDblClick : null, - onKeydown : null, - onContextMenu : null, - onRefresh : null - }, - - viewType: function (value) { - if (arguments.length === 0) { - switch (this.vType) { - case 'table': - return 'table'; - case 'icon-tile': - return 'icon-tile'; - case 'icon-large': - return 'icon-large'; - case 'icon-medium': - return 'icon-medium'; - default: - return 'icon-small'; - } - } else { - this.vType = value; - var vt = 'w2ui-' + this.viewType(); - $(this.box) - .removeClass('w2ui-icon-small w2ui-icon-medium w2ui-icon-large w2ui-icon-tile w2ui-table') - .addClass(vt); - return vt; - } - }, - - add: function (item) { - return this.insert(null, item); - }, - - insert: function (id, item) { - if (!$.isArray(item)) item = [item]; - // assume it is array - for (var i = 0; i < item.length; i++) { - // checks - if (typeof item[i].id === 'undefined') { - console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); - return; - } - if (!w2utils.checkUniqueId(item[i].id, this.items, 'items', this.name)) return; - // add item - var newItm = $.extend({}, w2listview.prototype.item, this.itemExtra, item[i]); - if (id === null || typeof id === 'undefined') { - this.items.push(newItm); - } else { - var middle = this.get(id, true); - this.items = this.items.slice(0, middle).concat([newItm], this.items.slice(middle)); - } - this.refresh(item[i].id); - } - }, - - remove: function (id) { - var removed = 0; - for (var i = 0; i < arguments.length; i++) { - var idx = this.get(arguments[i], true); - if (idx === null) return false; - removed++; - // remove from array - this.items.splice(idx, 1); - // remove from screen - $(this.itemNode(arguments[i])).remove(); - } - return removed; - }, - - set: function (id, item) { - var idx = this.get(id, true); - if (idx === null) return false; - $.extend(this.items[idx], item); - this.refresh(id); - return true; - }, - - get: function (id, returnIndex) { - var i = 0; - if (arguments.length === 0) { - var all = []; - for (; i < this.items.length; i++) { - if (this.items[i].id !== null) all.push(this.items[i].id); - } - return all; - } - for (; i < this.items.length; i++) { - if (this.items[i].id === id) { - if (returnIndex === true) return i; else return this.items[i]; - } - } - return null; - }, - - select: function (id, addSelection) { - var itm = this.get(id); - if (itm === null) return false; - if (arguments.length === 1 || !this.multiselect) addSelection = false; - - if (!addSelection) this.unselect(); - if (!itm.selected) { - $(this.itemNode(itm.id)).addClass('w2ui-selected'); - itm.selected = true; - } - return itm.selected; - }, - - unselect: function (id) { - var obj = this; - var i = 0; - if (arguments.length === 0) { - for (; i < this.items.length; i++) doUnselect(this.items[i]); - } else { - for (; i < arguments.length; i++) doUnselect(this.get(arguments[i])); - } - return true; - - function doUnselect(itm) { - if (itm !== null && itm.selected) { - $(obj.itemNode(itm.id)).removeClass('w2ui-selected'); - itm.selected = false; - } - } - }, - - getFocused: function (returnIndex) { - var rslt = this.get(this.curFocused, returnIndex); - if (rslt === null) rslt = this.get(this.selStart, returnIndex); - return rslt; - }, - - scrollIntoView: function (id) { - if (typeof id !== 'undefined') { - var node = this.itemNode(id); - if (node === null) return; - var nodeOffset = this.itemNodeOffsetInfo(node); - if (nodeOffset.top < this.box.scrollTop) { - $(this.box).scrollTop(nodeOffset.top); - } else if (nodeOffset.bottom > this.box.scrollTop + this.box.offsetHeight) { - $(this.box).scrollTop(nodeOffset.bottom - this.box.offsetHeight); - } - } - }, - - userSelect: function (id, event, isMouse) { - var itm = null; - - // update selection - if (event.shiftKey) { - this.unselect(); - var fIdx = this.get(this.selStart, true); - if (fIdx !== null) { - var idx = this.get(id, true); - var toIdx = Math.max(idx, fIdx); - for (var i = Math.min(idx, fIdx); i <= toIdx; i++) { - this.select(this.items[i].id, true); - } - } else { - this.select(id, true); - this.selStart = id; - } - } else if (event.ctrlKey) { - if (isMouse) { - itm = this.get(id); - if (itm.selected) this.unselect(id); else this.select(id, true); - this.selStart = id; - } - } else { - this.select(id, false); - this.selStart = id; - } - - // update focus - if (itm === null) itm = this.get(id); - if (itm === null) return; - var oldItm = this.getFocused(); - if (oldItm !== null) { - $(this.itemNode(oldItm.id)).removeClass('w2ui-focused'); - } - $(this.itemNode(id)).addClass('w2ui-focused'); - this.curFocused = id; - - // update view - this.scrollIntoView(id); - }, - - // =================================================== - // -- Internal Event Handlers - - click: function (id, event) { - var idx = this.get(id, true); - if (idx === null) return false; - var eventData = this.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, object: this.items[idx] }); - var rslt = eventData.isCancelled !== true; - if (rslt) { - // default action - this.userSelect(id, event, true); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - return rslt; - }, - - dblClick: function (id, event) { - var itm = this.get(id); - if (itm === null) return false; - var eventData = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: itm }); - var rslt = eventData.isCancelled !== true; - if (rslt) { - // default action - // -- empty - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - return rslt; - }, - - keydown: function (event) { - var obj = this; - var idx = this.getFocused(true); - if (idx === null || obj.keyboard !== true) return false; - var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); - var rslt = eventData.isCancelled !== true; - if (rslt) { - // default behaviour - var cancelProcessing = true; - switch (event.keyCode) { - case 13: - obj.dblClick(obj.items[idx].id, event); - break; - case 32: - obj.click(obj.items[idx].id, event); - break; - case 33: - processNeighbor('pgUp'); - break; - case 34: - processNeighbor('pgDown'); - break; - case 36: - processNeighbor('home'); - break; - case 35: - processNeighbor('end'); - break; - case 37: - processNeighbor('left'); - break; - case 38: - processNeighbor('up'); - break; - case 39: - processNeighbor('right'); - break; - case 40: - processNeighbor('down'); - break; - default: - cancelProcessing = false; - } - // cancel event if needed - if (cancelProcessing) { - if (event.preventDefault) event.preventDefault(); - if (event.stopPropagation) event.stopPropagation(); - } - - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - return rslt; - - function processNeighbor(neighbor) { - var newIdx = getNeighborIdx(neighbor); - if (newIdx >= 0 && newIdx < obj.items.length && newIdx !== idx) { - obj.userSelect(obj.items[newIdx].id, event, false); - } - } - - function getNeighborIdx(neighbor) { - var colsCnt = colsCount(); - var newIdx, itmOffset; - switch (neighbor) { - case 'up': - return idx - colsCnt; - case 'down': - return idx + colsCnt; - case 'left': - return (colsCnt > 1) ? idx - 1 : idx; - case 'right': - return (colsCnt > 1) ? idx + 1 : idx; - case 'pgUp': - if (idx < colsCnt) return 0; - itmOffset = obj.itemNodeOffsetInfo(obj.itemNode(obj.items[idx].id)); - var minTop = itmOffset.bottom - obj.box.offsetHeight - allowedOverflow(itmOffset); - newIdx = idx; - while (newIdx >= colsCnt) { - newIdx -= colsCnt; - if (obj.itemNodeOffsetInfo(obj.itemNode(obj.items[newIdx].id)).top < minTop) { - newIdx += colsCnt; - break; - } - } - return newIdx; - case 'pgDown': - if (idx >= obj.items.length - colsCnt) return obj.items.length - 1; - itmOffset = obj.itemNodeOffsetInfo(obj.itemNode(obj.items[idx].id)); - var maxBottom = itmOffset.top + obj.box.offsetHeight + allowedOverflow(itmOffset); - newIdx = idx; - while (newIdx < obj.items.length - colsCnt) { - newIdx += colsCnt; - if (obj.itemNodeOffsetInfo(obj.itemNode(obj.items[newIdx].id)).bottom > maxBottom) { - newIdx -= colsCnt; - break; - } - } - return newIdx; - case 'home': - return 0; - case 'end': - return obj.items.length - 1; - default: - return idx; - } - - function allowedOverflow(offset) { - return parseInt((offset.bottom - offset.top) / 2); - } - } - - function colsCount() { - var vt = obj.viewType(); - if (vt === 'table') return 1; - return parseInt($(obj.box).find('> ul').width() / itemWidth(vt), 10); - } - - function itemWidth(viewType) { - obj.itemWidths = obj.itemWidths || {}; - if (!(viewType in obj.itemWidths)) { - var itm = obj.itemNode(obj.items[idx].id); - obj.itemWidths[viewType] = w2utils.getSize(itm, 'width'); - } - return obj.itemWidths[viewType]; - } - }, - - contextMenu: function (id, event) { - var obj = this; - var itm = this.get(id); - if (itm === null) return false; - if (!itm.selected) obj.select(id); - var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: itm }); - var rslt = eventData.isCancelled !== true; - if (rslt) { - // default action - if (obj.menu.length > 0) { - $(obj.itemNode(id)) - .w2menu(obj.menu, { - left: (event ? event.offsetX || event.pageX : 50) - 25, - select: function (item, event, index) { obj.menuClick(id, index, event); } - }); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - return false; - }, - - menuClick: function (itemId, index, event) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: this.menu[index] }); - var rslt = eventData.isCancelled !== true; - if (rslt) { - // default action - // -- empty - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - return rslt; - }, - - itemNodeId: function (id) { - return 'lv_' + this.name + '_itm_' + id; - }, - - itemNode: function (id) { - return document.getElementById(this.itemNodeId(id)); - }, - - itemNodeOffsetInfo: function (node) { - var vt = this.viewType(); - this.itemSpacing = this.itemSpacing || {}; - if (!(vt in this.itemSpacing)) { - var $node = $(node); - this.itemSpacing[vt] = (parseInt($node.css('margin-top')) || 0) + (parseInt($node.css('margin-bottom')) || 0); - } - return { - top: node.offsetTop - this.itemSpacing[vt], - bottom: node.offsetTop + node.offsetHeight + this.itemSpacing[vt] - }; - }, - - refresh: function (id) { - var obj = this; - var time = (new Date()).getTime(); - - var idx; - if (typeof id !== 'undefined') { - idx = this.get(id, true); - if (idx === null) return false; - } - - // event before - var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), object: this.items[idx] }); - if (eventData.isCancelled === true) return; - - // default action - if (typeof id === 'undefined') { - // refresh all items - var itms = document.createDocumentFragment(); - for (var i = 0; i < this.items.length; i++) - itms.appendChild(getItemElement(this.items[i])); - var lst = this.lastItm.parentNode; - while (lst.firstChild !== this.lastItm) - lst.removeChild(lst.firstChild); - this.lastItm.parentNode.insertBefore(itms, this.lastItm); - } else { - // refresh single item - var itm = this.itemNode(id); - if (itm) { - // update existing - itm.parentNode.replaceChild(getItemElement(this.items[idx]), itm); - } else { - // create new - var nextItm; - if (idx !== this.items.length-1) nextItm = this.itemNode(this.items[idx+1].id); - if (!nextItm) nextItm = this.lastItm; - nextItm.parentNode.insertBefore(getItemElement(this.items[idx]), nextItm); - } - } - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - - return (new Date()).getTime() - time; - - function getItemElement(item) { - var imgClass = (item.icon !== null && typeof item.icon !== 'undefined') ? ' '+item.icon : ' icon-none'; - if (item.img !== null && typeof item.img !== 'undefined') imgClass = ' w2ui-icon '+item.img; - - var withDescription = (typeof item.description !== 'undefined' && item.description !== ''); - var withExtra = (obj.extraCols.length > 0); - var rslt = getItemTemplate(withDescription, withExtra); - rslt.id = obj.itemNodeId(item.id); - rslt.setAttribute('item_id', item.id); - var itmDiv = rslt.querySelector('div'); - itmDiv.querySelector('div.w2ui-listview-img').className = 'w2ui-listview-img'+imgClass; - itmDiv.querySelector('div.caption').textContent = item.caption; - if (withDescription) { - itmDiv.querySelector('div.description').textContent = item.description; - } - if (withExtra) { - var itmExtra = itmDiv.querySelector('div.extra div'); - for (var i = 0; i < obj.extraCols.length; i++) { - var colName = obj.extraCols[i].name; - if (colName in item) { - itmExtra.querySelector('div.'+colName).textContent = item[colName]; - } - } - } - return rslt; - } - - function getItemTemplate(withDescription, withExtra) { - var template, itmDiv; - if (!withDescription && !withExtra) { - if ('captionOnlyTemplate' in obj) { - template = obj.captionOnlyTemplate; - } else { - template = document.createElement('li'); - template.setAttribute('onmouseover', '$(this).addClass(\'hover\');'); - template.setAttribute('onmouseout', '$(this).removeClass(\'hover\');'); - template.setAttribute('onclick', 'w2ui[\''+obj.name+'\'].click(this.getAttribute(\'item_id\'), event);'); - template.setAttribute('ondblclick', 'w2ui[\''+obj.name+'\'].dblClick(this.getAttribute(\'item_id\'), event);'); - template.setAttribute('oncontextmenu', 'w2ui[\''+obj.name+'\'].contextMenu(this.getAttribute(\'item_id\'), event); if (event.preventDefault) event.preventDefault();'); - itmDiv = appendDiv(template); - appendDiv(itmDiv, 'w2ui-listview-img'); - appendDiv(itmDiv, 'caption'); - obj.captionOnlyTemplate = template; - } - } else if (withDescription && !withExtra) { - if ('captionWithDescription' in obj) { - template = obj.captionWithDescriptionTemplate; - } else { - template = getItemTemplate(false, false); - itmDiv = template.querySelector('div'); - appendDiv(itmDiv, 'description'); - obj.captionWithDescriptionTemplate = template; - } - } else if (!withDescription && withExtra) { - if ('captionWithExtra' in obj) { - template = obj.captionWithExtra; - } else { - template = appendExtra(getItemTemplate(false, false)); - obj.captionWithExtra = template; - } - } else if (withDescription && withExtra) { - if ('captionWithDescriptionAndExtra' in obj) { - template = obj.captionWithDescriptionAndExtra; - } else { - template = appendExtra(getItemTemplate(true, false)); - obj.captionWithDescriptionAndExtra = template; - } - } - return template.cloneNode(true); - - function appendExtra(node) { - var itmDiv = node.querySelector('div'); - var extra = appendDiv(itmDiv, 'extra'); - extra.style.width = extraColsWidth() + 'px'; - extra = appendDiv(extra); - for (var i = 0; i < obj.extraCols.length; i++) { - var col = obj.extraCols[i]; - var extraCol = appendDiv(extra, col.name); - extraCol.style.width = col.width + 'px'; - if ('align' in col) extraCol.style.textAlign = col.align; - if ('paddingLeft' in col) extraCol.style.paddingLeft = col.paddingLeft + 'px'; - if ('paddingRight' in col) extraCol.style.paddingRight = col.paddingRight + 'px'; - } - return node; - - function extraColsWidth() { - var rslt = 0; - for (var i = 0; i < obj.extraCols.length; i++) { - obj.extraCols[i].width = ('width' in obj.extraCols[i]) ? parseInt(obj.extraCols[i].width, 10) : 100; - rslt += obj.extraCols[i].width; - } - return rslt; - } - } - } - - function appendDiv(parentElement, cls, txt) { - var div = document.createElement('div'); - if (typeof cls !== 'undefined') div.className = cls; - if (typeof txt !== 'undefined') div.textContent = txt; - parentElement.appendChild(div); - return div; - } - - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return; - // default action - if (typeof box !== 'undefined' && box !== null && this.box !== box) { - if (this.lastItm) { - while (this.box.hasChildNodes()) - this.box.removeChild(this.box.lastChild); - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-listview w2ui-icon-small w2ui-icon-medium w2ui-icon-large w2ui-icon-tile w2ui-table'); - } - this.box = box; - } - if (!this.box) return false; - while (this.box.hasChildNodes()) - this.box.removeChild(this.box.lastChild); - this.box.scrollTop = 0; - - // render all items - var list = document.createElement('ul'); - var lastItm = document.createElement('li'); - lastItm.className = 'itmlast'; - lastItm.style.display = 'none'; - list.appendChild(lastItm); - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-listview w2ui-' + this.viewType()) - .append(list); - this.lastItm = lastItm; - this.refresh(); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - // clean up - if (this.box) { - this.lastItm = null; - $(this.box) - .empty() - .removeAttr('name') - .removeClass('w2ui-reset w2ui-listview w2ui-icon-small w2ui-icon-medium w2ui-icon-large w2ui-icon-tile w2ui-table'); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return true; - } - }; - - $.extend(w2listview.prototype, w2utils.event); - w2obj.listview = w2listview; + var w2listview = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.vType = null; + this.extraCols = []; + this.itemExtra = {}; + this.items = []; + this.menu = []; + this.multiselect = true; // multiselect support + this.keyboard = true; // keyboard support + this.curFocused = null; // currently focused item + this.selStart = null; // item to start selection from (used in selection with "shift" key) + this.onClick = null; + this.onDblClick = null; + this.onKeydown = null; + this.onContextMenu = null; + this.onMenuClick = null; // when context menu item selected + this.onRender = null; + this.onRefresh = null; + this.onDestroy = null; + + $.extend(this, { handlers: [] }); + $.extend(true, this, w2obj.listview, options); + for (var i = 0; i < this.extraCols.length; i++) { + this.itemExtra[this.extraCols[i].name] = ''; + } + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2listview = function(method) { + var obj; + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2listview')) return undefined; + if (typeof method.viewType !== 'undefined') { + method.vType = method.viewType; + delete method.viewType; + } + var itms = method.items; + obj = new w2listview(method); + if ($.isArray(itms)) { + for (var i = 0; i < itms.length; i++) { + obj.items[i] = $.extend({}, w2listview.prototype.item, obj.itemExtra, itms[i]); + } + } + if ($(this).length !== 0) { + obj.render($(this)[0]); + } + // register new object + w2ui[obj.name] = obj; + return obj; + } else if (w2ui[$(this).attr('name')]) { + obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2listview' ); + return undefined; + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2listview.prototype = { + item : { + id : null, // param to be sent to all event handlers + caption : '', + description : '', + icon : null, + img : null, + selected : false, + onClick : null, + onDblClick : null, + onKeydown : null, + onContextMenu : null, + onRefresh : null + }, + + viewType: function (value) { + if (arguments.length === 0) { + switch (this.vType) { + case 'table': + return 'table'; + case 'icon-tile': + return 'icon-tile'; + case 'icon-large': + return 'icon-large'; + case 'icon-medium': + return 'icon-medium'; + default: + return 'icon-small'; + } + } else { + this.vType = value; + var vt = 'w2ui-' + this.viewType(); + $(this.box) + .removeClass('w2ui-icon-small w2ui-icon-medium w2ui-icon-large w2ui-icon-tile w2ui-table') + .addClass(vt); + return vt; + } + }, + + add: function (item) { + return this.insert(null, item); + }, + + insert: function (id, item) { + if (!$.isArray(item)) item = [item]; + // assume it is array + for (var i = 0; i < item.length; i++) { + // checks + if (typeof item[i].id === 'undefined') { + console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); + return; + } + if (!w2utils.checkUniqueId(item[i].id, this.items, 'items', this.name)) return; + // add item + var newItm = $.extend({}, w2listview.prototype.item, this.itemExtra, item[i]); + if (id === null || typeof id === 'undefined') { + this.items.push(newItm); + } else { + var middle = this.get(id, true); + this.items = this.items.slice(0, middle).concat([newItm], this.items.slice(middle)); + } + this.refresh(item[i].id); + } + }, + + remove: function (id) { + var removed = 0; + for (var i = 0; i < arguments.length; i++) { + var idx = this.get(arguments[i], true); + if (idx === null) return false; + removed++; + // remove from array + this.items.splice(idx, 1); + // remove from screen + $(this.itemNode(arguments[i])).remove(); + } + return removed; + }, + + set: function (id, item) { + var idx = this.get(id, true); + if (idx === null) return false; + $.extend(this.items[idx], item); + this.refresh(id); + return true; + }, + + get: function (id, returnIndex) { + var i = 0; + if (arguments.length === 0) { + var all = []; + for (; i < this.items.length; i++) { + if (this.items[i].id !== null) all.push(this.items[i].id); + } + return all; + } + for (; i < this.items.length; i++) { + if (this.items[i].id === id) { + if (returnIndex === true) return i; else return this.items[i]; + } + } + return null; + }, + + select: function (id, addSelection) { + var itm = this.get(id); + if (itm === null) return false; + if (arguments.length === 1 || !this.multiselect) addSelection = false; + + if (!addSelection) this.unselect(); + if (!itm.selected) { + $(this.itemNode(itm.id)).addClass('w2ui-selected'); + itm.selected = true; + } + return itm.selected; + }, + + unselect: function (id) { + var obj = this; + var i = 0; + if (arguments.length === 0) { + for (; i < this.items.length; i++) doUnselect(this.items[i]); + } else { + for (; i < arguments.length; i++) doUnselect(this.get(arguments[i])); + } + return true; + + function doUnselect(itm) { + if (itm !== null && itm.selected) { + $(obj.itemNode(itm.id)).removeClass('w2ui-selected'); + itm.selected = false; + } + } + }, + + getFocused: function (returnIndex) { + var rslt = this.get(this.curFocused, returnIndex); + if (rslt === null) rslt = this.get(this.selStart, returnIndex); + return rslt; + }, + + scrollIntoView: function (id) { + if (typeof id !== 'undefined') { + var node = this.itemNode(id); + if (node === null) return; + var nodeOffset = this.itemNodeOffsetInfo(node); + if (nodeOffset.top < this.box.scrollTop) { + $(this.box).scrollTop(nodeOffset.top); + } else if (nodeOffset.bottom > this.box.scrollTop + this.box.offsetHeight) { + $(this.box).scrollTop(nodeOffset.bottom - this.box.offsetHeight); + } + } + }, + + userSelect: function (id, event, isMouse) { + var itm = null; + + // update selection + if (event.shiftKey) { + this.unselect(); + var fIdx = this.get(this.selStart, true); + if (fIdx !== null) { + var idx = this.get(id, true); + var toIdx = Math.max(idx, fIdx); + for (var i = Math.min(idx, fIdx); i <= toIdx; i++) { + this.select(this.items[i].id, true); + } + } else { + this.select(id, true); + this.selStart = id; + } + } else if (event.ctrlKey) { + if (isMouse) { + itm = this.get(id); + if (itm.selected) this.unselect(id); else this.select(id, true); + this.selStart = id; + } + } else { + this.select(id, false); + this.selStart = id; + } + + // update focus + if (itm === null) itm = this.get(id); + if (itm === null) return; + var oldItm = this.getFocused(); + if (oldItm !== null) { + $(this.itemNode(oldItm.id)).removeClass('w2ui-focused'); + } + $(this.itemNode(id)).addClass('w2ui-focused'); + this.curFocused = id; + + // update view + this.scrollIntoView(id); + }, + + // =================================================== + // -- Internal Event Handlers + + click: function (id, event) { + var idx = this.get(id, true); + if (idx === null) return false; + var eventData = this.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, object: this.items[idx] }); + var rslt = eventData.isCancelled !== true; + if (rslt) { + // default action + this.userSelect(id, event, true); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + return rslt; + }, + + dblClick: function (id, event) { + var itm = this.get(id); + if (itm === null) return false; + var eventData = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: itm }); + var rslt = eventData.isCancelled !== true; + if (rslt) { + // default action + // -- empty + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + return rslt; + }, + + keydown: function (event) { + var obj = this; + var idx = this.getFocused(true); + if (idx === null || obj.keyboard !== true) return false; + var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); + var rslt = eventData.isCancelled !== true; + if (rslt) { + // default behaviour + var cancelProcessing = true; + switch (event.keyCode) { + case 13: + obj.dblClick(obj.items[idx].id, event); + break; + case 32: + obj.click(obj.items[idx].id, event); + break; + case 33: + processNeighbor('pgUp'); + break; + case 34: + processNeighbor('pgDown'); + break; + case 36: + processNeighbor('home'); + break; + case 35: + processNeighbor('end'); + break; + case 37: + processNeighbor('left'); + break; + case 38: + processNeighbor('up'); + break; + case 39: + processNeighbor('right'); + break; + case 40: + processNeighbor('down'); + break; + default: + cancelProcessing = false; + } + // cancel event if needed + if (cancelProcessing) { + if (event.preventDefault) event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); + } + + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + return rslt; + + function processNeighbor(neighbor) { + var newIdx = getNeighborIdx(neighbor); + if (newIdx >= 0 && newIdx < obj.items.length && newIdx !== idx) { + obj.userSelect(obj.items[newIdx].id, event, false); + } + } + + function getNeighborIdx(neighbor) { + var colsCnt = colsCount(); + var newIdx, itmOffset; + switch (neighbor) { + case 'up': + return idx - colsCnt; + case 'down': + return idx + colsCnt; + case 'left': + return (colsCnt > 1) ? idx - 1 : idx; + case 'right': + return (colsCnt > 1) ? idx + 1 : idx; + case 'pgUp': + if (idx < colsCnt) return 0; + itmOffset = obj.itemNodeOffsetInfo(obj.itemNode(obj.items[idx].id)); + var minTop = itmOffset.bottom - obj.box.offsetHeight - allowedOverflow(itmOffset); + newIdx = idx; + while (newIdx >= colsCnt) { + newIdx -= colsCnt; + if (obj.itemNodeOffsetInfo(obj.itemNode(obj.items[newIdx].id)).top < minTop) { + newIdx += colsCnt; + break; + } + } + return newIdx; + case 'pgDown': + if (idx >= obj.items.length - colsCnt) return obj.items.length - 1; + itmOffset = obj.itemNodeOffsetInfo(obj.itemNode(obj.items[idx].id)); + var maxBottom = itmOffset.top + obj.box.offsetHeight + allowedOverflow(itmOffset); + newIdx = idx; + while (newIdx < obj.items.length - colsCnt) { + newIdx += colsCnt; + if (obj.itemNodeOffsetInfo(obj.itemNode(obj.items[newIdx].id)).bottom > maxBottom) { + newIdx -= colsCnt; + break; + } + } + return newIdx; + case 'home': + return 0; + case 'end': + return obj.items.length - 1; + default: + return idx; + } + + function allowedOverflow(offset) { + return parseInt((offset.bottom - offset.top) / 2); + } + } + + function colsCount() { + var vt = obj.viewType(); + if (vt === 'table') return 1; + return parseInt($(obj.box).find('> ul').width() / itemWidth(vt), 10); + } + + function itemWidth(viewType) { + obj.itemWidths = obj.itemWidths || {}; + if (!(viewType in obj.itemWidths)) { + var itm = obj.itemNode(obj.items[idx].id); + obj.itemWidths[viewType] = w2utils.getSize(itm, 'width'); + } + return obj.itemWidths[viewType]; + } + }, + + contextMenu: function (id, event) { + var obj = this; + var itm = this.get(id); + if (itm === null) return false; + if (!itm.selected) obj.select(id); + var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: itm }); + var rslt = eventData.isCancelled !== true; + if (rslt) { + // default action + if (obj.menu.length > 0) { + $(obj.itemNode(id)) + .w2menu(obj.menu, { + left: (event ? event.offsetX || event.pageX : 50) - 25, + select: function (item, event, index) { obj.menuClick(id, index, event); } + }); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + } + return false; + }, + + menuClick: function (itemId, index, event) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: this.menu[index] }); + var rslt = eventData.isCancelled !== true; + if (rslt) { + // default action + // -- empty + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + return rslt; + }, + + itemNodeId: function (id) { + return 'lv_' + this.name + '_itm_' + id; + }, + + itemNode: function (id) { + return document.getElementById(this.itemNodeId(id)); + }, + + itemNodeOffsetInfo: function (node) { + var vt = this.viewType(); + this.itemSpacing = this.itemSpacing || {}; + if (!(vt in this.itemSpacing)) { + var $node = $(node); + this.itemSpacing[vt] = (parseInt($node.css('margin-top')) || 0) + (parseInt($node.css('margin-bottom')) || 0); + } + return { + top: node.offsetTop - this.itemSpacing[vt], + bottom: node.offsetTop + node.offsetHeight + this.itemSpacing[vt] + }; + }, + + refresh: function (id) { + var obj = this; + var time = (new Date()).getTime(); + + var idx; + if (typeof id !== 'undefined') { + idx = this.get(id, true); + if (idx === null) return false; + } + + // event before + var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), object: this.items[idx] }); + if (eventData.isCancelled === true) return; + + // default action + if (typeof id === 'undefined') { + // refresh all items + var itms = document.createDocumentFragment(); + for (var i = 0; i < this.items.length; i++) + itms.appendChild(getItemElement(this.items[i])); + var lst = this.lastItm.parentNode; + while (lst.firstChild !== this.lastItm) + lst.removeChild(lst.firstChild); + this.lastItm.parentNode.insertBefore(itms, this.lastItm); + } else { + // refresh single item + var itm = this.itemNode(id); + if (itm) { + // update existing + itm.parentNode.replaceChild(getItemElement(this.items[idx]), itm); + } else { + // create new + var nextItm; + if (idx !== this.items.length-1) nextItm = this.itemNode(this.items[idx+1].id); + if (!nextItm) nextItm = this.lastItm; + nextItm.parentNode.insertBefore(getItemElement(this.items[idx]), nextItm); + } + } + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + + return (new Date()).getTime() - time; + + function getItemElement(item) { + var imgClass = (item.icon !== null && typeof item.icon !== 'undefined') ? ' '+item.icon : ' icon-none'; + if (item.img !== null && typeof item.img !== 'undefined') imgClass = ' w2ui-icon '+item.img; + + var withDescription = (typeof item.description !== 'undefined' && item.description !== ''); + var withExtra = (obj.extraCols.length > 0); + var rslt = getItemTemplate(withDescription, withExtra); + rslt.id = obj.itemNodeId(item.id); + rslt.setAttribute('item_id', item.id); + var itmDiv = rslt.querySelector('div'); + itmDiv.querySelector('div.w2ui-listview-img').className = 'w2ui-listview-img'+imgClass; + itmDiv.querySelector('div.caption').textContent = item.caption; + if (withDescription) { + itmDiv.querySelector('div.description').textContent = item.description; + } + if (withExtra) { + var itmExtra = itmDiv.querySelector('div.extra div'); + for (var i = 0; i < obj.extraCols.length; i++) { + var colName = obj.extraCols[i].name; + if (colName in item) { + itmExtra.querySelector('div.'+colName).textContent = item[colName]; + } + } + } + return rslt; + } + + function getItemTemplate(withDescription, withExtra) { + var template, itmDiv; + if (!withDescription && !withExtra) { + if ('captionOnlyTemplate' in obj) { + template = obj.captionOnlyTemplate; + } else { + template = document.createElement('li'); + template.setAttribute('onmouseover', '$(this).addClass(\'hover\');'); + template.setAttribute('onmouseout', '$(this).removeClass(\'hover\');'); + template.setAttribute('onclick', 'w2ui[\''+obj.name+'\'].click(this.getAttribute(\'item_id\'), event);'); + template.setAttribute('ondblclick', 'w2ui[\''+obj.name+'\'].dblClick(this.getAttribute(\'item_id\'), event);'); + template.setAttribute('oncontextmenu', 'w2ui[\''+obj.name+'\'].contextMenu(this.getAttribute(\'item_id\'), event); if (event.preventDefault) event.preventDefault();'); + itmDiv = appendDiv(template); + appendDiv(itmDiv, 'w2ui-listview-img'); + appendDiv(itmDiv, 'caption'); + obj.captionOnlyTemplate = template; + } + } else if (withDescription && !withExtra) { + if ('captionWithDescription' in obj) { + template = obj.captionWithDescriptionTemplate; + } else { + template = getItemTemplate(false, false); + itmDiv = template.querySelector('div'); + appendDiv(itmDiv, 'description'); + obj.captionWithDescriptionTemplate = template; + } + } else if (!withDescription && withExtra) { + if ('captionWithExtra' in obj) { + template = obj.captionWithExtra; + } else { + template = appendExtra(getItemTemplate(false, false)); + obj.captionWithExtra = template; + } + } else if (withDescription && withExtra) { + if ('captionWithDescriptionAndExtra' in obj) { + template = obj.captionWithDescriptionAndExtra; + } else { + template = appendExtra(getItemTemplate(true, false)); + obj.captionWithDescriptionAndExtra = template; + } + } + return template.cloneNode(true); + + function appendExtra(node) { + var itmDiv = node.querySelector('div'); + var extra = appendDiv(itmDiv, 'extra'); + extra.style.width = extraColsWidth() + 'px'; + extra = appendDiv(extra); + for (var i = 0; i < obj.extraCols.length; i++) { + var col = obj.extraCols[i]; + var extraCol = appendDiv(extra, col.name); + extraCol.style.width = col.width + 'px'; + if ('align' in col) extraCol.style.textAlign = col.align; + if ('paddingLeft' in col) extraCol.style.paddingLeft = col.paddingLeft + 'px'; + if ('paddingRight' in col) extraCol.style.paddingRight = col.paddingRight + 'px'; + } + return node; + + function extraColsWidth() { + var rslt = 0; + for (var i = 0; i < obj.extraCols.length; i++) { + obj.extraCols[i].width = ('width' in obj.extraCols[i]) ? parseInt(obj.extraCols[i].width, 10) : 100; + rslt += obj.extraCols[i].width; + } + return rslt; + } + } + } + + function appendDiv(parentElement, cls, txt) { + var div = document.createElement('div'); + if (typeof cls !== 'undefined') div.className = cls; + if (typeof txt !== 'undefined') div.textContent = txt; + parentElement.appendChild(div); + return div; + } + + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (eventData.isCancelled === true) return; + // default action + if (typeof box !== 'undefined' && box !== null && this.box !== box) { + if (this.lastItm) { + while (this.box.hasChildNodes()) + this.box.removeChild(this.box.lastChild); + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-listview w2ui-icon-small w2ui-icon-medium w2ui-icon-large w2ui-icon-tile w2ui-table'); + } + this.box = box; + } + if (!this.box) return false; + while (this.box.hasChildNodes()) + this.box.removeChild(this.box.lastChild); + this.box.scrollTop = 0; + + // render all items + var list = document.createElement('ul'); + var lastItm = document.createElement('li'); + lastItm.className = 'itmlast'; + lastItm.style.display = 'none'; + list.appendChild(lastItm); + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-listview w2ui-' + this.viewType()) + .append(list); + this.lastItm = lastItm; + this.refresh(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + // clean up + if (this.box) { + this.lastItm = null; + $(this.box) + .empty() + .removeAttr('name') + .removeClass('w2ui-reset w2ui-listview w2ui-icon-small w2ui-icon-medium w2ui-icon-large w2ui-icon-tile w2ui-table'); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return true; + } + }; + + $.extend(w2listview.prototype, w2utils.event); + w2obj.listview = w2listview; })(); diff --git a/src/w2popup.js b/src/w2popup.js index 90306f3a2..3d70b71db 100644 --- a/src/w2popup.js +++ b/src/w2popup.js @@ -1,18 +1,18 @@ /************************************************************************ * Library: Web 2.0 UI for jQuery (using prototypical inheritance) * - Following objects defined -* - w2popup - popup widget -* - $().w2popup - jQuery wrapper +* - w2popup - popup widget +* - $().w2popup - jQuery wrapper * - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - transition should include title, body and buttons, not just body +* - transition should include title, body and buttons, not just body * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - new: w2popup.status can be ['closed', 'opening', 'open', 'closing', resizing', 'moving'] -* - add lock method() to lock popup content -* - fixed bug with max width/height of message +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - new: w2popup.status can be ['closed', 'opening', 'open', 'closing', resizing', 'moving'] +* - add lock method() to lock popup content +* - fixed bug with max width/height of message * ************************************************************************/ @@ -20,624 +20,624 @@ var w2popup = {}; (function () { - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2popup = function(method, options) { - if (typeof method === 'undefined') { - options = {}; - method = 'open'; - } - if ($.isPlainObject(method)) { - options = method; - method = 'open'; - } - method = method.toLowerCase(); - if (method === 'load' && typeof options === 'string') { - options = $.extend({ url: options }, arguments.length > 2 ? arguments[2] : {}); - } - if (method === 'open' && options.url != null) method = 'load'; - options = options || {}; - // load options from markup - var dlgOptions = {}; - if ($(this).length > 0) { - if ($(this).find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { - if ($(this).find('div[rel=title]').length > 0) { - dlgOptions['title'] = $(this).find('div[rel=title]').html(); - } - if ($(this).find('div[rel=body]').length > 0) { - dlgOptions['body'] = $(this).find('div[rel=body]').html(); - dlgOptions['style'] = $(this).find('div[rel=body]')[0].style.cssText; - } - if ($(this).find('div[rel=buttons]').length > 0) { - dlgOptions['buttons'] = $(this).find('div[rel=buttons]').html(); - } - } else { - dlgOptions['title'] = ' '; - dlgOptions['body'] = $(this).html(); - } - if (parseInt($(this).css('width')) != 0) dlgOptions['width'] = parseInt($(this).css('width')); - if (parseInt($(this).css('height')) != 0) dlgOptions['height'] = parseInt($(this).css('height')); - } - // show popup - return w2popup[method]($.extend({}, dlgOptions, options)); - }; - - // ==================================================== - // -- Implementation of core functionality (SINGELTON) - - w2popup = { - defaults: { - title : '', - body : '', - buttons : '', - style : '', - color : '#000', - opacity : 0.4, - speed : 0.3, - modal : false, - maximized : false, - keyboard : true, // will close popup on esc if not modal - width : 500, - height : 300, - showClose : true, - showMax : false, - transition : null - }, - status : 'closed', // string that describes current status - handlers : [], - onOpen : null, - onClose : null, - onMax : null, - onMin : null, - onToggle : null, - onKeydown : null, - - open: function (options) { - var obj = this; - if (w2popup.status == 'closing') { - setTimeout(function () { obj.open.call(obj, options); }, 100); - return; - } - // get old options and merge them - var old_options = $('#w2ui-popup').data('options'); - var options = $.extend({}, this.defaults, { body : '' }, old_options, options, { maximized: false }); - // need timer because popup might not be open - setTimeout(function () { $('#w2ui-popup').data('options', options); }, 100); - // if new - reset event handlers - if ($('#w2ui-popup').length == 0) { - w2popup.handlers = []; - w2popup.onMax = null; - w2popup.onMin = null; - w2popup.onToggle = null; - w2popup.onOpen = null; - w2popup.onClose = null; - w2popup.onKeydown = null; - } - if (options.onOpen) w2popup.onOpen = options.onOpen; - if (options.onClose) w2popup.onClose = options.onClose; - if (options.onMax) w2popup.onMax = options.onMax; - if (options.onMin) w2popup.onMin = options.onMin; - if (options.onToggle) w2popup.onToggle = options.onToggle; - if (options.onKeydown) w2popup.onKeydown = options.onKeydown; - - if (window.innerHeight == undefined) { - var width = document.documentElement.offsetWidth; - var height = document.documentElement.offsetHeight; - if (w2utils.engine === 'IE7') { width += 21; height += 4; } - } else { - var width = window.innerWidth; - var height = window.innerHeight; - } - if (parseInt(width) - 10 < parseInt(options.width)) options.width = parseInt(width) - 10; - if (parseInt(height) - 10 < parseInt(options.height)) options.height = parseInt(height) - 10; - var top = ((parseInt(height) - parseInt(options.height)) / 2) * 0.6; - var left = (parseInt(width) - parseInt(options.width)) / 2; - // check if message is already displayed - if ($('#w2ui-popup').length == 0) { - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: false }); - if (eventData.isCancelled === true) return; - w2popup.status = 'opening'; - // output message - w2popup.lockScreen(options); - var msg = '
      '; - if (options.title != '') { - msg +='
      '+ - (options.showClose ? '
      Close
      ' : '')+ - (options.showMax ? '
      Max
      ' : '') + - options.title + - '
      '; - } - msg += '
      '; - msg += '
      ' + options.body + '
      '; - msg += '
      '; - msg += '
      '; - msg += '
      '; - msg += '
      '; - if (options.buttons != '') { - msg += '
      ' + options.buttons + '
      '; - } - msg += '
      '; - $('body').append(msg); - // allow element to render - setTimeout(function () { - $('#w2ui-popup .w2ui-box2').hide(); - $('#w2ui-popup').css({ - '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', - '-webkit-transform': 'scale(1)', - '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', - '-moz-transform': 'scale(1)', - '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', - '-ms-transform': 'scale(1)', - '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', - '-o-transform': 'scale(1)', - 'opacity': '1' - }); - }, 1); - // clean transform - setTimeout(function () { - $('#w2ui-popup').css({ - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '' - }); - // event after - w2popup.status = 'open'; - setTimeout(function () { - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 100); - }, options.speed * 1000); - } else { - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: true }); - if (eventData.isCancelled === true) return; - // check if size changed - w2popup.status = 'opening'; - if (typeof old_options == 'undefined' || old_options['width'] != options['width'] || old_options['height'] != options['height']) { - w2popup.resize(options.width, options.height); - } - if (typeof old_options != 'undefined') { - options.prevSize = options.width + ':' + options.height; - options.maximized = old_options.maximized; - } - // show new items - var body = $('#w2ui-popup .w2ui-box2 > .w2ui-msg-body').html(options.body); - if (body.length > 0) body[0].style.cssText = options.style; - $('#w2ui-popup .w2ui-msg-buttons').html(options.buttons); - $('#w2ui-popup .w2ui-msg-title').html( - (options.showClose ? '
      Close
      ' : '')+ - (options.showMax ? '
      Max
      ' : '') + - options.title); - // transition - var div_old = $('#w2ui-popup .w2ui-box1')[0]; - var div_new = $('#w2ui-popup .w2ui-box2')[0]; - w2utils.transition(div_old, div_new, options.transition); - div_new.className = 'w2ui-box1'; - div_old.className = 'w2ui-box2'; - $(div_new).addClass('w2ui-current-box'); - // remove max state - $('#w2ui-popup').data('prev-size', null); - // call event onChange - setTimeout(function () { - w2popup.status = 'open'; - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 100); - } - // save new options - options._last_w2ui_name = w2utils.keyboard.active(); - w2utils.keyboard.active(null); - // keyboard events - if (options.keyboard) $(document).on('keydown', this.keydown); - - // initialize move - var tmp = { - resizing: false, - mvMove : mvMove, - mvStop : mvStop - }; - $('#w2ui-popup .w2ui-msg-title').on('mousedown', function (event) { mvStart(event); }) - - // handlers - function mvStart(evnt) { - if (!evnt) evnt = window.event; - if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } - w2popup.status = 'moving'; - tmp.resizing = true; - tmp.x = evnt.screenX; - tmp.y = evnt.screenY; - tmp.pos_x = $('#w2ui-popup').position().left; - tmp.pos_y = $('#w2ui-popup').position().top; - w2popup.lock({ opacity: 0 }); - $(document).on('mousemove', tmp.mvMove); - $(document).on('mouseup', tmp.mvStop); - if (evnt.stopPropagation) evnt.stopPropagation(); else evnt.cancelBubble = true; - if (evnt.preventDefault) evnt.preventDefault(); else return false; - } - - function mvMove(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - tmp.div_x = evnt.screenX - tmp.x; - tmp.div_y = evnt.screenY - tmp.y; - $('#w2ui-popup').css({ - '-webkit-transition': 'none', - '-webkit-transform': 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)', - '-moz-transition': 'none', - '-moz-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', - '-ms-transition': 'none', - '-ms-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', - '-o-transition': 'none', - '-o-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)' - }); - } - - function mvStop(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - w2popup.status = 'open'; - tmp.div_x = (evnt.screenX - tmp.x); - tmp.div_y = (evnt.screenY - tmp.y); - $('#w2ui-popup').css({ - 'left': (tmp.pos_x + tmp.div_x) + 'px', - 'top': (tmp.pos_y + tmp.div_y) + 'px', - '-webkit-transition': 'none', - '-webkit-transform': 'translate3d(0px, 0px, 0px)', - '-moz-transition': 'none', - '-moz-transform': 'translate(0px, 0px)', - '-ms-transition': 'none', - '-ms-transform': 'translate(0px, 0px)', - '-o-transition': 'none', - '-o-transform': 'translate(0px, 0px)', - }); - tmp.resizing = false; - $(document).off('mousemove', tmp.mvMove); - $(document).off('mouseup', tmp.mvStop); - w2popup.unlock(); - } - return this; - }, - - keydown: function (event) { - var options = $('#w2ui-popup').data('options'); - if (!options.keyboard) return; - // trigger event - var eventData = w2popup.trigger({ phase: 'before', type: 'keydown', target: 'popup', options: options, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behavior - switch (event.keyCode) { - case 27: - event.preventDefault(); - if ($('#w2ui-popup .w2ui-popup-message').length > 0) w2popup.message(); else w2popup.close(); - break; - } - // event after - w2popup.trigger($.extend(eventData, { phase: 'after'})); - }, - - close: function (options) { - var obj = this; - var options = $.extend({}, $('#w2ui-popup').data('options'), options); - if ($('#w2ui-popup').length == 0) return; - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'close', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // default behavior - w2popup.status = 'closing'; - $('#w2ui-popup').css({ - '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', - '-webkit-transform': 'scale(0.9)', - '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', - '-moz-transform': 'scale(0.9)', - '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', - '-ms-transform': 'scale(0.9)', - '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', - '-o-transform': 'scale(0.9)', - 'opacity': '0' - }); - w2popup.unlockScreen(options); - setTimeout(function () { - $('#w2ui-popup').remove(); - w2popup.status = 'closed'; - // event after - obj.trigger($.extend(eventData, { phase: 'after'})); - }, options.speed * 1000); - // restore active - w2utils.keyboard.active(options._last_w2ui_name); - // remove keyboard events - if (options.keyboard) $(document).off('keydown', this.keydown); - }, - - toggle: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'toggle', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // defatul action - if (options.maximized === true) w2popup.min(); else w2popup.max(); - // event after - setTimeout(function () { - obj.trigger($.extend(eventData, { phase: 'after'})); - }, 250); - }, - - max: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - if (options.maximized === true) return; - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'max', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // default behavior - w2popup.status = 'resizing'; - options.prevSize = $('#w2ui-popup').css('width')+':'+$('#w2ui-popup').css('height'); - // do resize - w2popup.resize(10000, 10000, function () { - w2popup.status = 'open'; - options.maximized = true; - obj.trigger($.extend(eventData, { phase: 'after'})); - }); - }, - - min: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - if (options.maximized !== true) return; - var size = options.prevSize.split(':'); - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'min', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // default behavior - w2popup.status = 'resizing'; - // do resize - w2popup.resize(size[0], size[1], function () { - w2popup.status = 'open'; - options.maximized = false; - options.prevSize = null; - obj.trigger($.extend(eventData, { phase: 'after'})); - }); - }, - - get: function () { - return $('#w2ui-popup').data('options'); - }, - - set: function (options) { - w2popup.open(options); - }, - - clear: function() { - $('#w2ui-popup .w2ui-msg-title').html(''); - $('#w2ui-popup .w2ui-msg-body').html(''); - $('#w2ui-popup .w2ui-msg-buttons').html(''); - }, - - reset: function () { - w2popup.open(w2popup.defaults); - }, - - load: function (options) { - w2popup.status = 'loading'; - if (String(options.url) == 'undefined') { - console.log('ERROR: The url parameter is empty.'); - return; - } - var tmp = String(options.url).split('#'); - var url = tmp[0]; - var selector = tmp[1]; - if (String(options) == 'undefined') options = {}; - // load url - var html = $('#w2ui-popup').data(url); - if (typeof html != 'undefined' && html != null) { - popup(html, selector); - } else { - $.get(url, function (data, status, obj) { - popup(obj.responseText, selector); - $('#w2ui-popup').data(url, obj.responseText); // remember for possible future purposes - }); - } - function popup(html, selector) { - delete options.url; - $('body').append(''); - if (typeof selector != 'undefined' && $('#w2ui-tmp #'+selector).length > 0) { - $('#w2ui-tmp #' + selector).w2popup(options); - } else { - $('#w2ui-tmp > div').w2popup(options); - } - // link styles - if ($('#w2ui-tmp > style').length > 0) { - var style = $('
      ').append($('#w2ui-tmp > style').clone()).html(); - if ($('#w2ui-popup #div-style').length == 0) { - $('#w2ui-popup').append('
      '); - } - $('#w2ui-popup #div-style').html(style); - } - $('#w2ui-tmp').remove(); - } - }, - - message: function (options) { - $().w2tag(); // hide all tags - if (!options) options = { width: 200, height: 100 }; - if (parseInt(options.width) < 10) options.width = 10; - if (parseInt(options.height) < 10) options.height = 10; - if (typeof options.hideOnClick == 'undefined') options.hideOnClick = false; - var poptions = $('#w2ui-popup').data('options') - if (typeof options.width == 'undefined' || options.width > poptions.width - 10) options.width = poptions.width - 10; - if (typeof options.height == 'undefined' || options.height > poptions.height - 40) options.height = poptions.height - 40; // title is 30px or so - - var head = $('#w2ui-popup .w2ui-msg-title'); - var pwidth = parseInt($('#w2ui-popup').width()); - var msgCount = $('#w2ui-popup .w2ui-popup-message').length; - // remove message - if ($.trim(options.html) == '') { - $('#w2ui-popup #w2ui-message'+ (msgCount-1)).css('z-Index', 250); - var options = $('#w2ui-popup #w2ui-message'+ (msgCount-1)).data('options') || {}; - $('#w2ui-popup #w2ui-message'+ (msgCount-1)).remove(); - if (typeof options.onClose == 'function') options.onClose(); - if (msgCount == 1) { - w2popup.unlock(); - } else { - $('#w2ui-popup #w2ui-message'+ (msgCount-2)).show(); - } - } else { - // hide previous messages - $('#w2ui-popup .w2ui-popup-message').hide(); - // add message - $('#w2ui-popup .w2ui-box1') - .before(''); - $('#w2ui-popup #w2ui-message'+ msgCount).data('options', options); - var display = $('#w2ui-popup #w2ui-message'+ msgCount).css('display'); - $('#w2ui-popup #w2ui-message'+ msgCount).css({ - '-webkit-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), - '-moz-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), - '-ms-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), - '-o-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)') - }); - if (display == 'none') { - $('#w2ui-popup #w2ui-message'+ msgCount).show().html(options.html); - // timer needs to animation - setTimeout(function () { - $('#w2ui-popup #w2ui-message'+ msgCount).css({ - '-webkit-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), - '-moz-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), - '-ms-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), - '-o-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') - }); - }, 1); - // timer for lock - setTimeout(function() { - $('#w2ui-popup #w2ui-message'+ msgCount).css({ - '-webkit-transition': '0s', '-moz-transition': '0s', '-ms-transition': '0s', '-o-transition': '0s', - 'z-Index': 1500 - }); // has to be on top of lock - if (msgCount == 0) w2popup.lock(); - if (typeof options.onOpen == 'function') options.onOpen(); - }, 300); - } - } - }, - - lock: function (msg, showSpinner) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift($('#w2ui-popup')); - w2utils.lock.apply(window, args); - }, - - unlock: function () { - w2utils.unlock($('#w2ui-popup')); - }, - - // --- INTERNAL FUNCTIONS - - lockScreen: function (options) { - if ($('#w2ui-lock').length > 0) return false; - if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); - if (typeof options == 'undefined') options = {}; - options = $.extend({}, w2popup.defaults, options); - // show element - $('body').append('
      '); - // lock screen - setTimeout(function () { - $('#w2ui-lock').css({ - '-webkit-transition': options.speed + 's opacity', - '-moz-transition': options.speed + 's opacity', - '-ms-transition': options.speed + 's opacity', - '-o-transition': options.speed + 's opacity', - 'opacity': options.opacity - }); - }, 1); - // add events - if (options.modal == true) { - $('#w2ui-lock').on('mousedown', function () { - $('#w2ui-lock').css({ - '-webkit-transition': '.1s', - '-moz-transition': '.1s', - '-ms-transition': '.1s', - '-o-transition': '.1s', - 'opacity': '0.6' - }); - // if (window.getSelection) window.getSelection().removeAllRanges(); - }); - $('#w2ui-lock').on('mouseup', function () { - setTimeout(function () { - $('#w2ui-lock').css({ - '-webkit-transition': '.1s', - '-moz-transition': '.1s', - '-ms-transition': '.1s', - '-o-transition': '.1s', - 'opacity': options.opacity - }); - }, 100); - // if (window.getSelection) window.getSelection().removeAllRanges(); - }); - } else { - $('#w2ui-lock').on('mouseup', function () { w2popup.close(); }); - } - return true; - }, - - unlockScreen: function (options) { - if ($('#w2ui-lock').length == 0) return false; - if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); - if (typeof options == 'undefined') options = {}; - options = $.extend({}, w2popup.defaults, options); - $('#w2ui-lock').css({ - '-webkit-transition': options.speed + 's opacity', - '-moz-transition': options.speed + 's opacity', - '-ms-transition': options.speed + 's opacity', - '-o-transition': options.speed + 's opacity', - 'opacity': 0 - }); - setTimeout(function () { - $('#w2ui-lock').remove(); - }, options.speed * 1000); - return true; - }, - - resize: function (width, height, callBack) { - var options = $('#w2ui-popup').data('options'); - // calculate new position - if (parseInt($(window).width()) - 10 < parseInt(width)) width = parseInt($(window).width()) - 10; - if (parseInt($(window).height()) - 10 < parseInt(height)) height = parseInt($(window).height()) - 10; - var top = ((parseInt($(window).height()) - parseInt(height)) / 2) * 0.8; - var left = (parseInt($(window).width()) - parseInt(width)) / 2; - // resize there - $('#w2ui-popup').css({ - '-webkit-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - '-moz-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - '-ms-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - '-o-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', - 'top': top, - 'left': left, - 'width': width, - 'height': height - }); - if (typeof callBack == 'function') { - setTimeout(function () { - callBack(); - }, options.speed * 1000); - } - } - } - - // merge in event handling - $.extend(w2popup, w2utils.event); + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2popup = function(method, options) { + if (typeof method === 'undefined') { + options = {}; + method = 'open'; + } + if ($.isPlainObject(method)) { + options = method; + method = 'open'; + } + method = method.toLowerCase(); + if (method === 'load' && typeof options === 'string') { + options = $.extend({ url: options }, arguments.length > 2 ? arguments[2] : {}); + } + if (method === 'open' && options.url != null) method = 'load'; + options = options || {}; + // load options from markup + var dlgOptions = {}; + if ($(this).length > 0) { + if ($(this).find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { + if ($(this).find('div[rel=title]').length > 0) { + dlgOptions['title'] = $(this).find('div[rel=title]').html(); + } + if ($(this).find('div[rel=body]').length > 0) { + dlgOptions['body'] = $(this).find('div[rel=body]').html(); + dlgOptions['style'] = $(this).find('div[rel=body]')[0].style.cssText; + } + if ($(this).find('div[rel=buttons]').length > 0) { + dlgOptions['buttons'] = $(this).find('div[rel=buttons]').html(); + } + } else { + dlgOptions['title'] = ' '; + dlgOptions['body'] = $(this).html(); + } + if (parseInt($(this).css('width')) != 0) dlgOptions['width'] = parseInt($(this).css('width')); + if (parseInt($(this).css('height')) != 0) dlgOptions['height'] = parseInt($(this).css('height')); + } + // show popup + return w2popup[method]($.extend({}, dlgOptions, options)); + }; + + // ==================================================== + // -- Implementation of core functionality (SINGELTON) + + w2popup = { + defaults: { + title : '', + body : '', + buttons : '', + style : '', + color : '#000', + opacity : 0.4, + speed : 0.3, + modal : false, + maximized : false, + keyboard : true, // will close popup on esc if not modal + width : 500, + height : 300, + showClose : true, + showMax : false, + transition: null + }, + status : 'closed', // string that describes current status + handlers : [], + onOpen : null, + onClose : null, + onMax : null, + onMin : null, + onToggle : null, + onKeydown : null, + + open: function (options) { + var obj = this; + if (w2popup.status == 'closing') { + setTimeout(function () { obj.open.call(obj, options); }, 100); + return; + } + // get old options and merge them + var old_options = $('#w2ui-popup').data('options'); + var options = $.extend({}, this.defaults, { body : '' }, old_options, options, { maximized: false }); + // need timer because popup might not be open + setTimeout(function () { $('#w2ui-popup').data('options', options); }, 100); + // if new - reset event handlers + if ($('#w2ui-popup').length == 0) { + w2popup.handlers = []; + w2popup.onMax = null; + w2popup.onMin = null; + w2popup.onToggle = null; + w2popup.onOpen = null; + w2popup.onClose = null; + w2popup.onKeydown = null; + } + if (options.onOpen) w2popup.onOpen = options.onOpen; + if (options.onClose) w2popup.onClose = options.onClose; + if (options.onMax) w2popup.onMax = options.onMax; + if (options.onMin) w2popup.onMin = options.onMin; + if (options.onToggle) w2popup.onToggle = options.onToggle; + if (options.onKeydown) w2popup.onKeydown = options.onKeydown; + + if (window.innerHeight == undefined) { + var width = document.documentElement.offsetWidth; + var height = document.documentElement.offsetHeight; + if (w2utils.engine === 'IE7') { width += 21; height += 4; } + } else { + var width = window.innerWidth; + var height = window.innerHeight; + } + if (parseInt(width) - 10 < parseInt(options.width)) options.width = parseInt(width) - 10; + if (parseInt(height) - 10 < parseInt(options.height)) options.height = parseInt(height) - 10; + var top = ((parseInt(height) - parseInt(options.height)) / 2) * 0.6; + var left = (parseInt(width) - parseInt(options.width)) / 2; + // check if message is already displayed + if ($('#w2ui-popup').length == 0) { + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: false }); + if (eventData.isCancelled === true) return; + w2popup.status = 'opening'; + // output message + w2popup.lockScreen(options); + var msg = '
      '; + if (options.title != '') { + msg +='
      '+ + (options.showClose ? '
      Close
      ' : '')+ + (options.showMax ? '
      Max
      ' : '') + + options.title + + '
      '; + } + msg += '
      '; + msg += '
      ' + options.body + '
      '; + msg += '
      '; + msg += '
      '; + msg += '
      '; + msg += '
      '; + if (options.buttons != '') { + msg += '
      ' + options.buttons + '
      '; + } + msg += '
      '; + $('body').append(msg); + // allow element to render + setTimeout(function () { + $('#w2ui-popup .w2ui-box2').hide(); + $('#w2ui-popup').css({ + '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', + '-webkit-transform': 'scale(1)', + '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', + '-moz-transform': 'scale(1)', + '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', + '-ms-transform': 'scale(1)', + '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', + '-o-transform': 'scale(1)', + 'opacity': '1' + }); + }, 1); + // clean transform + setTimeout(function () { + $('#w2ui-popup').css({ + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '' + }); + // event after + w2popup.status = 'open'; + setTimeout(function () { + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 100); + }, options.speed * 1000); + } else { + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: true }); + if (eventData.isCancelled === true) return; + // check if size changed + w2popup.status = 'opening'; + if (typeof old_options == 'undefined' || old_options['width'] != options['width'] || old_options['height'] != options['height']) { + w2popup.resize(options.width, options.height); + } + if (typeof old_options != 'undefined') { + options.prevSize = options.width + ':' + options.height; + options.maximized = old_options.maximized; + } + // show new items + var body = $('#w2ui-popup .w2ui-box2 > .w2ui-msg-body').html(options.body); + if (body.length > 0) body[0].style.cssText = options.style; + $('#w2ui-popup .w2ui-msg-buttons').html(options.buttons); + $('#w2ui-popup .w2ui-msg-title').html( + (options.showClose ? '
      Close
      ' : '')+ + (options.showMax ? '
      Max
      ' : '') + + options.title); + // transition + var div_old = $('#w2ui-popup .w2ui-box1')[0]; + var div_new = $('#w2ui-popup .w2ui-box2')[0]; + w2utils.transition(div_old, div_new, options.transition); + div_new.className = 'w2ui-box1'; + div_old.className = 'w2ui-box2'; + $(div_new).addClass('w2ui-current-box'); + // remove max state + $('#w2ui-popup').data('prev-size', null); + // call event onChange + setTimeout(function () { + w2popup.status = 'open'; + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 100); + } + // save new options + options._last_w2ui_name = w2utils.keyboard.active(); + w2utils.keyboard.active(null); + // keyboard events + if (options.keyboard) $(document).on('keydown', this.keydown); + + // initialize move + var tmp = { + resizing : false, + mvMove : mvMove, + mvStop : mvStop + }; + $('#w2ui-popup .w2ui-msg-title').on('mousedown', function (event) { mvStart(event); }) + + // handlers + function mvStart(evnt) { + if (!evnt) evnt = window.event; + if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } + w2popup.status = 'moving'; + tmp.resizing = true; + tmp.x = evnt.screenX; + tmp.y = evnt.screenY; + tmp.pos_x = $('#w2ui-popup').position().left; + tmp.pos_y = $('#w2ui-popup').position().top; + w2popup.lock({ opacity: 0 }); + $(document).on('mousemove', tmp.mvMove); + $(document).on('mouseup', tmp.mvStop); + if (evnt.stopPropagation) evnt.stopPropagation(); else evnt.cancelBubble = true; + if (evnt.preventDefault) evnt.preventDefault(); else return false; + } + + function mvMove(evnt) { + if (tmp.resizing != true) return; + if (!evnt) evnt = window.event; + tmp.div_x = evnt.screenX - tmp.x; + tmp.div_y = evnt.screenY - tmp.y; + $('#w2ui-popup').css({ + '-webkit-transition': 'none', + '-webkit-transform': 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)', + '-moz-transition': 'none', + '-moz-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', + '-ms-transition': 'none', + '-ms-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)', + '-o-transition': 'none', + '-o-transform': 'translate('+ tmp.div_x +'px, '+ tmp.div_y +'px)' + }); + } + + function mvStop(evnt) { + if (tmp.resizing != true) return; + if (!evnt) evnt = window.event; + w2popup.status = 'open'; + tmp.div_x = (evnt.screenX - tmp.x); + tmp.div_y = (evnt.screenY - tmp.y); + $('#w2ui-popup').css({ + 'left': (tmp.pos_x + tmp.div_x) + 'px', + 'top': (tmp.pos_y + tmp.div_y) + 'px', + '-webkit-transition': 'none', + '-webkit-transform': 'translate3d(0px, 0px, 0px)', + '-moz-transition': 'none', + '-moz-transform': 'translate(0px, 0px)', + '-ms-transition': 'none', + '-ms-transform': 'translate(0px, 0px)', + '-o-transition': 'none', + '-o-transform': 'translate(0px, 0px)', + }); + tmp.resizing = false; + $(document).off('mousemove', tmp.mvMove); + $(document).off('mouseup', tmp.mvStop); + w2popup.unlock(); + } + return this; + }, + + keydown: function (event) { + var options = $('#w2ui-popup').data('options'); + if (!options.keyboard) return; + // trigger event + var eventData = w2popup.trigger({ phase: 'before', type: 'keydown', target: 'popup', options: options, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behavior + switch (event.keyCode) { + case 27: + event.preventDefault(); + if ($('#w2ui-popup .w2ui-popup-message').length > 0) w2popup.message(); else w2popup.close(); + break; + } + // event after + w2popup.trigger($.extend(eventData, { phase: 'after'})); + }, + + close: function (options) { + var obj = this; + var options = $.extend({}, $('#w2ui-popup').data('options'), options); + if ($('#w2ui-popup').length == 0) return; + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'close', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // default behavior + w2popup.status = 'closing'; + $('#w2ui-popup').css({ + '-webkit-transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', + '-webkit-transform': 'scale(0.9)', + '-moz-transition': options.speed + 's opacity, ' + options.speed + 's -moz-transform', + '-moz-transform': 'scale(0.9)', + '-ms-transition': options.speed + 's opacity, ' + options.speed + 's -ms-transform', + '-ms-transform': 'scale(0.9)', + '-o-transition': options.speed + 's opacity, ' + options.speed + 's -o-transform', + '-o-transform': 'scale(0.9)', + 'opacity': '0' + }); + w2popup.unlockScreen(options); + setTimeout(function () { + $('#w2ui-popup').remove(); + w2popup.status = 'closed'; + // event after + obj.trigger($.extend(eventData, { phase: 'after'})); + }, options.speed * 1000); + // restore active + w2utils.keyboard.active(options._last_w2ui_name); + // remove keyboard events + if (options.keyboard) $(document).off('keydown', this.keydown); + }, + + toggle: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'toggle', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // defatul action + if (options.maximized === true) w2popup.min(); else w2popup.max(); + // event after + setTimeout(function () { + obj.trigger($.extend(eventData, { phase: 'after'})); + }, 250); + }, + + max: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + if (options.maximized === true) return; + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'max', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // default behavior + w2popup.status = 'resizing'; + options.prevSize = $('#w2ui-popup').css('width')+':'+$('#w2ui-popup').css('height'); + // do resize + w2popup.resize(10000, 10000, function () { + w2popup.status = 'open'; + options.maximized = true; + obj.trigger($.extend(eventData, { phase: 'after'})); + }); + }, + + min: function () { + var obj = this; + var options = $('#w2ui-popup').data('options'); + if (options.maximized !== true) return; + var size = options.prevSize.split(':'); + // trigger event + var eventData = this.trigger({ phase: 'before', type: 'min', target: 'popup', options: options }); + if (eventData.isCancelled === true) return; + // default behavior + w2popup.status = 'resizing'; + // do resize + w2popup.resize(size[0], size[1], function () { + w2popup.status = 'open'; + options.maximized = false; + options.prevSize = null; + obj.trigger($.extend(eventData, { phase: 'after'})); + }); + }, + + get: function () { + return $('#w2ui-popup').data('options'); + }, + + set: function (options) { + w2popup.open(options); + }, + + clear: function() { + $('#w2ui-popup .w2ui-msg-title').html(''); + $('#w2ui-popup .w2ui-msg-body').html(''); + $('#w2ui-popup .w2ui-msg-buttons').html(''); + }, + + reset: function () { + w2popup.open(w2popup.defaults); + }, + + load: function (options) { + w2popup.status = 'loading'; + if (String(options.url) == 'undefined') { + console.log('ERROR: The url parameter is empty.'); + return; + } + var tmp = String(options.url).split('#'); + var url = tmp[0]; + var selector = tmp[1]; + if (String(options) == 'undefined') options = {}; + // load url + var html = $('#w2ui-popup').data(url); + if (typeof html != 'undefined' && html != null) { + popup(html, selector); + } else { + $.get(url, function (data, status, obj) { + popup(obj.responseText, selector); + $('#w2ui-popup').data(url, obj.responseText); // remember for possible future purposes + }); + } + function popup(html, selector) { + delete options.url; + $('body').append(''); + if (typeof selector != 'undefined' && $('#w2ui-tmp #'+selector).length > 0) { + $('#w2ui-tmp #' + selector).w2popup(options); + } else { + $('#w2ui-tmp > div').w2popup(options); + } + // link styles + if ($('#w2ui-tmp > style').length > 0) { + var style = $('
      ').append($('#w2ui-tmp > style').clone()).html(); + if ($('#w2ui-popup #div-style').length == 0) { + $('#w2ui-popup').append('
      '); + } + $('#w2ui-popup #div-style').html(style); + } + $('#w2ui-tmp').remove(); + } + }, + + message: function (options) { + $().w2tag(); // hide all tags + if (!options) options = { width: 200, height: 100 }; + if (parseInt(options.width) < 10) options.width = 10; + if (parseInt(options.height) < 10) options.height = 10; + if (typeof options.hideOnClick == 'undefined') options.hideOnClick = false; + var poptions = $('#w2ui-popup').data('options') + if (typeof options.width == 'undefined' || options.width > poptions.width - 10) options.width = poptions.width - 10; + if (typeof options.height == 'undefined' || options.height > poptions.height - 40) options.height = poptions.height - 40; // title is 30px or so + + var head = $('#w2ui-popup .w2ui-msg-title'); + var pwidth = parseInt($('#w2ui-popup').width()); + var msgCount = $('#w2ui-popup .w2ui-popup-message').length; + // remove message + if ($.trim(options.html) == '') { + $('#w2ui-popup #w2ui-message'+ (msgCount-1)).css('z-Index', 250); + var options = $('#w2ui-popup #w2ui-message'+ (msgCount-1)).data('options') || {}; + $('#w2ui-popup #w2ui-message'+ (msgCount-1)).remove(); + if (typeof options.onClose == 'function') options.onClose(); + if (msgCount == 1) { + w2popup.unlock(); + } else { + $('#w2ui-popup #w2ui-message'+ (msgCount-2)).show(); + } + } else { + // hide previous messages + $('#w2ui-popup .w2ui-popup-message').hide(); + // add message + $('#w2ui-popup .w2ui-box1') + .before(''); + $('#w2ui-popup #w2ui-message'+ msgCount).data('options', options); + var display = $('#w2ui-popup #w2ui-message'+ msgCount).css('display'); + $('#w2ui-popup #w2ui-message'+ msgCount).css({ + '-webkit-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), + '-moz-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), + '-ms-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)'), + '-o-transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)') + }); + if (display == 'none') { + $('#w2ui-popup #w2ui-message'+ msgCount).show().html(options.html); + // timer needs to animation + setTimeout(function () { + $('#w2ui-popup #w2ui-message'+ msgCount).css({ + '-webkit-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), + '-moz-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), + '-ms-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)'), + '-o-transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') + }); + }, 1); + // timer for lock + setTimeout(function() { + $('#w2ui-popup #w2ui-message'+ msgCount).css({ + '-webkit-transition': '0s', '-moz-transition': '0s', '-ms-transition': '0s', '-o-transition': '0s', + 'z-Index': 1500 + }); // has to be on top of lock + if (msgCount == 0) w2popup.lock(); + if (typeof options.onOpen == 'function') options.onOpen(); + }, 300); + } + } + }, + + lock: function (msg, showSpinner) { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift($('#w2ui-popup')); + w2utils.lock.apply(window, args); + }, + + unlock: function () { + w2utils.unlock($('#w2ui-popup')); + }, + + // --- INTERNAL FUNCTIONS + + lockScreen: function (options) { + if ($('#w2ui-lock').length > 0) return false; + if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); + if (typeof options == 'undefined') options = {}; + options = $.extend({}, w2popup.defaults, options); + // show element + $('body').append('
      '); + // lock screen + setTimeout(function () { + $('#w2ui-lock').css({ + '-webkit-transition': options.speed + 's opacity', + '-moz-transition': options.speed + 's opacity', + '-ms-transition': options.speed + 's opacity', + '-o-transition': options.speed + 's opacity', + 'opacity': options.opacity + }); + }, 1); + // add events + if (options.modal == true) { + $('#w2ui-lock').on('mousedown', function () { + $('#w2ui-lock').css({ + '-webkit-transition': '.1s', + '-moz-transition': '.1s', + '-ms-transition': '.1s', + '-o-transition': '.1s', + 'opacity': '0.6' + }); + // if (window.getSelection) window.getSelection().removeAllRanges(); + }); + $('#w2ui-lock').on('mouseup', function () { + setTimeout(function () { + $('#w2ui-lock').css({ + '-webkit-transition': '.1s', + '-moz-transition': '.1s', + '-ms-transition': '.1s', + '-o-transition': '.1s', + 'opacity': options.opacity + }); + }, 100); + // if (window.getSelection) window.getSelection().removeAllRanges(); + }); + } else { + $('#w2ui-lock').on('mouseup', function () { w2popup.close(); }); + } + return true; + }, + + unlockScreen: function (options) { + if ($('#w2ui-lock').length == 0) return false; + if (typeof options == 'undefined') options = $('#w2ui-popup').data('options'); + if (typeof options == 'undefined') options = {}; + options = $.extend({}, w2popup.defaults, options); + $('#w2ui-lock').css({ + '-webkit-transition': options.speed + 's opacity', + '-moz-transition': options.speed + 's opacity', + '-ms-transition': options.speed + 's opacity', + '-o-transition': options.speed + 's opacity', + 'opacity': 0 + }); + setTimeout(function () { + $('#w2ui-lock').remove(); + }, options.speed * 1000); + return true; + }, + + resize: function (width, height, callBack) { + var options = $('#w2ui-popup').data('options'); + // calculate new position + if (parseInt($(window).width()) - 10 < parseInt(width)) width = parseInt($(window).width()) - 10; + if (parseInt($(window).height()) - 10 < parseInt(height)) height = parseInt($(window).height()) - 10; + var top = ((parseInt($(window).height()) - parseInt(height)) / 2) * 0.8; + var left = (parseInt($(window).width()) - parseInt(width)) / 2; + // resize there + $('#w2ui-popup').css({ + '-webkit-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + '-moz-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + '-ms-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + '-o-transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top', + 'top': top, + 'left': left, + 'width': width, + 'height': height + }); + if (typeof callBack == 'function') { + setTimeout(function () { + callBack(); + }, options.speed * 1000); + } + } + } + + // merge in event handling + $.extend(w2popup, w2utils.event); })(); @@ -645,53 +645,53 @@ var w2popup = {}; // --- Common dialogs var w2alert = function (msg, title, callBack) { - if (typeof title == 'undefined') title = w2utils.lang('Notification'); - if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { - w2popup.message({ - width : 400, - height : 150, - html : '
      ' + - '
      ' + msg + '
      ' + - '
      ' + - '
      ' + - ' ' + - '
      ', - onClose : function () { - if (typeof callBack == 'function') callBack(); - } - }); - } else { - w2popup.open({ - width : 450, - height : 200, - showMax : false, - title : title, - body : '
      ' + msg + '
      ', - buttons : '', - onClose : function () { - if (typeof callBack == 'function') callBack(); - } - }); - } + if (typeof title == 'undefined') title = w2utils.lang('Notification'); + if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + w2popup.message({ + width : 400, + height : 150, + html : '
      ' + + '
      ' + msg + '
      ' + + '
      ' + + '
      ' + + ' ' + + '
      ', + onClose : function () { + if (typeof callBack == 'function') callBack(); + } + }); + } else { + w2popup.open({ + width : 450, + height : 200, + showMax : false, + title : title, + body : '
      ' + msg + '
      ', + buttons : '', + onClose : function () { + if (typeof callBack == 'function') callBack(); + } + }); + } }; var w2confirm = function (obj, callBack) { var w2confirm_width = 400, w2confirm_height = 150, - w2confirm_yes_text = 'Yes', + w2confirm_yes_text = 'Yes', w2confirm_yes_class = '', w2confirm_yes_style = '', - w2confirm_no_text = 'No', + w2confirm_no_text = 'No', w2confirm_no_class = '', w2confirm_no_style = '', title = w2utils.lang('Confirmation'); if (arguments.length == 1 && typeof obj == 'object') { - var msg = w2utils.lang(obj['msg']), - callBack = obj['callBack'], - btn_yes = obj['btn_yes'], - btn_no = obj['btn_no']; + var msg = w2utils.lang(obj['msg']), + callBack = obj['callBack'], + btn_yes = obj['btn_yes'], + btn_no = obj['btn_no']; if (obj.title) title = w2utils.lang(obj['title']); if (w2utils.isInt(obj.width)) w2confirm_width = obj.width; @@ -713,70 +713,70 @@ var w2confirm = function (obj, callBack) { var msg = obj; } - if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { if (w2confirm_width > w2popup.get().width) w2confirm_width = w2popup.get().width; if (w2confirm_height > (w2popup.get().height - 50)) w2confirm_height = w2popup.get().height - 50; - w2popup.message({ - width : w2confirm_width, - height : w2confirm_height, - html : '
      ' + - '
      ' + msg + '
      ' + - '
      ' + - '
      ' + - ' ' + - ' ' + - '
      ', - onOpen: function () { - $('#w2ui-popup .w2ui-popup-message .btn').on('click', function (event) { - w2popup.message(); - if (typeof callBack == 'function') callBack(event.target.id); - }); - }, - onKeydown: function (event) { - switch (event.originalEvent.keyCode) { - case 13: // enter - if (typeof callBack == 'function') callBack('Yes'); - w2popup.message(); - break - case 27: // esc - if (typeof callBack == 'function') callBack('No'); - w2popup.message(); - break - } - } - }); - } else { + w2popup.message({ + width : w2confirm_width, + height : w2confirm_height, + html : '
      ' + + '
      ' + msg + '
      ' + + '
      ' + + '
      ' + + ' ' + + ' ' + + '
      ', + onOpen: function () { + $('#w2ui-popup .w2ui-popup-message .btn').on('click', function (event) { + w2popup.message(); + if (typeof callBack == 'function') callBack(event.target.id); + }); + }, + onKeydown: function (event) { + switch (event.originalEvent.keyCode) { + case 13: // enter + if (typeof callBack == 'function') callBack('Yes'); + w2popup.message(); + break + case 27: // esc + if (typeof callBack == 'function') callBack('No'); + w2popup.message(); + break + } + } + }); + } else { if (!w2utils.isInt(obj.height)) w2confirm_height = w2confirm_height + 50; w2popup.open({ - width : w2confirm_width, - height : w2confirm_height, - title : title, - modal : true, - showClose : false, - body : '
      ' + msg + '
      ', - buttons : ''+ - '', - onOpen: function (event) { - event.onComplete = function () { - $('#w2ui-popup .w2ui-popup-btn').on('click', function (event) { - w2popup.close(); - if (typeof callBack == 'function') callBack(event.target.id); - }); - } - }, - onKeydown: function (event) { - switch (event.originalEvent.keyCode) { - case 13: // enter - if (typeof callBack == 'function') callBack('Yes'); - w2popup.close(); - break - case 27: // esc - if (typeof callBack == 'function') callBack('No'); - w2popup.close(); - break - } - } - }); - } + width : w2confirm_width, + height : w2confirm_height, + title : title, + modal : true, + showClose : false, + body : '
      ' + msg + '
      ', + buttons : ''+ + '', + onOpen: function (event) { + event.onComplete = function () { + $('#w2ui-popup .w2ui-popup-btn').on('click', function (event) { + w2popup.close(); + if (typeof callBack == 'function') callBack(event.target.id); + }); + } + }, + onKeydown: function (event) { + switch (event.originalEvent.keyCode) { + case 13: // enter + if (typeof callBack == 'function') callBack('Yes'); + w2popup.close(); + break + case 27: // esc + if (typeof callBack == 'function') callBack('No'); + w2popup.close(); + break + } + } + }); + } }; \ No newline at end of file diff --git a/src/w2sidebar.js b/src/w2sidebar.js index faa104897..b98115a70 100644 --- a/src/w2sidebar.js +++ b/src/w2sidebar.js @@ -1,823 +1,823 @@ /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2sidebar - sidebar widget -* - $().w2sidebar - jQuery wrapper -* - Dependencies: jQuery, w2utils +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2sidebar - sidebar widget +* - $().w2sidebar - jQuery wrapper +* - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - return ids of all subitems -* - add find() method to find nodes by a specific criteria (I want all nodes for exampe) -* - dbl click should be like it is in grid (with timer not HTML dbl click event) -* - reorder with grag and drop -* - add route property that would navigate to a #route -* - node.style is missleading - should be there to apply color for example +* - return ids of all subitems +* - add find() method to find nodes by a specific criteria (I want all nodes for exampe) +* - dbl click should be like it is in grid (with timer not HTML dbl click event) +* - reorder with grag and drop +* - add route property that would navigate to a #route +* - node.style is missleading - should be there to apply color for example * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - bug: bixed bug with selection -* - new: find({ params }) - returns all matched nodes -* - change: get() w/o params returns all node ids +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - bug: bixed bug with selection +* - new: find({ params }) - returns all matched nodes +* - change: get() w/o params returns all node ids * ************************************************************************/ (function () { - var w2sidebar = function (options) { - this.name = null; - this.box = null; - this.sidebar = null; - this.parent = null; - this.nodes = []; // Sidebar child nodes - this.menu = []; - this.selected = null; // current selected node (readonly) - this.img = null; - this.icon = null; - this.style = ''; - this.topHTML = ''; - this.bottomHTML = ''; - this.keyboard = true; - this.onClick = null; // Fire when user click on Node Text - this.onDblClick = null; // Fire when user dbl clicks - this.onContextMenu = null; - this.onMenuClick = null; // when context menu item selected - this.onExpand = null; // Fire when node Expands - this.onCollapse = null; // Fire when node Colapses - this.onKeydown = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; - - $.extend(true, this, w2obj.sidebar, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2sidebar = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2sidebar')) return; - // extend items - var nodes = method.nodes; - var object = new w2sidebar(method); - $.extend(object, { handlers: [], nodes: [] }); - if (typeof nodes != 'undefined') { - object.add(object, nodes); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - object.sidebar = object; - // register new object - w2ui[object.name] = object; - return object; - - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2sidebar' ); - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2sidebar.prototype = { - - node: { - id : null, - text : '', - count : null, - img : null, - icon : null, - nodes : [], - style : '', // additional style for subitems - selected : false, - expanded : false, - hidden : false, - disabled : false, - group : false, // if true, it will build as a group - groupShowHide : true, - plus : false, // if true, plus will be shown even if there is no sub nodes - // events - onClick : null, - onDblClick : null, - onContextMenu : null, - onExpand : null, - onCollapse : null, - // internal - parent : null, // node object - sidebar : null - }, - - add: function (parent, nodes) { - if (arguments.length == 1) { - // need to be in reverse order - nodes = arguments[0]; - parent = this; - } - if (typeof parent == 'string') parent = this.get(parent); - return this.insert(parent, null, nodes); - }, - - insert: function (parent, before, nodes) { - var txt, ind, tmp, node, nd; - if (arguments.length == 2) { - // need to be in reverse order - nodes = arguments[1]; - before = arguments[0]; - ind = this.get(before); - if (ind === null) { - if (!$.isArray(nodes)) nodes = [nodes]; - txt = (nodes[0].caption != null ? nodes[0].caption : nodes[0].text); - console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); - return null; - } - parent = this.get(before).parent; - } - if (typeof parent == 'string') parent = this.get(parent); - if (!$.isArray(nodes)) nodes = [nodes]; - for (var o in nodes) { - node = nodes[o]; - if (typeof node.id == null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.'); - continue; - } - if (this.get(this, node.id) !== null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ txt + ') because another node with the same id already exists.'); - continue; - } - tmp = $.extend({}, w2sidebar.prototype.node, node); - tmp.sidebar = this; - tmp.parent = parent; - nd = tmp.nodes || []; - tmp.nodes = []; // very important to re-init empty nodes array - if (before === null) { // append to the end - parent.nodes.push(tmp); - } else { - ind = this.get(parent, before, true); - if (ind === null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); - return null; - } - parent.nodes.splice(ind, 0, tmp); - } - if (nd.length > 0) { - this.insert(tmp, null, nd); - } - } - this.refresh(parent.id); - return tmp; - }, - - remove: function () { // multiple arguments - var deleted = 0; - var tmp; - for (var a = 0; a < arguments.length; a++) { - tmp = this.get(arguments[a]); - if (tmp === null) continue; - if (this.selected !== null && this.selected === tmp.id) { - this.selected = null; - } - var ind = this.get(tmp.parent, arguments[a], true); - if (ind === null) continue; - if (tmp.parent.nodes[ind].selected) tmp.sidebar.unselect(tmp.id); - tmp.parent.nodes.splice(ind, 1); - deleted++; - } - if (deleted > 0 && arguments.length == 1) this.refresh(tmp.parent.id); else this.refresh(); - return deleted; - }, - - set: function (parent, id, node) { - if (arguments.length == 2) { - // need to be in reverse order - node = id; - id = parent; - parent = this; - } - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return null; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].id === id) { - // make sure nodes inserted correctly - var nodes = node.nodes; - $.extend(parent.nodes[i], node, { nodes: [] }); - if (nodes != null) { - this.add(parent.nodes[i], nodes); - } - this.refresh(id); - return true; - } else { - var rv = this.set(parent.nodes[i], id, node); - if (rv) return true; - } - } - return false; - }, - - get: function (parent, id, returnIndex) { // can be just called get(id) or get(id, true) - if (arguments.length === 0) { - var all = []; - var tmp = this.find({}); - for (var t = 0; t < tmp.length; t++) { - if (tmp[t].id != null) all.push(tmp[t].id); - } - return all; - } else { - if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { - // need to be in reverse order - returnIndex = id; - id = parent; - parent = this; - } - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return null; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].id == id) { - if (returnIndex === true) return i; else return parent.nodes[i]; - } else { - var rv = this.get(parent.nodes[i], id, returnIndex); - if (rv || rv === 0) return rv; - } - } - return null; - } - }, - - find: function (parent, params, results) { // can be just called find({ selected: true }) - if (arguments.length == 1) { - // need to be in reverse order - params = parent; - parent = this; - } - if (!results) results = []; - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return results; - for (var i = 0; i < parent.nodes.length; i++) { - var match = true; - for (var prop in params) { - if (parent.nodes[i][prop] != params[prop]) match = false; - } - if (match) results.push(parent.nodes[i]); - if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results); - } - return results; - }, - - hide: function () { // multiple arguments - var hidden = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.hidden = true; - hidden++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return hidden; - }, - - show: function () { // multiple arguments - var shown = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.hidden = false; - shown++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return shown; - }, - - disable: function () { // multiple arguments - var disabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.disabled = true; - if (tmp.selected) this.unselect(tmp.id); - disabled++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return disabled; - }, - - enable: function () { // multiple arguments - var enabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp === null) continue; - tmp.disabled = false; - enabled++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return enabled; - }, - - select: function (id) { - var new_node = this.get(id); - if (!new_node) return false; - if (this.selected == id && new_node.selected) return false; - this.unselect(this.selected); - $(this.box).find('#node_'+ w2utils.escapeId(id)) - .addClass('w2ui-selected') - .find('.w2ui-icon').addClass('w2ui-icon-selected'); - new_node.selected = true; - this.selected = id; - return true; - }, - - unselect: function (id) { - var current = this.get(id); - if (!current) return false; - current.selected = false; - $(this.box).find('#node_'+ w2utils.escapeId(id)) - .removeClass('w2ui-selected') - .find('.w2ui-icon').removeClass('w2ui-icon-selected'); - if (this.selected == id) this.selected = null; - return true; - }, - - toggle: function(id) { - var nd = this.get(id); - if (nd === null) return false; - if (nd.plus) { - this.set(id, { plus: false }); - this.expand(id); - this.refresh(id); - return; - } - if (nd.nodes.length === 0) return false; - if (this.get(id).expanded) return this.collapse(id); else return this.expand(id); - }, - - collapse: function (id) { - var obj = this; - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'collapse', target: id, object: nd }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideUp(200); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      +
      '); - nd.expanded = false; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - setTimeout(function () { obj.refresh(id); }, 200); - return true; - }, - - collapseAll: function (parent) { - if (typeof parent == 'undefined') parent = this; - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return false; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false; - if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); - } - this.refresh(parent.id); - return true; - }, - - expand: function (id) { - var obj = this; - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'expand', target: id, object: nd }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideDown(200); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      -
      '); - nd.expanded = true; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - setTimeout(function () { obj.refresh(id); }, 200); - return true; - }, - - expandAll: function (parent) { - if (typeof parent == 'undefined') parent = this; - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return false; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true; - if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); - } - this.refresh(parent.id); - }, - - expandParents: function (id) { - var node = this.get(id); - if (node === null) return false; - if (node.parent) { - node.parent.expanded = true; - this.expandParents(node.parent.id); - } - this.refresh(id); - return true; - }, - - click: function (id, event) { - var obj = this; - var nd = this.get(id); - if (nd === null) return; - if (nd.disabled || nd.group) return; // should click event if already selected - // unselect all previsously - $(obj.box).find('.w2ui-node.w2ui-selected').each(function (index, el) { - var oldID = $(el).attr('id').replace('node_', ''); - var oldNode = obj.get(oldID); - if (oldNode != null) oldNode.selected = false; - $(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - }); - // select new one - var newNode = $(obj.box).find('#node_'+ w2utils.escapeId(id)); - var oldNode = $(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)); - newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); - // need timeout to allow rendering - setTimeout(function () { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, node: nd, object: nd }); - if (eventData.isCancelled === true) { - // restore selection - newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); - return; - } - // default action - if (oldNode !== null) oldNode.selected = false; - obj.get(id).selected = true; - obj.selected = id; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 1); - }, - - keydown: function (event) { - var obj = this; - var nd = obj.get(obj.selected); - if (!nd || obj.keyboard !== true) return; - // trigger event - var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default behaviour - if (event.keyCode == 13 || event.keyCode == 32) { // enter or space - if (nd.nodes.length > 0) obj.toggle(obj.selected); - } - if (event.keyCode == 37) { // left - if (nd.nodes.length > 0 && nd.expanded) { - obj.collapse(obj.selected); - } else { - selectNode(nd.parent); - if (!nd.parent.group) obj.collapse(nd.parent.id); - } - } - if (event.keyCode == 39) { // right - if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected); - } - if (event.keyCode == 38) { // up - selectNode(neighbor(nd, prev)); - } - if (event.keyCode == 40) { // down - selectNode(neighbor(nd, next)); - } - // cancel event if needed - if ($.inArray(event.keyCode, [13, 32, 37, 38, 39, 40]) != -1) { - if (event.preventDefault) event.preventDefault(); - if (event.stopPropagation) event.stopPropagation(); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - - function selectNode (node, event) { - if (node !== null && !node.hidden && !node.disabled && !node.group) { - obj.click(node.id, event); - setTimeout(function () { obj.scrollIntoView(); }, 50); - } - } - - function neighbor (node, neighborFunc) { - node = neighborFunc(node); - while (node !== null && (node.hidden || node.disabled)) { - if (node.group) break; else node = neighborFunc(node); - } - return node; - } - - function next (node, noSubs) { - if (node === null) return null; - var parent = node.parent; - var ind = obj.get(node.id, true); - var nextNode = null; - // jump inside - if (node.expanded && node.nodes.length > 0 && noSubs !== true) { - var t = node.nodes[0]; - if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t; - } else { - if (parent && ind + 1 < parent.nodes.length) { - nextNode = parent.nodes[ind + 1]; - } else { - nextNode = next(parent, true); // jump to the parent - } - } - if (nextNode !== null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode); - return nextNode; - } - - function prev (node) { - if (node === null) return null; - var parent = node.parent; - var ind = obj.get(node.id, true); - var prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent; - if (prevNode !== null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode); - return prevNode; - } - - function lastChild (node) { - if (node.expanded && node.nodes.length > 0) { - var t = node.nodes[node.nodes.length - 1]; - if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t); - } - return node; - } - }, - - scrollIntoView: function (id) { - if (typeof id == 'undefined') id = this.selected; - var nd = this.get(id); - if (nd === null) return; - var body = $(this.box).find('.w2ui-sidebar-div'); - var item = $(this.box).find('#node_'+ w2utils.escapeId(id)); - var offset = item.offset().top - body.offset().top; - if (offset + item.height() > body.height()) { - body.animate({ 'scrollTop': body.scrollTop() + body.height() / 1.3 }, 250, 'linear'); - } - if (offset <= 0) { - body.animate({ 'scrollTop': body.scrollTop() - body.height() / 1.3 }, 250, 'linear'); - } - }, - - dblClick: function (id, event) { - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: nd }); - if (eventData.isCancelled === true) return; - // default action - this.toggle(id); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - contextMenu: function (id, event) { - var obj = this; - var nd = obj.get(id); - if (id != obj.selected) obj.click(id); - // need timeout to allow click to finish first - setTimeout(function () { - // event before - var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: nd }); - if (eventData.isCancelled === true) return; - // default action - if (nd.group || nd.disabled) return; - if (obj.menu.length > 0) { - $(obj.box).find('#node_'+ w2utils.escapeId(id)) - .w2menu(obj.menu, { - left : (event ? event.offsetX || event.pageX : 50) - 25, - onSelect: function (event) { - obj.menuClick(id, parseInt(event.index), event.originalEvent); - } - } - ); - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 150); // need timer 150 for FF - }, - - menuClick: function (itemId, index, event) { - var obj = this; - // event before - var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: obj.menu[index] }); - if (eventData.isCancelled === true) return; - // default action - // -- empty - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return; - // default action - if (typeof box != 'undefined' && box !== null) { - if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-sidebar') - .html(''); - } - this.box = box; - } - if (!this.box) return; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-sidebar') - .html('
      '+ - '
      ' + - '
      '+ - '
      '+ - '
      ' - ); - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height: $(this.box).height() + 'px' - }); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // adjust top and bottom - if (this.topHTML !== '') { - $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); - } - if (this.bottomHTML !== '') { - $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - // --- - this.refresh(); - return (new Date()).getTime() - time; - }, - - refresh: function (id) { - var time = (new Date()).getTime(); - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // event before - var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id != 'undefined' ? id : this.name) }); - if (eventData.isCancelled === true) return; - // adjust top and bottom - if (this.topHTML !== '') { - $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); - } - if (this.bottomHTML !== '') { - $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); - } - // default action - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height: $(this.box).height() + 'px' - }); - var obj = this; - var node, nd; - var nm; - if (typeof id == 'undefined') { - node = this; - nm = '.w2ui-sidebar-div'; - } else { - node = this.get(id); - if (node === null) return; - nm = '#node_'+ w2utils.escapeId(node.id) + '_sub'; - } - var nodeHTML; - if (node !== this) { - var tmp = '#node_'+ w2utils.escapeId(node.id); - nodeHTML = getNodeHTML(node); - $(this.box).find(tmp).before(''); - $(this.box).find(tmp).remove(); - $(this.box).find(nm).remove(); - $('#sidebar_'+ this.name + '_tmp').before(nodeHTML); - $('#sidebar_'+ this.name + '_tmp').remove(); - } - // refresh sub nodes - $(this.box).find(nm).html(''); - for (var i = 0; i < node.nodes.length; i++) { - nd = node.nodes[i]; - nodeHTML = getNodeHTML(nd); - $(this.box).find(nm).append(nodeHTML); - if (nd.nodes.length !== 0) { this.refresh(nd.id); } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - - function getNodeHTML(nd) { - var html = ''; - var img = nd.img; - if (img === null) img = this.img; - var icon = nd.icon; - if (icon === null) icon = this.icon; - // -- find out level - var tmp = nd.parent; - var level = 0; - while (tmp && tmp.parent !== null) { - if (tmp.group) level--; - tmp = tmp.parent; - level++; - } - if (typeof nd.caption != 'undefined') nd.text = nd.caption; - if (nd.group) { - html = - '
      '+ - (nd.groupShowHide ? ''+ (!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')) +'' : '') + - ' '+ nd.text +''+ - '
      '+ - '
      '; - } else { - if (nd.selected && !nd.disabled) obj.selected = nd.id; - tmp = ''; - if (img) tmp = '
      '; - if (icon) tmp = '
      '; - html = - '
      '+ - ''+ - ''+ - ''+ - '
      '+ - '
      ' + (nd.nodes.length > 0 ? (nd.expanded ? '-' : '+') : (nd.plus ? '+' : '')) + '
      ' + - '
      '+ - tmp + - (nd.count || nd.count === 0 ? '
      '+ nd.count +'
      ' : '') + - '
      '+ nd.text +'
      '+ - '
      '+ - '
      '+ - '
      '; - } - return html; - } - }, - - resize: function () { - var time = (new Date()).getTime(); - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).css('overflow', 'hidden'); // container should have no overflow - //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'hidden'); - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height : $(this.box).height() + 'px' - }); - //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'auto'); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - // clean up - if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-sidebar') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - lock: function (msg, showSpinner) { - var box = $(this.box).find('> div:first-child'); - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(box); - w2utils.lock.apply(window, args); - }, - - unlock: function () { - w2utils.unlock(this.box); - } - }; - - $.extend(w2sidebar.prototype, w2utils.event); - w2obj.sidebar = w2sidebar; + var w2sidebar = function (options) { + this.name = null; + this.box = null; + this.sidebar = null; + this.parent = null; + this.nodes = []; // Sidebar child nodes + this.menu = []; + this.selected = null; // current selected node (readonly) + this.img = null; + this.icon = null; + this.style = ''; + this.topHTML = ''; + this.bottomHTML = ''; + this.keyboard = true; + this.onClick = null; // Fire when user click on Node Text + this.onDblClick = null; // Fire when user dbl clicks + this.onContextMenu = null; + this.onMenuClick = null; // when context menu item selected + this.onExpand = null; // Fire when node Expands + this.onCollapse = null; // Fire when node Colapses + this.onKeydown = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; + + $.extend(true, this, w2obj.sidebar, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2sidebar = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2sidebar')) return; + // extend items + var nodes = method.nodes; + var object = new w2sidebar(method); + $.extend(object, { handlers: [], nodes: [] }); + if (typeof nodes != 'undefined') { + object.add(object, nodes); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + object.sidebar = object; + // register new object + w2ui[object.name] = object; + return object; + + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2sidebar' ); + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2sidebar.prototype = { + + node: { + id : null, + text : '', + count : null, + img : null, + icon : null, + nodes : [], + style : '', // additional style for subitems + selected : false, + expanded : false, + hidden : false, + disabled : false, + group : false, // if true, it will build as a group + groupShowHide : true, + plus : false, // if true, plus will be shown even if there is no sub nodes + // events + onClick : null, + onDblClick : null, + onContextMenu : null, + onExpand : null, + onCollapse : null, + // internal + parent : null, // node object + sidebar : null + }, + + add: function (parent, nodes) { + if (arguments.length == 1) { + // need to be in reverse order + nodes = arguments[0]; + parent = this; + } + if (typeof parent == 'string') parent = this.get(parent); + return this.insert(parent, null, nodes); + }, + + insert: function (parent, before, nodes) { + var txt, ind, tmp, node, nd; + if (arguments.length == 2) { + // need to be in reverse order + nodes = arguments[1]; + before = arguments[0]; + ind = this.get(before); + if (ind === null) { + if (!$.isArray(nodes)) nodes = [nodes]; + txt = (nodes[0].caption != null ? nodes[0].caption : nodes[0].text); + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); + return null; + } + parent = this.get(before).parent; + } + if (typeof parent == 'string') parent = this.get(parent); + if (!$.isArray(nodes)) nodes = [nodes]; + for (var o in nodes) { + node = nodes[o]; + if (typeof node.id == null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.'); + continue; + } + if (this.get(this, node.id) !== null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ txt + ') because another node with the same id already exists.'); + continue; + } + tmp = $.extend({}, w2sidebar.prototype.node, node); + tmp.sidebar = this; + tmp.parent = parent; + nd = tmp.nodes || []; + tmp.nodes = []; // very important to re-init empty nodes array + if (before === null) { // append to the end + parent.nodes.push(tmp); + } else { + ind = this.get(parent, before, true); + if (ind === null) { + txt = (node.caption != null ? node.caption : node.text); + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); + return null; + } + parent.nodes.splice(ind, 0, tmp); + } + if (nd.length > 0) { + this.insert(tmp, null, nd); + } + } + this.refresh(parent.id); + return tmp; + }, + + remove: function () { // multiple arguments + var deleted = 0; + var tmp; + for (var a = 0; a < arguments.length; a++) { + tmp = this.get(arguments[a]); + if (tmp === null) continue; + if (this.selected !== null && this.selected === tmp.id) { + this.selected = null; + } + var ind = this.get(tmp.parent, arguments[a], true); + if (ind === null) continue; + if (tmp.parent.nodes[ind].selected) tmp.sidebar.unselect(tmp.id); + tmp.parent.nodes.splice(ind, 1); + deleted++; + } + if (deleted > 0 && arguments.length == 1) this.refresh(tmp.parent.id); else this.refresh(); + return deleted; + }, + + set: function (parent, id, node) { + if (arguments.length == 2) { + // need to be in reverse order + node = id; + id = parent; + parent = this; + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return null; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id === id) { + // make sure nodes inserted correctly + var nodes = node.nodes; + $.extend(parent.nodes[i], node, { nodes: [] }); + if (nodes != null) { + this.add(parent.nodes[i], nodes); + } + this.refresh(id); + return true; + } else { + var rv = this.set(parent.nodes[i], id, node); + if (rv) return true; + } + } + return false; + }, + + get: function (parent, id, returnIndex) { // can be just called get(id) or get(id, true) + if (arguments.length === 0) { + var all = []; + var tmp = this.find({}); + for (var t = 0; t < tmp.length; t++) { + if (tmp[t].id != null) all.push(tmp[t].id); + } + return all; + } else { + if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { + // need to be in reverse order + returnIndex = id; + id = parent; + parent = this; + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return null; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id == id) { + if (returnIndex === true) return i; else return parent.nodes[i]; + } else { + var rv = this.get(parent.nodes[i], id, returnIndex); + if (rv || rv === 0) return rv; + } + } + return null; + } + }, + + find: function (parent, params, results) { // can be just called find({ selected: true }) + if (arguments.length == 1) { + // need to be in reverse order + params = parent; + parent = this; + } + if (!results) results = []; + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return results; + for (var i = 0; i < parent.nodes.length; i++) { + var match = true; + for (var prop in params) { + if (parent.nodes[i][prop] != params[prop]) match = false; + } + if (match) results.push(parent.nodes[i]); + if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results); + } + return results; + }, + + hide: function () { // multiple arguments + var hidden = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.hidden = true; + hidden++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return hidden; + }, + + show: function () { // multiple arguments + var shown = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.hidden = false; + shown++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return shown; + }, + + disable: function () { // multiple arguments + var disabled = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.disabled = true; + if (tmp.selected) this.unselect(tmp.id); + disabled++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return disabled; + }, + + enable: function () { // multiple arguments + var enabled = 0; + for (var a = 0; a < arguments.length; a++) { + var tmp = this.get(arguments[a]); + if (tmp === null) continue; + tmp.disabled = false; + enabled++; + } + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); + return enabled; + }, + + select: function (id) { + var new_node = this.get(id); + if (!new_node) return false; + if (this.selected == id && new_node.selected) return false; + this.unselect(this.selected); + $(this.box).find('#node_'+ w2utils.escapeId(id)) + .addClass('w2ui-selected') + .find('.w2ui-icon').addClass('w2ui-icon-selected'); + new_node.selected = true; + this.selected = id; + return true; + }, + + unselect: function (id) { + var current = this.get(id); + if (!current) return false; + current.selected = false; + $(this.box).find('#node_'+ w2utils.escapeId(id)) + .removeClass('w2ui-selected') + .find('.w2ui-icon').removeClass('w2ui-icon-selected'); + if (this.selected == id) this.selected = null; + return true; + }, + + toggle: function(id) { + var nd = this.get(id); + if (nd === null) return false; + if (nd.plus) { + this.set(id, { plus: false }); + this.expand(id); + this.refresh(id); + return; + } + if (nd.nodes.length === 0) return false; + if (this.get(id).expanded) return this.collapse(id); else return this.expand(id); + }, + + collapse: function (id) { + var obj = this; + var nd = this.get(id); + // event before + var eventData = this.trigger({ phase: 'before', type: 'collapse', target: id, object: nd }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideUp(200); + $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      +
      '); + nd.expanded = false; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + setTimeout(function () { obj.refresh(id); }, 200); + return true; + }, + + collapseAll: function (parent) { + if (typeof parent == 'undefined') parent = this; + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return false; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false; + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); + } + this.refresh(parent.id); + return true; + }, + + expand: function (id) { + var obj = this; + var nd = this.get(id); + // event before + var eventData = this.trigger({ phase: 'before', type: 'expand', target: id, object: nd }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideDown(200); + $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
      -
      '); + nd.expanded = true; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + setTimeout(function () { obj.refresh(id); }, 200); + return true; + }, + + expandAll: function (parent) { + if (typeof parent == 'undefined') parent = this; + if (typeof parent == 'string') parent = this.get(parent); + if (parent.nodes == null) return false; + for (var i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true; + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); + } + this.refresh(parent.id); + }, + + expandParents: function (id) { + var node = this.get(id); + if (node === null) return false; + if (node.parent) { + node.parent.expanded = true; + this.expandParents(node.parent.id); + } + this.refresh(id); + return true; + }, + + click: function (id, event) { + var obj = this; + var nd = this.get(id); + if (nd === null) return; + if (nd.disabled || nd.group) return; // should click event if already selected + // unselect all previsously + $(obj.box).find('.w2ui-node.w2ui-selected').each(function (index, el) { + var oldID = $(el).attr('id').replace('node_', ''); + var oldNode = obj.get(oldID); + if (oldNode != null) oldNode.selected = false; + $(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); + }); + // select new one + var newNode = $(obj.box).find('#node_'+ w2utils.escapeId(id)); + var oldNode = $(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)); + newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); + // need timeout to allow rendering + setTimeout(function () { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, node: nd, object: nd }); + if (eventData.isCancelled === true) { + // restore selection + newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); + oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); + return; + } + // default action + if (oldNode !== null) oldNode.selected = false; + obj.get(id).selected = true; + obj.selected = id; + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 1); + }, + + keydown: function (event) { + var obj = this; + var nd = obj.get(obj.selected); + if (!nd || obj.keyboard !== true) return; + // trigger event + var eventData = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default behaviour + if (event.keyCode == 13 || event.keyCode == 32) { // enter or space + if (nd.nodes.length > 0) obj.toggle(obj.selected); + } + if (event.keyCode == 37) { // left + if (nd.nodes.length > 0 && nd.expanded) { + obj.collapse(obj.selected); + } else { + selectNode(nd.parent); + if (!nd.parent.group) obj.collapse(nd.parent.id); + } + } + if (event.keyCode == 39) { // right + if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected); + } + if (event.keyCode == 38) { // up + selectNode(neighbor(nd, prev)); + } + if (event.keyCode == 40) { // down + selectNode(neighbor(nd, next)); + } + // cancel event if needed + if ($.inArray(event.keyCode, [13, 32, 37, 38, 39, 40]) != -1) { + if (event.preventDefault) event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + + function selectNode (node, event) { + if (node !== null && !node.hidden && !node.disabled && !node.group) { + obj.click(node.id, event); + setTimeout(function () { obj.scrollIntoView(); }, 50); + } + } + + function neighbor (node, neighborFunc) { + node = neighborFunc(node); + while (node !== null && (node.hidden || node.disabled)) { + if (node.group) break; else node = neighborFunc(node); + } + return node; + } + + function next (node, noSubs) { + if (node === null) return null; + var parent = node.parent; + var ind = obj.get(node.id, true); + var nextNode = null; + // jump inside + if (node.expanded && node.nodes.length > 0 && noSubs !== true) { + var t = node.nodes[0]; + if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t; + } else { + if (parent && ind + 1 < parent.nodes.length) { + nextNode = parent.nodes[ind + 1]; + } else { + nextNode = next(parent, true); // jump to the parent + } + } + if (nextNode !== null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode); + return nextNode; + } + + function prev (node) { + if (node === null) return null; + var parent = node.parent; + var ind = obj.get(node.id, true); + var prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent; + if (prevNode !== null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode); + return prevNode; + } + + function lastChild (node) { + if (node.expanded && node.nodes.length > 0) { + var t = node.nodes[node.nodes.length - 1]; + if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t); + } + return node; + } + }, + + scrollIntoView: function (id) { + if (typeof id == 'undefined') id = this.selected; + var nd = this.get(id); + if (nd === null) return; + var body = $(this.box).find('.w2ui-sidebar-div'); + var item = $(this.box).find('#node_'+ w2utils.escapeId(id)); + var offset = item.offset().top - body.offset().top; + if (offset + item.height() > body.height()) { + body.animate({ 'scrollTop': body.scrollTop() + body.height() / 1.3 }, 250, 'linear'); + } + if (offset <= 0) { + body.animate({ 'scrollTop': body.scrollTop() - body.height() / 1.3 }, 250, 'linear'); + } + }, + + dblClick: function (id, event) { + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + var nd = this.get(id); + // event before + var eventData = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: nd }); + if (eventData.isCancelled === true) return; + // default action + this.toggle(id); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + contextMenu: function (id, event) { + var obj = this; + var nd = obj.get(id); + if (id != obj.selected) obj.click(id); + // need timeout to allow click to finish first + setTimeout(function () { + // event before + var eventData = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: nd }); + if (eventData.isCancelled === true) return; + // default action + if (nd.group || nd.disabled) return; + if (obj.menu.length > 0) { + $(obj.box).find('#node_'+ w2utils.escapeId(id)) + .w2menu(obj.menu, { + left : (event ? event.offsetX || event.pageX : 50) - 25, + onSelect: function (event) { + obj.menuClick(id, parseInt(event.index), event.originalEvent); + } + } + ); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 150); // need timer 150 for FF + }, + + menuClick: function (itemId, index, event) { + var obj = this; + // event before + var eventData = obj.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: obj.menu[index] }); + if (eventData.isCancelled === true) return; + // default action + // -- empty + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (eventData.isCancelled === true) return; + // default action + if (typeof box != 'undefined' && box !== null) { + if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html(''); + } + this.box = box; + } + if (!this.box) return; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-sidebar') + .html('
      '+ + '
      ' + + '
      '+ + '
      '+ + '
      ' + ); + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height: $(this.box).height() + 'px' + }); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // adjust top and bottom + if (this.topHTML !== '') { + $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); + } + if (this.bottomHTML !== '') { + $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + // --- + this.refresh(); + return (new Date()).getTime() - time; + }, + + refresh: function (id) { + var time = (new Date()).getTime(); + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id != 'undefined' ? id : this.name) }); + if (eventData.isCancelled === true) return; + // adjust top and bottom + if (this.topHTML !== '') { + $(this.box).find('.w2ui-sidebar-top').html(this.topHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); + } + if (this.bottomHTML !== '') { + $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); + $(this.box).find('.w2ui-sidebar-div') + .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); + } + // default action + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height: $(this.box).height() + 'px' + }); + var obj = this; + var node, nd; + var nm; + if (typeof id == 'undefined') { + node = this; + nm = '.w2ui-sidebar-div'; + } else { + node = this.get(id); + if (node === null) return; + nm = '#node_'+ w2utils.escapeId(node.id) + '_sub'; + } + var nodeHTML; + if (node !== this) { + var tmp = '#node_'+ w2utils.escapeId(node.id); + nodeHTML = getNodeHTML(node); + $(this.box).find(tmp).before(''); + $(this.box).find(tmp).remove(); + $(this.box).find(nm).remove(); + $('#sidebar_'+ this.name + '_tmp').before(nodeHTML); + $('#sidebar_'+ this.name + '_tmp').remove(); + } + // refresh sub nodes + $(this.box).find(nm).html(''); + for (var i = 0; i < node.nodes.length; i++) { + nd = node.nodes[i]; + nodeHTML = getNodeHTML(nd); + $(this.box).find(nm).append(nodeHTML); + if (nd.nodes.length !== 0) { this.refresh(nd.id); } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + + function getNodeHTML(nd) { + var html = ''; + var img = nd.img; + if (img === null) img = this.img; + var icon = nd.icon; + if (icon === null) icon = this.icon; + // -- find out level + var tmp = nd.parent; + var level = 0; + while (tmp && tmp.parent !== null) { + if (tmp.group) level--; + tmp = tmp.parent; + level++; + } + if (typeof nd.caption != 'undefined') nd.text = nd.caption; + if (nd.group) { + html = + '
      '+ + (nd.groupShowHide ? ''+ (!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')) +'' : '') + + ' '+ nd.text +''+ + '
      '+ + '
      '; + } else { + if (nd.selected && !nd.disabled) obj.selected = nd.id; + tmp = ''; + if (img) tmp = '
      '; + if (icon) tmp = '
      '; + html = + '
      '+ + ''+ + ''+ + ''+ + '
      '+ + '
      ' + (nd.nodes.length > 0 ? (nd.expanded ? '-' : '+') : (nd.plus ? '+' : '')) + '
      ' + + '
      '+ + tmp + + (nd.count || nd.count === 0 ? '
      '+ nd.count +'
      ' : '') + + '
      '+ nd.text +'
      '+ + '
      '+ + '
      '+ + '
      '; + } + return html; + } + }, + + resize: function () { + var time = (new Date()).getTime(); + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).css('overflow', 'hidden'); // container should have no overflow + //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'hidden'); + $(this.box).find('> div').css({ + width : $(this.box).width() + 'px', + height : $(this.box).height() + 'px' + }); + //$(this.box).find('.w2ui-sidebar-div').css('overflow', 'auto'); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + // clean up + if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + lock: function (msg, showSpinner) { + var box = $(this.box).find('> div:first-child'); + var args = Array.prototype.slice.call(arguments, 0); + args.unshift(box); + w2utils.lock.apply(window, args); + }, + + unlock: function () { + w2utils.unlock(this.box); + } + }; + + $.extend(w2sidebar.prototype, w2utils.event); + w2obj.sidebar = w2sidebar; })(); diff --git a/src/w2tabs.js b/src/w2tabs.js index 930e42a37..e5f011f27 100644 --- a/src/w2tabs.js +++ b/src/w2tabs.js @@ -1,416 +1,416 @@ /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2tabs - tabs widget -* - $().w2tabs - jQuery wrapper +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2tabs - tabs widget +* - $().w2tabs - jQuery wrapper * - Dependencies: jQuery, w2utils * * == NICE TO HAVE == * - on overflow display << >> * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - individual tab onClick (possibly other events) are not working +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - individual tab onClick (possibly other events) are not working * ************************************************************************/ (function () { - var w2tabs = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.active = null; - this.tabs = []; - this.right = ''; - this.style = ''; - this.onClick = null; - this.onClose = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; + var w2tabs = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.active = null; + this.tabs = []; + this.right = ''; + this.style = ''; + this.onClick = null; + this.onClose = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; - $.extend(this, { handlers: [] }); - $.extend(true, this, w2obj.tabs, options); - }; + $.extend(this, { handlers: [] }); + $.extend(true, this, w2obj.tabs, options); + }; - // ==================================================== - // -- Registers as a jQuery plugin + // ==================================================== + // -- Registers as a jQuery plugin - $.fn.w2tabs = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2tabs')) return; - // extend tabs - var tabs = method.tabs || []; - var object = new w2tabs(method); - for (var i = 0; i < tabs.length; i++) { - object.tabs[i] = $.extend({}, w2tabs.prototype.tab, tabs[i]); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - // register new object - w2ui[object.name] = object; - return object; - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2tabs' ); - return undefined; - } - }; + $.fn.w2tabs = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2tabs')) return; + // extend tabs + var tabs = method.tabs || []; + var object = new w2tabs(method); + for (var i = 0; i < tabs.length; i++) { + object.tabs[i] = $.extend({}, w2tabs.prototype.tab, tabs[i]); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + return object; + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2tabs' ); + return undefined; + } + }; - // ==================================================== - // -- Implementation of core functionality + // ==================================================== + // -- Implementation of core functionality - w2tabs.prototype = { - tab : { - id : null, // command to be sent to all event handlers - text : '', - hidden : false, - disabled : false, - closable : false, - hint : '', - onClick : null, - onRefresh : null, - onClose : null - }, + w2tabs.prototype = { + tab : { + id : null, // command to be sent to all event handlers + text : '', + hidden : false, + disabled : false, + closable : false, + hint : '', + onClick : null, + onRefresh : null, + onClose : null + }, - add: function (tab) { - return this.insert(null, tab); - }, + add: function (tab) { + return this.insert(null, tab); + }, - insert: function (id, tab) { - if (!$.isArray(tab)) tab = [tab]; - // assume it is array - for (var i = 0; i < tab.length; i++) { - // checks - if (typeof tab[i].id === 'undefined') { - console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); - return; - } - if (!w2utils.checkUniqueId(tab[i].id, this.tabs, 'tabs', this.name)) return; - // add tab - var newTab = $.extend({}, w2tabs.prototype.tab, tab[i]); - if (id === null || typeof id === 'undefined') { - this.tabs.push(newTab); - } else { - var middle = this.get(id, true); - this.tabs = this.tabs.slice(0, middle).concat([newTab], this.tabs.slice(middle)); - } - this.refresh(tab[i].id); - } - }, + insert: function (id, tab) { + if (!$.isArray(tab)) tab = [tab]; + // assume it is array + for (var i = 0; i < tab.length; i++) { + // checks + if (typeof tab[i].id === 'undefined') { + console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); + return; + } + if (!w2utils.checkUniqueId(tab[i].id, this.tabs, 'tabs', this.name)) return; + // add tab + var newTab = $.extend({}, w2tabs.prototype.tab, tab[i]); + if (id === null || typeof id === 'undefined') { + this.tabs.push(newTab); + } else { + var middle = this.get(id, true); + this.tabs = this.tabs.slice(0, middle).concat([newTab], this.tabs.slice(middle)); + } + this.refresh(tab[i].id); + } + }, - remove: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab) return false; - removed++; - // remove from array - this.tabs.splice(this.get(tab.id, true), 1); - // remove from screen - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).remove(); - } - return removed; - }, + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab) return false; + removed++; + // remove from array + this.tabs.splice(this.get(tab.id, true), 1); + // remove from screen + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).remove(); + } + return removed; + }, - select: function (id) { - if (this.active == id || this.get(id) === null) return false; - this.active = id; - this.refresh(); - return true; - }, + select: function (id) { + if (this.active == id || this.get(id) === null) return false; + this.active = id; + this.refresh(); + return true; + }, - set: function (id, tab) { - var index = this.get(id, true); - if (index === null) return false; - $.extend(this.tabs[index], tab); - this.refresh(id); - return true; - }, + set: function (id, tab) { + var index = this.get(id, true); + if (index === null) return false; + $.extend(this.tabs[index], tab); + this.refresh(id); + return true; + }, - get: function (id, returnIndex) { - if (arguments.length === 0) { - var all = []; - for (var i1 = 0; i1 < this.tabs.length; i1++) { - if (this.tabs[i1].id != null) { - all.push(this.tabs[i1].id); - } - } - return all; - } else { - for (var i2 = 0; i2 < this.tabs.length; i2++) { - if (this.tabs[i2].id == id) { // need to be == since id can be numeric - return (returnIndex === true ? i2 : this.tabs[i2]); - } - } - } - return null; - }, + get: function (id, returnIndex) { + if (arguments.length === 0) { + var all = []; + for (var i1 = 0; i1 < this.tabs.length; i1++) { + if (this.tabs[i1].id != null) { + all.push(this.tabs[i1].id); + } + } + return all; + } else { + for (var i2 = 0; i2 < this.tabs.length; i2++) { + if (this.tabs[i2].id == id) { // need to be == since id can be numeric + return (returnIndex === true ? i2 : this.tabs[i2]); + } + } + } + return null; + }, - show: function () { - var obj = this; - var shown = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.hidden === false) continue; - shown++; - tab.hidden = false; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return shown; - }, + show: function () { + var obj = this; + var shown = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.hidden === false) continue; + shown++; + tab.hidden = false; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return shown; + }, - hide: function () { - var obj = this; - var hidden= 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.hidden === true) continue; - hidden++; - tab.hidden = true; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return hidden; - }, + hide: function () { + var obj = this; + var hidden= 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.hidden === true) continue; + hidden++; + tab.hidden = true; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return hidden; + }, - enable: function () { - var obj = this; - var enabled = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.disabled === false) continue; - enabled++; - tab.disabled = false; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return enabled; - }, + enable: function () { + var obj = this; + var enabled = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.disabled === false) continue; + enabled++; + tab.disabled = false; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return enabled; + }, - disable: function () { - var obj = this; - var disabled = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.disabled === true) continue; - disabled++; - tab.disabled = true; - tmp.push(tab.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return disabled; - }, + disable: function () { + var obj = this; + var disabled = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var tab = this.get(arguments[a]); + if (!tab || tab.disabled === true) continue; + disabled++; + tab.disabled = true; + tmp.push(tab.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return disabled; + }, - refresh: function (id) { - var time = (new Date()).getTime(); - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - // event before - var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), object: this.get(id) }); - if (eventData.isCancelled === true) return; - if (typeof id === 'undefined') { - // refresh all - for (var i = 0; i < this.tabs.length; i++) this.refresh(this.tabs[i].id); - } else { - // create or refresh only one item - var tab = this.get(id); - if (tab === null) return false; - if (typeof tab.caption !== 'undefined') tab.text = tab.caption; + refresh: function (id) { + var time = (new Date()).getTime(); + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), object: this.get(id) }); + if (eventData.isCancelled === true) return; + if (typeof id === 'undefined') { + // refresh all + for (var i = 0; i < this.tabs.length; i++) this.refresh(this.tabs[i].id); + } else { + // create or refresh only one item + var tab = this.get(id); + if (tab === null) return false; + if (typeof tab.caption !== 'undefined') tab.text = tab.caption; - var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); - var tabHTML = (tab.closable ? '
      ' : '') + - '
      ' + tab.text + '
      '; - if (jq_el.length === 0) { - // does not exist - create it - var addStyle = ''; - if (tab.hidden) { addStyle += 'display: none;'; } - if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } - var html = ''+ tabHTML + ''; - if (this.get(id, true) !== this.tabs.length-1 && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).length > 0) { - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).before(html); - } else { - $(this.box).find('#tabs_'+ this.name +'_right').before(html); - } - } else { - // refresh - jq_el.html(tabHTML); - if (tab.hidden) { jq_el.css('display', 'none'); } - else { jq_el.css('display', ''); } - if (tab.disabled) { jq_el.css({ 'opacity': '0.2', '-moz-opacity': '0.2', '-webkit-opacity': '0.2', '-o-opacity': '0.2', 'filter': 'alpha(opacity=20)' }); } - else { jq_el.css({ 'opacity': '1', '-moz-opacity': '1', '-webkit-opacity': '1', '-o-opacity': '1', 'filter': 'alpha(opacity=100)' }); } - } - } - // right html - $('#tabs_'+ this.name +'_right').html(this.right); - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, + var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); + var tabHTML = (tab.closable ? '
      ' : '') + + '
      ' + tab.text + '
      '; + if (jq_el.length === 0) { + // does not exist - create it + var addStyle = ''; + if (tab.hidden) { addStyle += 'display: none;'; } + if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } + var html = ''+ tabHTML + ''; + if (this.get(id, true) !== this.tabs.length-1 && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).length > 0) { + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).before(html); + } else { + $(this.box).find('#tabs_'+ this.name +'_right').before(html); + } + } else { + // refresh + jq_el.html(tabHTML); + if (tab.hidden) { jq_el.css('display', 'none'); } + else { jq_el.css('display', ''); } + if (tab.disabled) { jq_el.css({ 'opacity': '0.2', '-moz-opacity': '0.2', '-webkit-opacity': '0.2', '-o-opacity': '0.2', 'filter': 'alpha(opacity=20)' }); } + else { jq_el.css({ 'opacity': '1', '-moz-opacity': '1', '-webkit-opacity': '1', '-o-opacity': '1', 'filter': 'alpha(opacity=100)' }); } + } + } + // right html + $('#tabs_'+ this.name +'_right').html(this.right); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, - render: function (box) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return; - // default action - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (typeof box !== 'undefined' && box !== null) { - if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-tabs') - .html(''); - } - this.box = box; - } - if (!this.box) return false; - // render all buttons - var html = ''+ - ' '+ - '
      '+ this.right +'
      '; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-tabs') - .html(html); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(); - return (new Date()).getTime() - time; - }, + render: function (box) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (eventData.isCancelled === true) return; + // default action + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (typeof box !== 'undefined' && box !== null) { + if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html(''); + } + this.box = box; + } + if (!this.box) return false; + // render all buttons + var html = ''+ + ' '+ + '
      '+ this.right +'
      '; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-tabs') + .html(html); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(); + return (new Date()).getTime() - time; + }, - resize: function () { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; + resize: function () { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; - // intentionaly blank + // intentionaly blank - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - // clean up - if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-tabs') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + // clean up + if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html(''); + } + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, - // =================================================== - // -- Internal Event Handlers + // =================================================== + // -- Internal Event Handlers - click: function (id, event) { - var tab = this.get(id); - if (tab === null || tab.disabled) return false; - // event before - var eventData = this.trigger({ phase: 'before', type: 'click', target: id, tab: tab, object: tab, originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active) +' .w2ui-tab').removeClass('active'); - this.active = tab.id; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(id); - }, + click: function (id, event) { + var tab = this.get(id); + if (tab === null || tab.disabled) return false; + // event before + var eventData = this.trigger({ phase: 'before', type: 'click', target: id, tab: tab, object: tab, originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active) +' .w2ui-tab').removeClass('active'); + this.active = tab.id; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(id); + }, - animateClose: function(id, event) { - var tab = this.get(id); - if (tab === null || tab.disabled) return false; - // event before - var eventData = this.trigger({ phase: 'before', type: 'close', target: id, object: this.get(id), originalEvent: event }); - if (eventData.isCancelled === true) return; - // default action - var obj = this; - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).css({ - '-webkit-transition': '.2s', - '-moz-transition': '2s', - '-ms-transition': '.2s', - '-o-transition': '.2s', - opacity: '0' }); - setTimeout(function () { - var width = $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).width(); - $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)) - .html('
      '); - setTimeout(function () { - $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).find(':first-child').css({ 'width': '0px' }); - }, 50); - }, 200); - setTimeout(function () { - obj.remove(id); - }, 450); - // event before - this.trigger($.extend(eventData, { phase: 'after' })); - this.refresh(); - }, + animateClose: function(id, event) { + var tab = this.get(id); + if (tab === null || tab.disabled) return false; + // event before + var eventData = this.trigger({ phase: 'before', type: 'close', target: id, object: this.get(id), originalEvent: event }); + if (eventData.isCancelled === true) return; + // default action + var obj = this; + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).css({ + '-webkit-transition': '.2s', + '-moz-transition': '2s', + '-ms-transition': '.2s', + '-o-transition': '.2s', + opacity: '0' }); + setTimeout(function () { + var width = $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).width(); + $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)) + .html('
      '); + setTimeout(function () { + $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).find(':first-child').css({ 'width': '0px' }); + }, 50); + }, 200); + setTimeout(function () { + obj.remove(id); + }, 450); + // event before + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(); + }, - animateInsert: function(id, tab) { - if (this.get(id) === null) return; - if (!$.isPlainObject(tab)) return; - // check for unique - if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return; - // insert simple div - var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); - if (jq_el.length !== 0) return; // already exists - // measure width - if (typeof tab.caption !== 'undefined') tab.text = tab.caption; - var tmp = '
      '+ - ''+ - '
      '+ - (tab.closable ? '
      ' : '') + - '
      '+ tab.text +'
      '+ - '
      '+ - '
      '; - $('body').append(tmp); - // create dummy element - var tabHTML = '
       
      '; - var addStyle = ''; - if (tab.hidden) { addStyle += 'display: none;'; } - if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } - var html = ''+ tabHTML +''; - if (this.get(id, true) !== this.tabs.length && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).length > 0) { - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).before(html); - } else { - $(this.box).find('#tabs_'+ this.name +'_right').before(html); - } - // -- move - var obj = this; - setTimeout(function () { - var width = $('#_tmp_simple_tab').width(); - $('#_tmp_tabs').remove(); - $('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id) +' > div').css('width', width+'px'); - }, 1); - setTimeout(function () { - // insert for real - obj.insert(id, tab); - }, 200); - } - }; + animateInsert: function(id, tab) { + if (this.get(id) === null) return; + if (!$.isPlainObject(tab)) return; + // check for unique + if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return; + // insert simple div + var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); + if (jq_el.length !== 0) return; // already exists + // measure width + if (typeof tab.caption !== 'undefined') tab.text = tab.caption; + var tmp = '
      '+ + ''+ + '
      '+ + (tab.closable ? '
      ' : '') + + '
      '+ tab.text +'
      '+ + '
      '+ + '
      '; + $('body').append(tmp); + // create dummy element + var tabHTML = '
       
      '; + var addStyle = ''; + if (tab.hidden) { addStyle += 'display: none;'; } + if (tab.disabled) { addStyle += 'opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);'; } + var html = ''+ tabHTML +''; + if (this.get(id, true) !== this.tabs.length && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).length > 0) { + $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).before(html); + } else { + $(this.box).find('#tabs_'+ this.name +'_right').before(html); + } + // -- move + var obj = this; + setTimeout(function () { + var width = $('#_tmp_simple_tab').width(); + $('#_tmp_tabs').remove(); + $('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id) +' > div').css('width', width+'px'); + }, 1); + setTimeout(function () { + // insert for real + obj.insert(id, tab); + }, 200); + } + }; - $.extend(w2tabs.prototype, w2utils.event); - w2obj.tabs = w2tabs; + $.extend(w2tabs.prototype, w2utils.event); + w2obj.tabs = w2tabs; })(); diff --git a/src/w2toolbar.js b/src/w2toolbar.js index 0029e0851..af4c2e15c 100644 --- a/src/w2toolbar.js +++ b/src/w2toolbar.js @@ -1,511 +1,511 @@ /************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2toolbar - toolbar widget -* - $().w2toolbar - jQuery wrapper -* - Dependencies: jQuery, w2utils +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2toolbar - toolbar widget +* - $().w2toolbar - jQuery wrapper +* - Dependencies: jQuery, w2utils * * == NICE TO HAVE == -* - on overflow display << >> -* - verticle toolbar +* - on overflow display << >> +* - verticle toolbar * * == 1.4 changes -* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 -* - fixed submenu event bugs +* - deleted getSelection().removeAllRanges() - see https://github.com/vitmalina/w2ui/issues/323 +* - fixed submenu event bugs * ************************************************************************/ (function () { - var w2toolbar = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.items = []; - this.right = ''; // HTML text on the right of toolbar - this.onClick = null; - this.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null; - - $.extend(true, this, w2obj.toolbar, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2toolbar = function(method) { - if (typeof method === 'object' || !method ) { - // check name parameter - if (!w2utils.checkName(method, 'w2toolbar')) return; - // extend items - var items = method.items || []; - var object = new w2toolbar(method); - $.extend(object, { items: [], handlers: [] }); - for (var i = 0; i < items.length; i++) { - object.items[i] = $.extend({}, w2toolbar.prototype.item, items[i]); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - // register new object - w2ui[object.name] = object; - return object; - - } else if (w2ui[$(this).attr('name')]) { - var obj = w2ui[$(this).attr('name')]; - obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2toolbar' ); - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2toolbar.prototype = { - item: { - id : null, // command to be sent to all event handlers - type : 'button', // button, check, radio, drop, menu, break, html, spacer - text : '', - html : '', - img : null, - icon : null, - hidden : false, - disabled: false, - checked : false, // used for radio buttons - arrow : true, // arrow down for drop/menu types - hint : '', - group : null, // used for radio buttons - items : null, // for type menu it is an array of items in the menu - onClick : null - }, - - add: function (items) { - this.insert(null, items); - }, - - insert: function (id, items) { - if (!$.isArray(items)) items = [items]; - for (var o = 0; o < items.length; o++) { - // checks - if (typeof items[o].type === 'undefined') { - console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.'); - return; - } - if ($.inArray(String(items[o].type), ['button', 'check', 'radio', 'drop', 'menu', 'break', 'html', 'spacer']) === -1) { - console.log('ERROR: The parameter "type" should be one of the following [button, check, radio, drop, menu, break, html, spacer] '+ - 'in w2toolbar.add() method.'); - return; - } - if (typeof items[o].id === 'undefined') { - console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.'); - return; - } - if (!w2utils.checkUniqueId(items[o].id, this.items, 'toolbar items', this.name)) return; - // add item - var it = $.extend({}, w2toolbar.prototype.item, items[o]); - if (id == null) { - this.items.push(it); - } else { - var middle = this.get(id, true); - this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle)); - } - this.refresh(it.id); - } - }, - - remove: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - removed++; - // remove from screen - $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove(); - // remove from array - var ind = this.get(it.id, true); - if (ind) this.items.splice(ind, 1); - } - return removed; - }, - - set: function (id, item) { - var index = this.get(id, true); - if (index === null) return false; - $.extend(this.items[index], item); - this.refresh(id); - return true; - }, - - get: function (id, returnIndex) { - if (arguments.length === 0) { - var all = []; - for (var i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id !== null) all.push(this.items[i1].id); - return all; - } - for (var i2 = 0; i2 < this.items.length; i2++) { - if (this.items[i2].id === id) { - if (returnIndex === true) return i2; else return this.items[i2]; - } - } - return null; - }, - - show: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.hidden = false; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - hide: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.hidden = true; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - enable: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.disabled = false; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - disable: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.disabled = true; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - check: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.checked = true; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - uncheck: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.checked = false; - tmp.push(it.id); - } - setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout - return items; - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return; - - if (box != null) { - if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-toolbar') - .html(''); - } - this.box = box; - } - if (!this.box) return; - // render all buttons - var html = ''+ - ''; - for (var i = 0; i < this.items.length; i++) { - var it = this.items[i]; - if (it.id == null) it.id = "item_" + i; - if (it === null) continue; - if (it.type === 'spacer') { - html += ''; - } else { - html += ''; - } - } - html += ''; - html += ''+ - '
      '+ this.getItemHTML(it) + - ''+ this.right +'
      '; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-toolbar') - .html(html); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - refresh: function (id) { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), item: this.get(id) }); - if (eventData.isCancelled === true) return; - - if (id == null) { - // refresh all - for (var i = 0; i < this.items.length; i++) { - var it1 = this.items[i]; - if (it1.id == null) it1.id = "item_" + i; - this.refresh(it1.id); - } - } - // create or refresh only one item - var it = this.get(id); - if (it === null) return false; - - var el = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)); - var html = this.getItemHTML(it); - if (el.length === 0) { - // does not exist - create it - if (it.type === 'spacer') { - html = ''; - } else { - html = ''+ html + - ''; - } - if (this.get(id, true) === this.items.length-1) { - $(this.box).find('#tb_'+ this.name +'_right').before(html); - } else { - $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(this.items[parseInt(this.get(id, true))+1].id)).before(html); - } - } else { - // refresh - el.html(html); - if (it.hidden) { el.css('display', 'none'); } else { el.css('display', ''); } - if (it.disabled) { el.addClass('disabled'); } else { el.removeClass('disabled'); } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - resize: function () { - var time = (new Date()).getTime(); - // event before - var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (eventData.isCancelled === true) return; - - // intentionaly blank - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return; - // clean up - if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-toolbar') - .html(''); - } - $(this.box).html(''); - delete w2ui[this.name]; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, - - // ======================================== - // --- Internal Functions - - getItemHTML: function (item) { - var html = ''; - - if (typeof item.caption !== 'undefined') item.text = item.caption; - if (typeof item.hint === 'undefined') item.hint = ''; - if (typeof item.text === 'undefined') item.text = ''; - - switch (item.type) { - case 'menu': - case 'button': - case 'check': - case 'radio': - case 'drop': - var img = ' '; - if (item.img) img = '
      '; - if (item.icon) img = '
      '; - html += ''+ - '
      '+ - ' '+ - ' ' + - img + - (item.text !== '' ? '' : '') + - (((item.type === 'drop' || item.type === 'menu') && item.arrow !== false) ? - '' : '') + - '
      '+ item.text +'
      '+ - '
      '; - break; - - case 'break': - html += ''+ - ' '+ - '
       
      '; - break; - - case 'html': - html += ''+ - ' '+ - '
      ' + item.html + '
      '; - break; - } - - var newHTML = ''; - if (typeof item.onRender === 'function') newHTML = item.onRender.call(this, item.id, html); - if (typeof this.onRender === 'function') newHTML = this.onRender(item.id, html); - if (newHTML !== '' && newHTML != null) html = newHTML; - return html; - }, - - menuClick: function (event) { - var obj = this; - if (event.item && !event.item.disabled) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'click', target: event.item.id + ':' + event.subItem.id, item: event.item, - subItem: event.subItem, originalEvent: event.originalEvent }); - if (eventData.isCancelled === true) return; - - // intentionaly blank - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - }, - - click: function (id, event) { - var obj = this; - var it = this.get(id); - if (it && !it.disabled) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'click', target: (typeof id !== 'undefined' ? id : this.name), - item: it, object: it, originalEvent: event }); - if (eventData.isCancelled === true) return; - - var btn = $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button'); - btn.removeClass('down'); - - if (it.type === 'radio') { - for (var i = 0; i < this.items.length; i++) { - var itt = this.items[i]; - if (itt == null || itt.id === it.id || itt.type !== 'radio') continue; - if (itt.group === it.group && itt.checked) { - itt.checked = false; - this.refresh(itt.id); - } - } - it.checked = true; - btn.addClass('checked'); - } - - if (it.type === 'drop' || it.type === 'menu') { - if (it.checked) { - // if it was already checked, second click will hide it - it.checked = false; - } else { - // show overlay - setTimeout(function () { - var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); - if (!$.isPlainObject(it.overlay)) it.overlay = {}; - var left = (el.width() - 50) / 2; - if (left > 19) left = 19; - if (it.type === 'drop') { - el.w2overlay(it.html, $.extend({ left: left, top: 3 }, it.overlay)); - } - if (it.type === 'menu') { - el.w2menu(it.items, $.extend({ left: left, top: 3 }, it.overlay, { - select: function (event) { - obj.menuClick({ item: it, subItem: event.item, originalEvent: event.originalEvent }); - hideDrop(); - } - })); - } - // window.click to hide it - $(document).on('click', hideDrop); - function hideDrop() { - $(document).off('click', hideDrop); - it.checked = false; - btn.removeClass('checked'); - } - }, 1); - } - } - - if (it.type === 'check' || it.type === 'drop' || it.type === 'menu') { - it.checked = !it.checked; - if (it.checked) { - btn.addClass('checked'); - } else { - btn.removeClass('checked'); - } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - } - }; - - $.extend(w2toolbar.prototype, w2utils.event); - w2obj.toolbar = w2toolbar; + var w2toolbar = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.items = []; + this.right = ''; // HTML text on the right of toolbar + this.onClick = null; + this.onRender = null; + this.onRefresh = null; + this.onResize = null; + this.onDestroy = null; + + $.extend(true, this, w2obj.toolbar, options); + }; + + // ==================================================== + // -- Registers as a jQuery plugin + + $.fn.w2toolbar = function(method) { + if (typeof method === 'object' || !method ) { + // check name parameter + if (!w2utils.checkName(method, 'w2toolbar')) return; + // extend items + var items = method.items || []; + var object = new w2toolbar(method); + $.extend(object, { items: [], handlers: [] }); + for (var i = 0; i < items.length; i++) { + object.items[i] = $.extend({}, w2toolbar.prototype.item, items[i]); + } + if ($(this).length !== 0) { + object.render($(this)[0]); + } + // register new object + w2ui[object.name] = object; + return object; + + } else if (w2ui[$(this).attr('name')]) { + var obj = w2ui[$(this).attr('name')]; + obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); + return this; + } else { + console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2toolbar' ); + } + }; + + // ==================================================== + // -- Implementation of core functionality + + w2toolbar.prototype = { + item: { + id : null, // command to be sent to all event handlers + type : 'button', // button, check, radio, drop, menu, break, html, spacer + text : '', + html : '', + img : null, + icon : null, + hidden : false, + disabled : false, + checked : false, // used for radio buttons + arrow : true, // arrow down for drop/menu types + hint : '', + group : null, // used for radio buttons + items : null, // for type menu it is an array of items in the menu + onClick : null + }, + + add: function (items) { + this.insert(null, items); + }, + + insert: function (id, items) { + if (!$.isArray(items)) items = [items]; + for (var o = 0; o < items.length; o++) { + // checks + if (typeof items[o].type === 'undefined') { + console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.'); + return; + } + if ($.inArray(String(items[o].type), ['button', 'check', 'radio', 'drop', 'menu', 'break', 'html', 'spacer']) === -1) { + console.log('ERROR: The parameter "type" should be one of the following [button, check, radio, drop, menu, break, html, spacer] '+ + 'in w2toolbar.add() method.'); + return; + } + if (typeof items[o].id === 'undefined') { + console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.'); + return; + } + if (!w2utils.checkUniqueId(items[o].id, this.items, 'toolbar items', this.name)) return; + // add item + var it = $.extend({}, w2toolbar.prototype.item, items[o]); + if (id == null) { + this.items.push(it); + } else { + var middle = this.get(id, true); + this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle)); + } + this.refresh(it.id); + } + }, + + remove: function () { + var removed = 0; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + removed++; + // remove from screen + $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove(); + // remove from array + var ind = this.get(it.id, true); + if (ind) this.items.splice(ind, 1); + } + return removed; + }, + + set: function (id, item) { + var index = this.get(id, true); + if (index === null) return false; + $.extend(this.items[index], item); + this.refresh(id); + return true; + }, + + get: function (id, returnIndex) { + if (arguments.length === 0) { + var all = []; + for (var i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id !== null) all.push(this.items[i1].id); + return all; + } + for (var i2 = 0; i2 < this.items.length; i2++) { + if (this.items[i2].id === id) { + if (returnIndex === true) return i2; else return this.items[i2]; + } + } + return null; + }, + + show: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.hidden = false; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + hide: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.hidden = true; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + enable: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.disabled = false; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + disable: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.disabled = true; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + check: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.checked = true; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + uncheck: function () { + var obj = this; + var items = 0; + var tmp = []; + for (var a = 0; a < arguments.length; a++) { + var it = this.get(arguments[a]); + if (!it) continue; + items++; + it.checked = false; + tmp.push(it.id); + } + setTimeout(function () { for (var t in tmp) obj.refresh(tmp[t]); }, 15); // needs timeout + return items; + }, + + render: function (box) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); + if (eventData.isCancelled === true) return; + + if (box != null) { + if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html(''); + } + this.box = box; + } + if (!this.box) return; + // render all buttons + var html = ''+ + ''; + for (var i = 0; i < this.items.length; i++) { + var it = this.items[i]; + if (it.id == null) it.id = "item_" + i; + if (it === null) continue; + if (it.type === 'spacer') { + html += ''; + } else { + html += ''; + } + } + html += ''; + html += ''+ + '
      '+ this.getItemHTML(it) + + ''+ this.right +'
      '; + $(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-toolbar') + .html(html); + if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + refresh: function (id) { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'refresh', target: (typeof id !== 'undefined' ? id : this.name), item: this.get(id) }); + if (eventData.isCancelled === true) return; + + if (id == null) { + // refresh all + for (var i = 0; i < this.items.length; i++) { + var it1 = this.items[i]; + if (it1.id == null) it1.id = "item_" + i; + this.refresh(it1.id); + } + } + // create or refresh only one item + var it = this.get(id); + if (it === null) return false; + + var el = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)); + var html = this.getItemHTML(it); + if (el.length === 0) { + // does not exist - create it + if (it.type === 'spacer') { + html = ''; + } else { + html = ''+ html + + ''; + } + if (this.get(id, true) === this.items.length-1) { + $(this.box).find('#tb_'+ this.name +'_right').before(html); + } else { + $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(this.items[parseInt(this.get(id, true))+1].id)).before(html); + } + } else { + // refresh + el.html(html); + if (it.hidden) { el.css('display', 'none'); } else { el.css('display', ''); } + if (it.disabled) { el.addClass('disabled'); } else { el.removeClass('disabled'); } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + resize: function () { + var time = (new Date()).getTime(); + // event before + var eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name }); + if (eventData.isCancelled === true) return; + + // intentionaly blank + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + destroy: function () { + // event before + var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); + if (eventData.isCancelled === true) return; + // clean up + if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { + $(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html(''); + } + $(this.box).html(''); + delete w2ui[this.name]; + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, + + // ======================================== + // --- Internal Functions + + getItemHTML: function (item) { + var html = ''; + + if (typeof item.caption !== 'undefined') item.text = item.caption; + if (typeof item.hint === 'undefined') item.hint = ''; + if (typeof item.text === 'undefined') item.text = ''; + + switch (item.type) { + case 'menu': + case 'button': + case 'check': + case 'radio': + case 'drop': + var img = ' '; + if (item.img) img = '
      '; + if (item.icon) img = '
      '; + html += ''+ + '
      '+ + ' '+ + ' ' + + img + + (item.text !== '' ? '' : '') + + (((item.type === 'drop' || item.type === 'menu') && item.arrow !== false) ? + '' : '') + + '
      '+ item.text +'
      '+ + '
      '; + break; + + case 'break': + html += ''+ + ' '+ + '
       
      '; + break; + + case 'html': + html += ''+ + ' '+ + '
      ' + item.html + '
      '; + break; + } + + var newHTML = ''; + if (typeof item.onRender === 'function') newHTML = item.onRender.call(this, item.id, html); + if (typeof this.onRender === 'function') newHTML = this.onRender(item.id, html); + if (newHTML !== '' && newHTML != null) html = newHTML; + return html; + }, + + menuClick: function (event) { + var obj = this; + if (event.item && !event.item.disabled) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'click', target: event.item.id + ':' + event.subItem.id, item: event.item, + subItem: event.subItem, originalEvent: event.originalEvent }); + if (eventData.isCancelled === true) return; + + // intentionaly blank + + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + }, + + click: function (id, event) { + var obj = this; + var it = this.get(id); + if (it && !it.disabled) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'click', target: (typeof id !== 'undefined' ? id : this.name), + item: it, object: it, originalEvent: event }); + if (eventData.isCancelled === true) return; + + var btn = $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button'); + btn.removeClass('down'); + + if (it.type === 'radio') { + for (var i = 0; i < this.items.length; i++) { + var itt = this.items[i]; + if (itt == null || itt.id === it.id || itt.type !== 'radio') continue; + if (itt.group === it.group && itt.checked) { + itt.checked = false; + this.refresh(itt.id); + } + } + it.checked = true; + btn.addClass('checked'); + } + + if (it.type === 'drop' || it.type === 'menu') { + if (it.checked) { + // if it was already checked, second click will hide it + it.checked = false; + } else { + // show overlay + setTimeout(function () { + var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); + if (!$.isPlainObject(it.overlay)) it.overlay = {}; + var left = (el.width() - 50) / 2; + if (left > 19) left = 19; + if (it.type === 'drop') { + el.w2overlay(it.html, $.extend({ left: left, top: 3 }, it.overlay)); + } + if (it.type === 'menu') { + el.w2menu(it.items, $.extend({ left: left, top: 3 }, it.overlay, { + select: function (event) { + obj.menuClick({ item: it, subItem: event.item, originalEvent: event.originalEvent }); + hideDrop(); + } + })); + } + // window.click to hide it + $(document).on('click', hideDrop); + function hideDrop() { + $(document).off('click', hideDrop); + it.checked = false; + btn.removeClass('checked'); + } + }, 1); + } + } + + if (it.type === 'check' || it.type === 'drop' || it.type === 'menu') { + it.checked = !it.checked; + if (it.checked) { + btn.addClass('checked'); + } else { + btn.removeClass('checked'); + } + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + } + }; + + $.extend(w2toolbar.prototype, w2utils.event); + w2obj.toolbar = w2toolbar; })(); diff --git a/src/w2utils.js b/src/w2utils.js index 6c1fbd1f0..cf3194ddf 100644 --- a/src/w2utils.js +++ b/src/w2utils.js @@ -4,866 +4,866 @@ var w2obj = w2obj || {}; // expose object to be able to overwrite default functi /************************************************ * Library: Web 2.0 UI for jQuery * - Following objects are defines -* - w2ui - object that will contain all widgets -* - w2obj - object with widget prototypes -* - w2utils - basic utilities -* - $().w2render - common render -* - $().w2destroy - common destroy -* - $().w2marker - marker plugin -* - $().w2tag - tag plugin -* - $().w2overlay - overlay plugin -* - $().w2menu - menu plugin -* - w2utils.event - generic event object -* - w2utils.keyboard - object for keyboard navigation +* - w2ui - object that will contain all widgets +* - w2obj - object with widget prototypes +* - w2utils - basic utilities +* - $().w2render - common render +* - $().w2destroy - common destroy +* - $().w2marker - marker plugin +* - $().w2tag - tag plugin +* - $().w2overlay - overlay plugin +* - $().w2menu - menu plugin +* - w2utils.event - generic event object +* - w2utils.keyboard - object for keyboard navigation * - Dependencies: jQuery * * == NICE TO HAVE == -* - date has problems in FF new Date('yyyy-mm-dd') breaks -* - bug: w2utils.formatDate('2011-31-01', 'yyyy-dd-mm'); - wrong foratter -* - overlay should be displayed where more space (on top or on bottom) -* - write and article how to replace certain framework functions -* - format date and time is buggy -* - onComplete should pass widget as context (this) -* - add maxHeight for the w2menu -* - user localization from another lib (make it generic), https://github.com/jquery/globalize#readme -* - hidden and disabled in menus -* - isTime should support seconds -* - TEST On IOS +* - date has problems in FF new Date('yyyy-mm-dd') breaks +* - bug: w2utils.formatDate('2011-31-01', 'yyyy-dd-mm'); - wrong foratter +* - overlay should be displayed where more space (on top or on bottom) +* - write and article how to replace certain framework functions +* - format date and time is buggy +* - onComplete should pass widget as context (this) +* - add maxHeight for the w2menu +* - user localization from another lib (make it generic), https://github.com/jquery/globalize#readme +* - hidden and disabled in menus +* - isTime should support seconds +* - TEST On IOS * * == 1.4 changes -* - lock(box, options) || lock(box, msg, spinner) -* - updated age() date(), formatDate(), formatTime() - input format either '2013/12/21 19:03:59 PST' or unix timestamp -* - formatNumer(num, groupSymbol) - added new param -* - improved localization support (currency prefix, suffix, numbger group symbol) -* - improoved overlays (better positioning, refresh, etc.) -* - multiple overlay at the same time (if it has name) -* - overlay options.css removed, I have added options.style -* - ability to open searchable w2menu -* - w2confirm({}) +* - lock(box, options) || lock(box, msg, spinner) +* - updated age() date(), formatDate(), formatTime() - input format either '2013/12/21 19:03:59 PST' or unix timestamp +* - formatNumer(num, groupSymbol) - added new param +* - improved localization support (currency prefix, suffix, numbger group symbol) +* - improoved overlays (better positioning, refresh, etc.) +* - multiple overlay at the same time (if it has name) +* - overlay options.css removed, I have added options.style +* - ability to open searchable w2menu +* - w2confirm({}) * ************************************************/ var w2utils = (function () { - var tmp = {}; // for some temp variables - var obj = { - settings : { - "locale" : "en-us", - "date_format" : "m/d/yyyy", - "date_display" : "Mon d, yyyy", - "time_format" : "h12", - "currencyPrefix": "$", - "currencySuffix": "", - "currencyPrecision": 2, - "groupSymbol" : ",", - "shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - "fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - "shortdays" : ["M", "T", "W", "T", "F", "S", "S"], - "fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], - "RESTfull" : false, - "phrases" : {} // empty object for english phrases - }, - isInt : isInt, - isFloat : isFloat, - isMoney : isMoney, - isHex : isHex, - isAlphaNumeric : isAlphaNumeric, - isEmail : isEmail, - isDate : isDate, - isTime : isTime, - age : age, - date : date, - size : size, - formatNumber : formatNumber, - formatDate : formatDate, - formatTime : formatTime, - formatDateTime : formatDateTime, - stripTags : stripTags, - encodeTags : encodeTags, - escapeId : escapeId, - base64encode : base64encode, - base64decode : base64decode, - transition : transition, - lock : lock, - unlock : unlock, - lang : lang, - locale : locale, - getSize : getSize, - scrollBarSize : scrollBarSize, - checkName : checkName, - checkUniqueId : checkUniqueId - }; - return obj; - - function isInt (val) { - var re = /^[-+]?[0-9]+$/; - return re.test(val); - } - - function isFloat (val) { - return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)); - } - - function isMoney (val) { - var se = w2utils.settings; - var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +'[-+]?[0-9]*[\.]?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i'); - if (typeof val === 'string') { - val = val.replace(new RegExp(se.groupSymbol, 'g'), ''); - } - if (typeof val === 'object' || val === '') return false; - return re.test(val); - } - - function isHex (val) { - var re = /^[a-fA-F0-9]+$/; - return re.test(val); - } - - function isAlphaNumeric (val) { - var re = /^[a-zA-Z0-9_-]+$/; - return re.test(val); - } - - function isEmail (val) { - var email = /^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; - return email.test(val); - } - - function isDate (val, format, retDate) { - if (!val) return false; - - var dt = 'Invalid Date'; - var month, day, year; - - if (format == null) format = w2utils.settings.date_format; - - if (typeof val.getUTCFullYear === 'function' && typeof val.getUTCMonth === 'function' && typeof val.getUTCDate === 'function') { - year = val.getUTCFullYear(); - month = val.getUTCMonth(); - day = val.getUTCDate(); - } else if (typeof val.getFullYear === 'function' && typeof val.getMonth === 'function' && typeof val.getDate === 'function') { - year = val.getFullYear(); - month = val.getMonth(); - day = val.getDate(); - } else { - val = String(val); - // convert month formats - if (RegExp('mon', 'ig').test(format)) { - format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); - val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); - for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) { - var t = w2utils.settings.fullmonths[m]; - val = val.replace(RegExp(t, 'ig'), (parseInt(m) + 1)).replace(RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)); - } - } - // format date - var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); - var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); - if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } - if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } - if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } - if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } - if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } - if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } - if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } - if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } - if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } - if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } - } - if (!isInt(year)) return false; - if (!isInt(month)) return false; - if (!isInt(day)) return false; - year = +year; - month = +month; - day = +day; - dt = new Date(year, month - 1, day); - // do checks - if (month == null) return false; - if (dt === 'Invalid Date') return false; - if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false; - if (retDate === true) return dt; else return true; - } - - function isTime (val, retTime) { - // Both formats 10:20pm and 22:20 - if (val == null) return false; - var max, pm; - // -- process american format - val = String(val); - val = val.toUpperCase(); - pm = val.indexOf('PM') >= 0; - var ampm = (pm || val.indexOf('AM') >= 0); - if (ampm) max = 12; else max = 24; - val = val.replace('AM', '').replace('PM', ''); - val = $.trim(val); - // --- - var tmp = val.split(':'); - var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0); - // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: - if ((!ampm || tmp.length !== 1) && tmp.length !== 2) { return false; } - if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; } - if (tmp.length === 2 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; } - // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). - // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. - if (!ampm && max === h && m !== 0) { return false; } - if (ampm && tmp.length === 1 && h === 0) { return false; } - - if (retTime === true) { - if (pm) h += 12; - return { - hours: h, - minutes: m - }; - } - return true; - } - - function age (dateStr) { - if (dateStr === '' || dateStr == null) return ''; - var d1 = new Date(dateStr); - if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps - if (d1 === 'Invalid Date') return ''; - - var d2 = new Date(); - var sec = (d2.getTime() - d1.getTime()) / 1000; - var amount = ''; - var type = ''; - if (sec < 0) { - amount = 'future'; - type = ''; - } else if (sec < 60) { - amount = Math.floor(sec); - type = 'sec'; - if (sec < 0) { amount = 0; type = 'sec'; } - } else if (sec < 60*60) { - amount = Math.floor(sec/60); - type = 'min'; - } else if (sec < 24*60*60) { - amount = Math.floor(sec/60/60); - type = 'hour'; - } else if (sec < 30*24*60*60) { - amount = Math.floor(sec/24/60/60); - type = 'day'; - } else if (sec < 12*30*24*60*60) { - amount = Math.floor(sec/30/24/60/60*10)/10; - type = 'month'; - } else if (sec >= 12*30*24*60*60) { - amount = Math.floor(sec/12/30/24/60/60*10)/10; - type = 'year'; - } - return amount + ' ' + type + (amount > 1 ? 's' : ''); - } - - function date (dateStr) { - if (dateStr === '' || dateStr == null) return ''; - var d1 = new Date(dateStr); - if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps - if (d1 === 'Invalid Date') return ''; - - var months = w2utils.settings.shortmonths; - var d2 = new Date(); // today - var d3 = new Date(); - d3.setTime(d3.getTime() - 86400000); // yesterday - - var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear(); - var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear(); - var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear(); - - var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); - var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); - var dsp = dd1; - if (dd1 === dd2) dsp = time; - if (dd1 === dd3) dsp = w2utils.lang('Yesterday'); - - return ''+ dsp +''; - } - - function size (sizeStr) { - if (!w2utils.isFloat(sizeStr) || sizeStr === '') return ''; - sizeStr = parseFloat(sizeStr); - if (sizeStr === 0) return 0; - var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB']; - var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ); - return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + sizes[i]; - } - - function formatNumber (val, groupSymbol) { - var ret = ''; - if (groupSymbol == null) groupSymbol = w2utils.settings.groupSymbol || ','; - // check if this is a number - if (w2utils.isFloat(val) || w2utils.isInt(val) || w2utils.isMoney(val)) { - tmp = String(val).split('.'); - ret = String(tmp[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + groupSymbol); - if (tmp[1] != null) ret += '.' + tmp[1]; - } - return ret; - } - - function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String - var months = w2utils.settings.shortmonths; - var fullMonths = w2utils.settings.fullmonths; - if (!format) format = this.settings.date_format; - if (dateStr === '' || dateStr == null) return ''; - - var dt = new Date(dateStr); - if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps - if (dt === 'Invalid Date') return ''; - - var year = dt.getFullYear(); - var month = dt.getMonth(); - var date = dt.getDate(); - return format.toLowerCase() - .replace('month', w2utils.settings.fullmonths[month]) - .replace('mon', w2utils.settings.shortmonths[month]) - .replace(/yyyy/g, year) - .replace(/yyy/g, year) - .replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2)) - .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceeded by a letter - .replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1)) - .replace(/dd/g, (date < 10 ? '0' : '') + date) - .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceeded by a letter - } - - function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String - var months = w2utils.settings.shortmonths; - var fullMonths = w2utils.settings.fullmonths; - if (!format) format = (this.settings.time_format === 'h12' ? 'hh:mi pm' : 'h24:mi'); - if (dateStr === '' || dateStr == null) return ''; - - var dt = new Date(dateStr); - if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps - if (w2utils.isTime(dateStr)) { - var tmp = w2utils.isTime(dateStr, true); - dt = new Date(); - dt.setHours(tmp.hours); - dt.setMinutes(tmp.minutes); - } - if (dt === 'Invalid Date') return ''; - - var type = 'am'; - var hour = dt.getHours(); - var h24 = dt.getHours(); - var min = dt.getMinutes(); - var sec = dt.getSeconds(); - if (min < 10) min = '0' + min; - if (sec < 10) sec = '0' + sec; - if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { - if (hour >= 12) type = 'pm'; - if (hour > 12) hour = hour - 12; - } - return format.toLowerCase() - .replace('am', type) - .replace('pm', type) - .replace('hh', hour) - .replace('h24', h24) - .replace('mm', min) - .replace('mi', min) - .replace('ss', sec) - .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceeded by a letter - .replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceeded by a letter - } - - function formatDateTime(dateStr, format) { - var fmt; - if (typeof format !== 'string') { - fmt = [this.settings.date_format, this.settings.time_format]; - } else { - fmt = format.split('|'); - } - return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]); - } - - function stripTags (html) { - if (html === null) return html; - switch (typeof html) { - case 'number': - break; - case 'string': - html = $.trim(String(html).replace(/(<([^>]+)>)/ig, "")); - break; - case 'object': - for (var a in html) html[a] = this.stripTags(html[a]); - break; - } - return html; - } - - function encodeTags (html) { - if (html === null) return html; - switch (typeof html) { - case 'number': - break; - case 'string': - html = String(html).replace(/&/g, "&").replace(/>/g, ">").replace(/\|\/? {}\\])/g, '\\$1'); - } - - function base64encode (input) { - var output = ""; - var chr1, chr2, chr3, enc1, enc2, enc3, enc4; - var i = 0; - var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - input = utf8_encode(input); - - while (i < input.length) { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); - } - - function utf8_encode (string) { - var string = String(string).replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - var c = string.charCodeAt(n); - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - } - return utftext; - } - - return output; - } - - function base64decode (input) { - var output = ""; - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0; - var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - enc1 = keyStr.indexOf(input.charAt(i++)); - enc2 = keyStr.indexOf(input.charAt(i++)); - enc3 = keyStr.indexOf(input.charAt(i++)); - enc4 = keyStr.indexOf(input.charAt(i++)); - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - output = output + String.fromCharCode(chr1); - if (enc3 !== 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 !== 64) { - output = output + String.fromCharCode(chr3); - } - } - output = utf8_decode(output); - - function utf8_decode (utftext) { - var string = ""; - var i = 0; - var c = 0, c2, c3; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string += String.fromCharCode(c); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return string; - } - - return output; - } - - function transition (div_old, div_new, type, callBack) { - var width = $(div_old).width(); - var height = $(div_old).height(); - var time = 0.5; - - if (!div_old || !div_new) { - console.log('ERROR: Cannot do transition when one of the divs is null'); - return; - } - - div_old.parentNode.style.cssText += cross('perspective', '700px') +'; overflow: hidden;'; - div_old.style.cssText += '; position: absolute; z-index: 1019; '+ cross('backface-visibility', 'hidden'); - div_new.style.cssText += '; position: absolute; z-index: 1020; '+ cross('backface-visibility', 'hidden'); - - switch (type) { - case 'slide-left': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d('+ width + 'px, 0, 0)', 'translate('+ width +'px, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); - }, 1); - break; - - case 'slide-right': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0px, 0, 0)', 'translate(0px, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d('+ width +'px, 0, 0)', 'translate('+ width +'px, 0)'); - }, 1); - break; - - case 'slide-down': - // init divs - div_old.style.cssText += 'overflow: hidden; z-index: 1; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; z-index: 0; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); - }, 1); - break; - - case 'slide-up': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - }, 1); - break; - - case 'flip-left': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(-180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(180deg)'); - }, 1); - break; - - case 'flip-right': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(-180deg)'); - }, 1); - break; - - case 'flip-down': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(-180deg)'); - }, 1); - break; - - case 'flip-up': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(-180deg)'); - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(180deg)'); - }, 1); - break; - - case 'pop-in': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') + '; '+ cross('transform', 'scale(.8)') + '; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time+'s') +';'; - }, 1); - break; - - case 'pop-out': - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time+'s') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1.7)') +'; opacity: 0;'; - }, 1); - break; - - default: - // init divs - div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); - div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; - $(div_new).show(); - // -- need a timing function because otherwise not working - window.setTimeout(function() { - div_new.style.cssText += cross('transition', time +'s') +'; opacity: 1;'; - div_old.style.cssText += cross('transition', time +'s'); - }, 1); - break; - } - - setTimeout(function () { - if (type === 'slide-down') { - $(div_old).css('z-index', '1019'); - $(div_new).css('z-index', '1020'); - } - if (div_new) { - $(div_new).css({ - 'opacity': '1', - '-webkit-transition': '', - '-moz-transition': '', - '-ms-transition': '', - '-o-transition': '', - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '', - '-webkit-backface-visibility': '', - '-moz-backface-visibility': '', - '-ms-backface-visibility': '', - '-o-backface-visibility': '' - }); - } - if (div_old) { - $(div_old).css({ - 'opacity': '1', - '-webkit-transition': '', - '-moz-transition': '', - '-ms-transition': '', - '-o-transition': '', - '-webkit-transform': '', - '-moz-transform': '', - '-ms-transform': '', - '-o-transform': '', - '-webkit-backface-visibility': '', - '-moz-backface-visibility': '', - '-ms-backface-visibility': '', - '-o-backface-visibility': '' - }); - if (div_old.parentNode) $(div_old.parentNode).css({ - '-webkit-perspective': '', - '-moz-perspective': '', - '-ms-perspective': '', - '-o-perspective': '' - }); - } - if (typeof callBack === 'function') callBack(); - }, time * 1000); - - function cross(property, value, none_webkit_value) { - var isWebkit=!!window.webkitURL; // jQuery no longer supports $.browser - RR - if (!isWebkit && typeof none_webkit_value !== 'undefined') value = none_webkit_value; - return ';'+ property +': '+ value +'; -webkit-'+ property +': '+ value +'; -moz-'+ property +': '+ value +'; '+ - '-ms-'+ property +': '+ value +'; -o-'+ property +': '+ value +';'; - } - } - - function lock (box, msg, spinner) { - var options = {}; - if (typeof msg === 'object') { - options = msg; - } else { - options.msg = msg; - options.spinner = spinner; - } - if (!options.msg && options.msg !== 0) options.msg = ''; - w2utils.unlock(box); - $(box).prepend( - '
      '+ - '
      ' - ); - var $lock = $(box).find('.w2ui-lock'); - var mess = $(box).find('.w2ui-lock-msg'); - if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' }); - if (options.spinner === true) options.msg = '
      ' + options.msg; - if (options.opacity != null) $lock.css('opacity', options.opacity); - if (typeof $lock.fadeIn == 'function') { - $lock.fadeIn(200); - mess.html(options.msg).fadeIn(200); - } else { - $lock.show(); - mess.html(options.msg).show(0); - } - // hide all tags (do not hide overlays as the form can be in overlay) - $().w2tag(); - } - - function unlock (box) { - $(box).find('.w2ui-lock').remove(); - $(box).find('.w2ui-lock-msg').remove(); - } - - function getSize (el, type) { - var $el = $(el); - var bwidth = { - left: parseInt($el.css('border-left-width')) || 0, - right: parseInt($el.css('border-right-width')) || 0, - top: parseInt($el.css('border-top-width')) || 0, - bottom: parseInt($el.css('border-bottom-width')) || 0 - }; - var mwidth = { - left: parseInt($el.css('margin-left')) || 0, - right: parseInt($el.css('margin-right')) || 0, - top: parseInt($el.css('margin-top')) || 0, - bottom: parseInt($el.css('margin-bottom')) || 0 - }; - var pwidth = { - left: parseInt($el.css('padding-left')) || 0, - right: parseInt($el.css('padding-right')) || 0, - top: parseInt($el.css('padding-top')) || 0, - bottom: parseInt($el.css('padding-bottom')) || 0 - }; - switch (type) { - case 'top': return bwidth.top + mwidth.top + pwidth.top; - case 'bottom': return bwidth.bottom + mwidth.bottom + pwidth.bottom; - case 'left': return bwidth.left + mwidth.left + pwidth.left; - case 'right': return bwidth.right + mwidth.right + pwidth.right; - case 'width': return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width()); - case 'height': return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height()); - case '+width': return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right; - case '+height': return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom; - } - return 0; - } - - function lang (phrase) { - var translation = this.settings.phrases[phrase]; - if (translation == null) return phrase; else return translation; - } - - function locale (locale) { - if (!locale) locale = 'en-us'; - if (locale.length === 5) locale = 'locale/'+ locale +'.json'; - // load from the file - $.ajax({ - url : locale, - type : "GET", - dataType: "JSON", - async : false, - cache : false, - success : function (data, status, xhr) { - w2utils.settings = $.extend(true, w2utils.settings, data); - // apply translation to some prototype functions - var p = w2obj.grid.prototype; - for (var b in p.buttons) { - p.buttons[b].caption = w2utils.lang(p.buttons[b].caption); - p.buttons[b].hint = w2utils.lang(p.buttons[b].hint); - } - p.msgDelete = w2utils.lang(p.msgDelete); - p.msgNotJSON = w2utils.lang(p.msgNotJSON); - p.msgRefresh = w2utils.lang(p.msgRefresh); - }, - error : function (xhr, status, msg) { - console.log('ERROR: Cannot load locale '+ locale); - } - }); - } - - function scrollBarSize () { - if (tmp.scrollBarSize) return tmp.scrollBarSize; - var html = - '
      '+ - '
      1
      '+ - '
      '; - $('body').append(html); - tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width(); - $('#_scrollbar_width').remove(); - if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+ - return tmp.scrollBarSize; - } + var tmp = {}; // for some temp variables + var obj = { + settings : { + "locale" : "en-us", + "date_format" : "m/d/yyyy", + "date_display" : "Mon d, yyyy", + "time_format" : "h12", + "currencyPrefix" : "$", + "currencySuffix" : "", + "currencyPrecision" : 2, + "groupSymbol" : ",", + "shortmonths" : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + "fullmonths" : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + "shortdays" : ["M", "T", "W", "T", "F", "S", "S"], + "fulldays" : ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + "RESTfull" : false, + "phrases" : {} // empty object for english phrases + }, + isInt : isInt, + isFloat : isFloat, + isMoney : isMoney, + isHex : isHex, + isAlphaNumeric : isAlphaNumeric, + isEmail : isEmail, + isDate : isDate, + isTime : isTime, + age : age, + date : date, + size : size, + formatNumber : formatNumber, + formatDate : formatDate, + formatTime : formatTime, + formatDateTime : formatDateTime, + stripTags : stripTags, + encodeTags : encodeTags, + escapeId : escapeId, + base64encode : base64encode, + base64decode : base64decode, + transition : transition, + lock : lock, + unlock : unlock, + lang : lang, + locale : locale, + getSize : getSize, + scrollBarSize : scrollBarSize, + checkName : checkName, + checkUniqueId : checkUniqueId + }; + return obj; + + function isInt (val) { + var re = /^[-+]?[0-9]+$/; + return re.test(val); + } + + function isFloat (val) { + return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)); + } + + function isMoney (val) { + var se = w2utils.settings; + var re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') +'[-+]?[0-9]*[\.]?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i'); + if (typeof val === 'string') { + val = val.replace(new RegExp(se.groupSymbol, 'g'), ''); + } + if (typeof val === 'object' || val === '') return false; + return re.test(val); + } + + function isHex (val) { + var re = /^[a-fA-F0-9]+$/; + return re.test(val); + } + + function isAlphaNumeric (val) { + var re = /^[a-zA-Z0-9_-]+$/; + return re.test(val); + } + + function isEmail (val) { + var email = /^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; + return email.test(val); + } + + function isDate (val, format, retDate) { + if (!val) return false; + + var dt = 'Invalid Date'; + var month, day, year; + + if (format == null) format = w2utils.settings.date_format; + + if (typeof val.getUTCFullYear === 'function' && typeof val.getUTCMonth === 'function' && typeof val.getUTCDate === 'function') { + year = val.getUTCFullYear(); + month = val.getUTCMonth(); + day = val.getUTCDate(); + } else if (typeof val.getFullYear === 'function' && typeof val.getMonth === 'function' && typeof val.getDate === 'function') { + year = val.getFullYear(); + month = val.getMonth(); + day = val.getDate(); + } else { + val = String(val); + // convert month formats + if (RegExp('mon', 'ig').test(format)) { + format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase(); + for (var m = 0, len = w2utils.settings.fullmonths.length; m < len; m++) { + var t = w2utils.settings.fullmonths[m]; + val = val.replace(RegExp(t, 'ig'), (parseInt(m) + 1)).replace(RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)); + } + } + // format date + var tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); + var tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); + if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2]; } + if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0]; } + if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0]; } + if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2]; } + if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900; } + if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900; } + } + if (!isInt(year)) return false; + if (!isInt(month)) return false; + if (!isInt(day)) return false; + year = +year; + month = +month; + day = +day; + dt = new Date(year, month - 1, day); + // do checks + if (month == null) return false; + if (dt === 'Invalid Date') return false; + if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false; + if (retDate === true) return dt; else return true; + } + + function isTime (val, retTime) { + // Both formats 10:20pm and 22:20 + if (val == null) return false; + var max, pm; + // -- process american format + val = String(val); + val = val.toUpperCase(); + pm = val.indexOf('PM') >= 0; + var ampm = (pm || val.indexOf('AM') >= 0); + if (ampm) max = 12; else max = 24; + val = val.replace('AM', '').replace('PM', ''); + val = $.trim(val); + // --- + var tmp = val.split(':'); + var h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0); + // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: + if ((!ampm || tmp.length !== 1) && tmp.length !== 2) { return false; } + if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false; } + if (tmp.length === 2 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false; } + // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). + // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. + if (!ampm && max === h && m !== 0) { return false; } + if (ampm && tmp.length === 1 && h === 0) { return false; } + + if (retTime === true) { + if (pm) h += 12; + return { + hours: h, + minutes: m + }; + } + return true; + } + + function age (dateStr) { + if (dateStr === '' || dateStr == null) return ''; + var d1 = new Date(dateStr); + if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps + if (d1 === 'Invalid Date') return ''; + + var d2 = new Date(); + var sec = (d2.getTime() - d1.getTime()) / 1000; + var amount = ''; + var type = ''; + if (sec < 0) { + amount = 'future'; + type = ''; + } else if (sec < 60) { + amount = Math.floor(sec); + type = 'sec'; + if (sec < 0) { amount = 0; type = 'sec'; } + } else if (sec < 60*60) { + amount = Math.floor(sec/60); + type = 'min'; + } else if (sec < 24*60*60) { + amount = Math.floor(sec/60/60); + type = 'hour'; + } else if (sec < 30*24*60*60) { + amount = Math.floor(sec/24/60/60); + type = 'day'; + } else if (sec < 12*30*24*60*60) { + amount = Math.floor(sec/30/24/60/60*10)/10; + type = 'month'; + } else if (sec >= 12*30*24*60*60) { + amount = Math.floor(sec/12/30/24/60/60*10)/10; + type = 'year'; + } + return amount + ' ' + type + (amount > 1 ? 's' : ''); + } + + function date (dateStr) { + if (dateStr === '' || dateStr == null) return ''; + var d1 = new Date(dateStr); + if (w2utils.isInt(dateStr)) d1 = new Date(Number(dateStr)); // for unix timestamps + if (d1 === 'Invalid Date') return ''; + + var months = w2utils.settings.shortmonths; + var d2 = new Date(); // today + var d3 = new Date(); + d3.setTime(d3.getTime() - 86400000); // yesterday + + var dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear(); + var dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear(); + var dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear(); + + var time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var time2= (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am'); + var dsp = dd1; + if (dd1 === dd2) dsp = time; + if (dd1 === dd3) dsp = w2utils.lang('Yesterday'); + + return ''+ dsp +''; + } + + function size (sizeStr) { + if (!w2utils.isFloat(sizeStr) || sizeStr === '') return ''; + sizeStr = parseFloat(sizeStr); + if (sizeStr === 0) return 0; + var sizes = ['Bt', 'KB', 'MB', 'GB', 'TB']; + var i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ); + return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + sizes[i]; + } + + function formatNumber (val, groupSymbol) { + var ret = ''; + if (groupSymbol == null) groupSymbol = w2utils.settings.groupSymbol || ','; + // check if this is a number + if (w2utils.isFloat(val) || w2utils.isInt(val) || w2utils.isMoney(val)) { + tmp = String(val).split('.'); + ret = String(tmp[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + groupSymbol); + if (tmp[1] != null) ret += '.' + tmp[1]; + } + return ret; + } + + function formatDate (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + var months = w2utils.settings.shortmonths; + var fullMonths = w2utils.settings.fullmonths; + if (!format) format = this.settings.date_format; + if (dateStr === '' || dateStr == null) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (dt === 'Invalid Date') return ''; + + var year = dt.getFullYear(); + var month = dt.getMonth(); + var date = dt.getDate(); + return format.toLowerCase() + .replace('month', w2utils.settings.fullmonths[month]) + .replace('mon', w2utils.settings.shortmonths[month]) + .replace(/yyyy/g, year) + .replace(/yyy/g, year) + .replace(/yy/g, year > 2000 ? 100 + parseInt(String(year).substr(2)) : String(year).substr(2)) + .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceeded by a letter + .replace(/mm/g, (month + 1 < 10 ? '0' : '') + (month + 1)) + .replace(/dd/g, (date < 10 ? '0' : '') + date) + .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])d/g, '$1' + date); // only y's that are not preceeded by a letter + } + + function formatTime (dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + var months = w2utils.settings.shortmonths; + var fullMonths = w2utils.settings.fullmonths; + if (!format) format = (this.settings.time_format === 'h12' ? 'hh:mi pm' : 'h24:mi'); + if (dateStr === '' || dateStr == null) return ''; + + var dt = new Date(dateStr); + if (w2utils.isInt(dateStr)) dt = new Date(Number(dateStr)); // for unix timestamps + if (w2utils.isTime(dateStr)) { + var tmp = w2utils.isTime(dateStr, true); + dt = new Date(); + dt.setHours(tmp.hours); + dt.setMinutes(tmp.minutes); + } + if (dt === 'Invalid Date') return ''; + + var type = 'am'; + var hour = dt.getHours(); + var h24 = dt.getHours(); + var min = dt.getMinutes(); + var sec = dt.getSeconds(); + if (min < 10) min = '0' + min; + if (sec < 10) sec = '0' + sec; + if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { + if (hour >= 12) type = 'pm'; + if (hour > 12) hour = hour - 12; + } + return format.toLowerCase() + .replace('am', type) + .replace('pm', type) + .replace('hh', hour) + .replace('h24', h24) + .replace('mm', min) + .replace('mi', min) + .replace('ss', sec) + .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceeded by a letter + .replace(/(^|[^a-z$])s/g, '$1' + sec); // only y's that are not preceeded by a letter + } + + function formatDateTime(dateStr, format) { + var fmt; + if (typeof format !== 'string') { + fmt = [this.settings.date_format, this.settings.time_format]; + } else { + fmt = format.split('|'); + } + return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]); + } + + function stripTags (html) { + if (html === null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = $.trim(String(html).replace(/(<([^>]+)>)/ig, "")); + break; + case 'object': + for (var a in html) html[a] = this.stripTags(html[a]); + break; + } + return html; + } + + function encodeTags (html) { + if (html === null) return html; + switch (typeof html) { + case 'number': + break; + case 'string': + html = String(html).replace(/&/g, "&").replace(/>/g, ">").replace(/\|\/? {}\\])/g, '\\$1'); + } + + function base64encode (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = utf8_encode(input); + + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); + } + + function utf8_encode (string) { + var string = String(string).replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + } + + return output; + } + + function base64decode (input) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 !== 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 !== 64) { + output = output + String.fromCharCode(chr3); + } + } + output = utf8_decode(output); + + function utf8_decode (utftext) { + var string = ""; + var i = 0; + var c = 0, c2, c3; + + while ( i < utftext.length ) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + + return string; + } + + return output; + } + + function transition (div_old, div_new, type, callBack) { + var width = $(div_old).width(); + var height = $(div_old).height(); + var time = 0.5; + + if (!div_old || !div_new) { + console.log('ERROR: Cannot do transition when one of the divs is null'); + return; + } + + div_old.parentNode.style.cssText += cross('perspective', '700px') +'; overflow: hidden;'; + div_old.style.cssText += '; position: absolute; z-index: 1019; '+ cross('backface-visibility', 'hidden'); + div_new.style.cssText += '; position: absolute; z-index: 1020; '+ cross('backface-visibility', 'hidden'); + + switch (type) { + case 'slide-left': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d('+ width + 'px, 0, 0)', 'translate('+ width +'px, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +';'+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); + }, 1); + break; + + case 'slide-right': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(-'+ width +'px, 0, 0)', 'translate(-'+ width +'px, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0px, 0, 0)', 'translate(0px, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d('+ width +'px, 0, 0)', 'translate('+ width +'px, 0)'); + }, 1); + break; + + case 'slide-down': + // init divs + div_old.style.cssText += 'overflow: hidden; z-index: 1; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; z-index: 0; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); + }, 1); + break; + + case 'slide-up': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, '+ height +'px, 0)', 'translate(0, '+ height +'px)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + }, 1); + break; + + case 'flip-left': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(-180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(180deg)'); + }, 1); + break; + + case 'flip-right': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateY(180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateY(-180deg)'); + }, 1); + break; + + case 'flip-down': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(-180deg)'); + }, 1); + break; + + case 'flip-up': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(0deg)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'rotateX(-180deg)'); + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(0deg)'); + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'rotateX(180deg)'); + }, 1); + break; + + case 'pop-in': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') + '; '+ cross('transform', 'scale(.8)') + '; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time+'s') +';'; + }, 1); + break; + + case 'pop-out': + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; '+ cross('transform', 'scale(1)') +'; opacity: 1;'; + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time+'s') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time+'s') +'; '+ cross('transform', 'scale(1.7)') +'; opacity: 0;'; + }, 1); + break; + + default: + // init divs + div_old.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)'); + div_new.style.cssText += 'overflow: hidden; '+ cross('transform', 'translate3d(0, 0, 0)', 'translate(0, 0)') +'; opacity: 0;'; + $(div_new).show(); + // -- need a timing function because otherwise not working + window.setTimeout(function() { + div_new.style.cssText += cross('transition', time +'s') +'; opacity: 1;'; + div_old.style.cssText += cross('transition', time +'s'); + }, 1); + break; + } + + setTimeout(function () { + if (type === 'slide-down') { + $(div_old).css('z-index', '1019'); + $(div_new).css('z-index', '1020'); + } + if (div_new) { + $(div_new).css({ + 'opacity': '1', + '-webkit-transition': '', + '-moz-transition': '', + '-ms-transition': '', + '-o-transition': '', + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '', + '-webkit-backface-visibility': '', + '-moz-backface-visibility': '', + '-ms-backface-visibility': '', + '-o-backface-visibility': '' + }); + } + if (div_old) { + $(div_old).css({ + 'opacity': '1', + '-webkit-transition': '', + '-moz-transition': '', + '-ms-transition': '', + '-o-transition': '', + '-webkit-transform': '', + '-moz-transform': '', + '-ms-transform': '', + '-o-transform': '', + '-webkit-backface-visibility': '', + '-moz-backface-visibility': '', + '-ms-backface-visibility': '', + '-o-backface-visibility': '' + }); + if (div_old.parentNode) $(div_old.parentNode).css({ + '-webkit-perspective': '', + '-moz-perspective': '', + '-ms-perspective': '', + '-o-perspective': '' + }); + } + if (typeof callBack === 'function') callBack(); + }, time * 1000); + + function cross(property, value, none_webkit_value) { + var isWebkit=!!window.webkitURL; // jQuery no longer supports $.browser - RR + if (!isWebkit && typeof none_webkit_value !== 'undefined') value = none_webkit_value; + return ';'+ property +': '+ value +'; -webkit-'+ property +': '+ value +'; -moz-'+ property +': '+ value +'; '+ + '-ms-'+ property +': '+ value +'; -o-'+ property +': '+ value +';'; + } + } + + function lock (box, msg, spinner) { + var options = {}; + if (typeof msg === 'object') { + options = msg; + } else { + options.msg = msg; + options.spinner = spinner; + } + if (!options.msg && options.msg !== 0) options.msg = ''; + w2utils.unlock(box); + $(box).prepend( + '
      '+ + '
      ' + ); + var $lock = $(box).find('.w2ui-lock'); + var mess = $(box).find('.w2ui-lock-msg'); + if (!options.msg) mess.css({ 'background-color': 'transparent', 'border': '0px' }); + if (options.spinner === true) options.msg = '
      ' + options.msg; + if (options.opacity != null) $lock.css('opacity', options.opacity); + if (typeof $lock.fadeIn == 'function') { + $lock.fadeIn(200); + mess.html(options.msg).fadeIn(200); + } else { + $lock.show(); + mess.html(options.msg).show(0); + } + // hide all tags (do not hide overlays as the form can be in overlay) + $().w2tag(); + } + + function unlock (box) { + $(box).find('.w2ui-lock').remove(); + $(box).find('.w2ui-lock-msg').remove(); + } + + function getSize (el, type) { + var $el = $(el); + var bwidth = { + left : parseInt($el.css('border-left-width')) || 0, + right : parseInt($el.css('border-right-width')) || 0, + top : parseInt($el.css('border-top-width')) || 0, + bottom : parseInt($el.css('border-bottom-width')) || 0 + }; + var mwidth = { + left : parseInt($el.css('margin-left')) || 0, + right : parseInt($el.css('margin-right')) || 0, + top : parseInt($el.css('margin-top')) || 0, + bottom : parseInt($el.css('margin-bottom')) || 0 + }; + var pwidth = { + left : parseInt($el.css('padding-left')) || 0, + right : parseInt($el.css('padding-right')) || 0, + top : parseInt($el.css('padding-top')) || 0, + bottom : parseInt($el.css('padding-bottom')) || 0 + }; + switch (type) { + case 'top' : return bwidth.top + mwidth.top + pwidth.top; + case 'bottom' : return bwidth.bottom + mwidth.bottom + pwidth.bottom; + case 'left' : return bwidth.left + mwidth.left + pwidth.left; + case 'right' : return bwidth.right + mwidth.right + pwidth.right; + case 'width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right + parseInt($el.width()); + case 'height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom + parseInt($el.height()); + case '+width' : return bwidth.left + bwidth.right + mwidth.left + mwidth.right + pwidth.left + pwidth.right; + case '+height' : return bwidth.top + bwidth.bottom + mwidth.top + mwidth.bottom + pwidth.top + pwidth.bottom; + } + return 0; + } + + function lang (phrase) { + var translation = this.settings.phrases[phrase]; + if (translation == null) return phrase; else return translation; + } + + function locale (locale) { + if (!locale) locale = 'en-us'; + if (locale.length === 5) locale = 'locale/'+ locale +'.json'; + // load from the file + $.ajax({ + url : locale, + type : "GET", + dataType : "JSON", + async : false, + cache : false, + success : function (data, status, xhr) { + w2utils.settings = $.extend(true, w2utils.settings, data); + // apply translation to some prototype functions + var p = w2obj.grid.prototype; + for (var b in p.buttons) { + p.buttons[b].caption = w2utils.lang(p.buttons[b].caption); + p.buttons[b].hint = w2utils.lang(p.buttons[b].hint); + } + p.msgDelete = w2utils.lang(p.msgDelete); + p.msgNotJSON = w2utils.lang(p.msgNotJSON); + p.msgRefresh = w2utils.lang(p.msgRefresh); + }, + error : function (xhr, status, msg) { + console.log('ERROR: Cannot load locale '+ locale); + } + }); + } + + function scrollBarSize () { + if (tmp.scrollBarSize) return tmp.scrollBarSize; + var html = + '
      '+ + '
      1
      '+ + '
      '; + $('body').append(html); + tmp.scrollBarSize = 100 - $('#_scrollbar_width > div').width(); + $('#_scrollbar_width').remove(); + if (String(navigator.userAgent).indexOf('MSIE') >= 0) tmp.scrollBarSize = tmp.scrollBarSize / 2; // need this for IE9+ + return tmp.scrollBarSize; + } function checkName (params, component) { // was w2checkNameParam - if (!params || typeof params.name === 'undefined') { - console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().'); - return false; - } - if (typeof w2ui[params.name] !== 'undefined') { - console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').'); - return false; - } - if (!w2utils.isAlphaNumeric(params.name)) { - console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); - return false; - } - return true; - } - - function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId - if (!$.isArray(items)) items = [items]; - for (var i = 0; i < items.length; i++) { - if (items[i].id === id) { - console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')'); - return false; - } - } - return true; - } + if (!params || typeof params.name === 'undefined') { + console.log('ERROR: The parameter "name" is required but not supplied in $().'+ component +'().'); + return false; + } + if (typeof w2ui[params.name] !== 'undefined') { + console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ params.name +').'); + return false; + } + if (!w2utils.isAlphaNumeric(params.name)) { + console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); + return false; + } + return true; + } + + function checkUniqueId (id, items, itemsDecription, objName) { // was w2checkUniqueId + if (!$.isArray(items)) items = [items]; + for (var i = 0; i < items.length; i++) { + if (items[i].id === id) { + console.log('ERROR: The parameter "id='+ id +'" is not unique within the current '+ itemsDecription +'. (obj: '+ objName +')'); + return false; + } + } + return true; + } })(); /*********************************************************** @@ -875,102 +875,102 @@ var w2utils = (function () { w2utils.event = { - on: function (eventData, handler) { - if (!$.isPlainObject(eventData)) eventData = { type: eventData }; - eventData = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, eventData); - - if (!eventData.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; } - if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; } - this.handlers.push({ event: eventData, handler: handler }); - }, - - off: function (eventData, handler) { - if (!$.isPlainObject(eventData)) eventData = { type: eventData }; - eventData = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, eventData); - - if (!eventData.type) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; } - if (!handler) { handler = null; } - // remove handlers - var newHandlers = []; - for (var h = 0, len = this.handlers.length; h < len; h++) { - var t = this.handlers[h]; - if ((t.event.type === eventData.type || eventData.type === '*') && - (t.event.target === eventData.target || eventData.target === null) && - (t.handler === handler || handler === null)) - { - // match - } else { - newHandlers.push(t); - } - } - this.handlers = newHandlers; - }, - - trigger: function (eventData) { - var eventData = $.extend({ type: null, phase: 'before', target: null }, eventData, { - isStopped: false, isCancelled: false, - preventDefault : function () { this.isCancelled = true; }, - stopPropagation : function () { this.isStopped = true; } - }); - if (eventData.phase === 'before') eventData.onComplete = null; - var args, fun, tmp; - if (eventData.target == null) eventData.target = null; - // process events in REVERSE order - for (var h = this.handlers.length-1; h >= 0; h--) { - var item = this.handlers[h]; - if ((item.event.type === eventData.type || item.event.type === '*') && - (item.event.target === eventData.target || item.event.target === null) && - (item.event.execute === eventData.phase || item.event.execute === '*' || item.event.phase === '*')) - { - eventData = $.extend({}, item.event, eventData); - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(item.handler); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - item.handler.call(this, eventData.target, eventData); // old way for back compatibility - } else { - item.handler.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true - } - } - // main object events - var funName = 'on' + eventData.type.substr(0,1).toUpperCase() + eventData.type.substr(1); - if (eventData.phase === 'before' && typeof this[funName] === 'function') { - fun = this[funName]; - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(fun); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - fun.call(this, eventData.target, eventData); // old way for back compatibility - } else { - fun.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true - } - // item object events - if (eventData.object != null && eventData.phase === 'before' && - typeof eventData.object[funName] === 'function') - { - fun = eventData.object[funName]; - // check handler arguments - args = []; - tmp = RegExp(/\((.*?)\)/).exec(fun); - if (tmp) args = tmp[1].split(/\s*,\s*/); - if (args.length === 2) { - fun.call(this, eventData.target, eventData); // old way for back compatibility - } else { - fun.call(this, eventData); // new way - } - if (eventData.isStopped === true || eventData.stop === true) return eventData; - } - // execute onComplete - if (eventData.phase === 'after' && typeof eventData.onComplete === 'function') eventData.onComplete.call(this, eventData); - - return eventData; - } + on: function (eventData, handler) { + if (!$.isPlainObject(eventData)) eventData = { type: eventData }; + eventData = $.extend({ type: null, execute: 'before', target: null, onComplete: null }, eventData); + + if (!eventData.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return; } + if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return; } + this.handlers.push({ event: eventData, handler: handler }); + }, + + off: function (eventData, handler) { + if (!$.isPlainObject(eventData)) eventData = { type: eventData }; + eventData = $.extend({}, { type: null, execute: 'before', target: null, onComplete: null }, eventData); + + if (!eventData.type) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return; } + if (!handler) { handler = null; } + // remove handlers + var newHandlers = []; + for (var h = 0, len = this.handlers.length; h < len; h++) { + var t = this.handlers[h]; + if ((t.event.type === eventData.type || eventData.type === '*') && + (t.event.target === eventData.target || eventData.target === null) && + (t.handler === handler || handler === null)) + { + // match + } else { + newHandlers.push(t); + } + } + this.handlers = newHandlers; + }, + + trigger: function (eventData) { + var eventData = $.extend({ type: null, phase: 'before', target: null }, eventData, { + isStopped: false, isCancelled: false, + preventDefault : function () { this.isCancelled = true; }, + stopPropagation : function () { this.isStopped = true; } + }); + if (eventData.phase === 'before') eventData.onComplete = null; + var args, fun, tmp; + if (eventData.target == null) eventData.target = null; + // process events in REVERSE order + for (var h = this.handlers.length-1; h >= 0; h--) { + var item = this.handlers[h]; + if ((item.event.type === eventData.type || item.event.type === '*') && + (item.event.target === eventData.target || item.event.target === null) && + (item.event.execute === eventData.phase || item.event.execute === '*' || item.event.phase === '*')) + { + eventData = $.extend({}, item.event, eventData); + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(item.handler); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + item.handler.call(this, eventData.target, eventData); // old way for back compatibility + } else { + item.handler.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true + } + } + // main object events + var funName = 'on' + eventData.type.substr(0,1).toUpperCase() + eventData.type.substr(1); + if (eventData.phase === 'before' && typeof this[funName] === 'function') { + fun = this[funName]; + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, eventData.target, eventData); // old way for back compatibility + } else { + fun.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; // back compatibility eventData.stop === true + } + // item object events + if (eventData.object != null && eventData.phase === 'before' && + typeof eventData.object[funName] === 'function') + { + fun = eventData.object[funName]; + // check handler arguments + args = []; + tmp = RegExp(/\((.*?)\)/).exec(fun); + if (tmp) args = tmp[1].split(/\s*,\s*/); + if (args.length === 2) { + fun.call(this, eventData.target, eventData); // old way for back compatibility + } else { + fun.call(this, eventData); // new way + } + if (eventData.isStopped === true || eventData.stop === true) return eventData; + } + // execute onComplete + if (eventData.phase === 'after' && typeof eventData.onComplete === 'function') eventData.onComplete.call(this, eventData); + + return eventData; + } }; /*********************************************************** @@ -982,52 +982,52 @@ w2utils.event = { *********************************************************/ w2utils.keyboard = (function (obj) { - // private scope - var w2ui_name = null; - - obj.active = active; - obj.clear = clear; - obj.register = register; - - init(); - return obj; - - function init() { - $(document).on('keydown', keydown); - $(document).on('mousedown', mousedown); - } - - function keydown (event) { - var tag = event.target.tagName; - if ($.inArray(tag, ['INPUT', 'SELECT', 'TEXTAREA']) !== -1) return; - if ($(event.target).prop('contenteditable') === 'true') return; - if (!w2ui_name) return; - // pass to appropriate widget - if (w2ui[w2ui_name] && typeof w2ui[w2ui_name].keydown === 'function') { - w2ui[w2ui_name].keydown.call(w2ui[w2ui_name], event); - } - } - - function mousedown (event) { - var tag = event.target.tagName; - var obj = $(event.target).parents('.w2ui-reset'); - if (obj.length > 0) { - var name = obj.attr('name'); - if (w2ui[name] && w2ui[name].keyboard) w2ui_name = name; - } - } - - function active (new_w2ui_name) { - if (typeof new_w2ui_name !== 'undefined') w2ui_name = new_w2ui_name; - return w2ui_name; - } - - function clear () { - w2ui_name = null; - } - - function register () { - } + // private scope + var w2ui_name = null; + + obj.active = active; + obj.clear = clear; + obj.register = register; + + init(); + return obj; + + function init() { + $(document).on('keydown', keydown); + $(document).on('mousedown', mousedown); + } + + function keydown (event) { + var tag = event.target.tagName; + if ($.inArray(tag, ['INPUT', 'SELECT', 'TEXTAREA']) !== -1) return; + if ($(event.target).prop('contenteditable') === 'true') return; + if (!w2ui_name) return; + // pass to appropriate widget + if (w2ui[w2ui_name] && typeof w2ui[w2ui_name].keydown === 'function') { + w2ui[w2ui_name].keydown.call(w2ui[w2ui_name], event); + } + } + + function mousedown (event) { + var tag = event.target.tagName; + var obj = $(event.target).parents('.w2ui-reset'); + if (obj.length > 0) { + var name = obj.attr('name'); + if (w2ui[name] && w2ui[name].keyboard) w2ui_name = name; + } + } + + function active (new_w2ui_name) { + if (typeof new_w2ui_name !== 'undefined') w2ui_name = new_w2ui_name; + return w2ui_name; + } + + function clear () { + w2ui_name = null; + } + + function register () { + } })({}); @@ -1039,565 +1039,565 @@ w2utils.keyboard = (function (obj) { (function () { - $.fn.w2render = function (name) { - if ($(this).length > 0) { - if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]); - if (typeof name === 'object') name.render($(this)[0]); - } - }; - - $.fn.w2destroy = function (name) { - if (!name && this.length > 0) name = this.attr('name'); - if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy(); - if (typeof name === 'object') name.destroy(); - }; - - $.fn.w2marker = function (str) { - if (str === '' || str == null) { // remove marker - return $(this).each(function (index, el) { - el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark - }); - } else { // add marker - return $(this).each(function (index, el) { - if (typeof str === 'string') str = [str]; - el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark - for (var s in str) { - var tmp = str[s]; - if (typeof tmp !== 'string') tmp = String(tmp); - // escape regex special chars - tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&').replace(//g, '<'); - var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags - el.innerHTML = el.innerHTML.replace(regex, replaceValue); - } - function replaceValue(matched) { // mark new - return '' + matched + ''; - } - }); - } - }; - - // -- w2tag - appears on the right side from element, there can be multiple on screen at a time - - $.fn.w2tag = function (text, options) { - if (!$.isPlainObject(options)) options = {}; - if (!$.isPlainObject(options.css)) options.css = {}; - if (typeof options['class'] === 'undefined') options['class'] = ''; - // remove all tags - if ($(this).length === 0) { - $('.w2ui-tag').each(function (index, elem) { - var opt = $(elem).data('options'); - if (opt == null) opt = {}; - $($(elem).data('taged-el')).removeClass( opt['class'] ); - clearInterval($(elem).data('timer')); - $(elem).remove(); - }); - return; - } - return $(this).each(function (index, el) { - // show or hide tag - var tagOrigID = el.id; - var tagID = w2utils.escapeId(el.id); - if (text === '' || text == null) { - $('#w2ui-tag-'+tagID).css('opacity', 0); - setTimeout(function () { - // remmove element - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - $('#w2ui-tag-'+tagID).remove(); - }, 300); - } else { - // remove elements - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - $('#w2ui-tag-'+tagID).remove(); - // insert - $('body').append( - '
      '); - - var timer = setInterval(function () { - // monitor if destroyed - if ($(el).length === 0 || ($(el).offset().left === 0 && $(el).offset().top === 0)) { - clearInterval($('#w2ui-tag-'+tagID).data('timer')); - tmp_hide(); - return; - } - // monitor if moved - if ($('#w2ui-tag-'+tagID).data('position') !== ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) { - $('#w2ui-tag-'+tagID).css({ - '-webkit-transition': '.2s', - '-moz-transition' : '.2s', - '-ms-transition' : '.2s', - '-o-transition' : '.2s', - left: ($(el).offset().left + el.offsetWidth) + 'px', - top: $(el).offset().top + 'px' - }).data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top); - } - }, 100); - setTimeout(function () { - if (!$(el).offset()) return; - $('#w2ui-tag-'+tagID).css({ - opacity: '1', - left: ($(el).offset().left + el.offsetWidth) + 'px', - top: $(el).offset().top + 'px' - }).html('
      '+ text +'
      ') - .data('text', text) - .data('taged-el', el) - .data('options', options) - .data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) - .data('timer', timer); - $(el).off('keypress', tmp_hide).on('keypress', tmp_hide).off('change', tmp_hide).on('change', tmp_hide) - .css(options.css).addClass(options['class']); - if (typeof options.onShow === 'function') options.onShow(); - }, 1); - var originalCSS = ''; - if ($(el).length > 0) originalCSS = $(el)[0].style.cssText; - // bind event to hide it - function tmp_hide() { - $tag = $('#w2ui-tag-'+tagID); - if ($tag.length <= 0) return; - clearInterval($tag.data('timer')); - $tag.remove(); - $(el).off('keypress', tmp_hide).removeClass(options['class']); - if ($(el).length > 0) $(el)[0].style.cssText = originalCSS; - if (typeof options.onHide === 'function') options.onHide(); - } - } - }); - }; - - // w2overlay - appears under the element, there can be only one at a time - - $.fn.w2overlay = function (html, options) { - var obj = this; - var name = ''; - var defaults = { - name : null, // it not null, then allows multiple concurent overlays - align : 'none', // can be none, left, right, both - left : 0, // offset left - top : 0, // offset top - tipLeft : 30, // tip offset left - width : 0, // fixed width - height : 0, // fixed height - maxWidth : null, // max width if any - maxHeight : null, // max height if any - style : '', // additional style for main div - 'class' : '', // additional class name for main dvi - onShow : null, // event on show - onHide : null, // event on hide - openAbove : false, // show abover control - tmp : {} - }; - if (!$.isPlainObject(options)) options = {}; - options = $.extend({}, defaults, options); - if (options.name) name = '-' + options.name; - // if empty then hide - var tmp_hide; - if (this.length === 0 || html === '' || html == null) { - if ($('#w2ui-overlay'+ name).length > 0) { - tmp_hide = $('#w2ui-overlay'+ name)[0].hide; - if (typeof tmp_hide === 'function') tmp_hide(); - } else { - $('#w2ui-overlay'+ name).remove(); - } - return $(this); - } - if ($('#w2ui-overlay'+ name).length > 0) { - tmp_hide = $('#w2ui-overlay'+ name)[0].hide; - $(document).off('click', tmp_hide); - if (typeof tmp_hide === 'function') tmp_hide(); - } - $('body').append( - '' - ); - // init - var div1 = $('#w2ui-overlay'+ name); - var div2 = div1.find(' > div'); - div2.html(html); - // pick bg color of first div - var bc = div2.css('background-color'); - if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css('background-color', bc); - - div1.data('element', obj.length > 0 ? obj[0] : null) - .data('options', options) - .data('position', $(obj).offset().left + 'x' + $(obj).offset().top) - .fadeIn('fast').on('mousedown', function (event) { - $('#w2ui-overlay'+ name).data('keepOpen', true); - if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName) === -1) event.preventDefault(); - }); - div1[0].hide = hide; - div1[0].resize = resize; - - // need time to display - resize(); - setTimeout(function () { - resize(); - $(document).off('click', hide).on('click', hide); - if (typeof options.onShow === 'function') options.onShow(); - }, 10); - - monitor(); - return $(this); - - // monitor position - function monitor() { - var tmp = $('#w2ui-overlay'+ name); - if (tmp.data('element') !== obj[0]) return; // it if it different overlay - if (tmp.length === 0) return; - var pos = $(obj).offset().left + 'x' + $(obj).offset().top; - if (tmp.data('position') !== pos) { - hide(); - } else { - setTimeout(monitor, 250); - } - } - - // click anywhere else hides the drop down - function hide () { - var div1 = $('#w2ui-overlay'+ name); - if (div1.data('keepOpen') === true) { - div1.removeData('keepOpen'); - return; - } - var result; - if (typeof options.onHide === 'function') result = options.onHide(); - if (result === false) return; - div1.remove(); - $(document).off('click', hide); - clearInterval(div1.data('timer')); - } - - function resize () { - var div1 = $('#w2ui-overlay'+ name); - var div2 = div1.find(' > div'); - // if goes over the screen, limit height and width - if (div1.length > 0) { - div2.height('auto').width('auto'); - // width/height - var overflowX = false; - var overflowY = false; - var h = div2.height(); - var w = div2.width(); - if (options.width && options.width < w) w = options.width; - if (w < 30) w = 30; - // if content of specific height - if (options.tmp.contentHeight) { - h = options.tmp.contentHeight; - div2.height(h); - setTimeout(function () { - if (div2.height() > div2.find('div.menu > table').height()) { - div2.find('div.menu').css('overflow-y', 'hidden'); - } - }, 1); - setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); - } - if (options.tmp.contentWidth) { - w = options.tmp.contentWidth; - div2.width(w); - setTimeout(function () { - if (div2.width() > div2.find('div.menu > table').width()) { - div2.find('div.menu').css('overflow-x', 'hidden'); - } - }, 1); - setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); - } - // alignment - switch (options.align) { - case 'both': - options.left = 17; - if (options.width === 0) options.width = w2utils.getSize($(obj), 'width'); - break; - case 'left': - options.left = 17; - break; - case 'right': - options.tipLeft = w - 45; - options.left = w2utils.getSize($(obj), 'width') - w + 10; - break; - } - // adjust position - var tmp = (w - 17) / 2; - var boxLeft = options.left; - var boxWidth = options.width; - var tipLeft = options.tipLeft; - if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto'); - if (tmp < 25) { - boxLeft = 25 - tmp; - tipLeft = Math.floor(tmp); - } - // Y coord - div1.css({ - top : (obj.offset().top + w2utils.getSize(obj, 'height') + options.top + 7) + 'px', - left : ((obj.offset().left > 25 ? obj.offset().left : 25) + boxLeft) + 'px', - 'min-width' : boxWidth, - 'min-height': (options.height ? options.height : 'auto') - }); - // $(window).height() - has a problem in FF20 - var maxHeight = window.innerHeight + $(document).scrollTop() - div2.offset().top - 7; - var maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; - if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) { - // show on top - maxHeight = div2.offset().top - $(document).scrollTop() - 7; - if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; - if (h > maxHeight) { - overflowY = true; - div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); - h = maxHeight; - } - div1.css('top', ($(obj).offset().top - h - 24 + options.top) + 'px'); - div1.find('>style').html( - '#w2ui-overlay'+ name +':before { display: none; margin-left: '+ parseInt(tipLeft) +'px; }'+ - '#w2ui-overlay'+ name +':after { display: block; margin-left: '+ parseInt(tipLeft) +'px; }' - ); - } else { - // show under - if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; - if (h > maxHeight) { - overflowY = true; - div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); - } - div1.find('>style').html( - '#w2ui-overlay'+ name +':before { display: block; margin-left: '+ parseInt(tipLeft) +'px; }'+ - '#w2ui-overlay'+ name +':after { display: none; margin-left: '+ parseInt(tipLeft) +'px; }' - ); - } - // check width - w = div2.width(); - maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; - if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth; - if (w > maxWidth && options.align !== 'both') { - options.align = 'right'; - setTimeout(function () { resize(); }, 1); - } - // check scroll bar - if (overflowY && overflowX) div2.width(w + w2utils.scrollBarSize() + 2); - } - } - }; - - $.fn.w2menu = function (menu, options) { - /* - ITEM STRUCTURE - item : { - id : null, - text : '', - style : '', - hidden : true - ... - } - */ - var defaults = { - index : null, // current selected - items : [], - render : null, - msgNoItems : 'No items', - onSelect : null, - tmp : {} - }; - var obj = this; - var name = ''; - if (menu === 'refresh') { - // if not show - call blur - if ($('#w2ui-overlay'+ name).length > 0) { - options = $.extend($.fn.w2menuOptions, options); - var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); - $('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML()); - $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); - mresize(); - } else { - $(this).w2menu(options); - } - } else { - if (arguments.length === 1) options = menu; else options.items = menu; - if (typeof options !== 'object') options = {}; - options = $.extend({}, defaults, options); - $.fn.w2menuOptions = options; - if (options.name) name = '-' + options.name; - if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select; - if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender; - // since only one overlay can exist at a time - $.fn.w2menuHandler = function (event, index) { - if (typeof options.onSelect === 'function') { - // need time so that menu first hides - setTimeout(function () { - options.onSelect({ - index : index, - item : options.items[index], - originalEvent: event - }); - }, 10); - } - }; - var html = ''; - if (options.search) { - html += - '
      '+ - ' '+ - ' '+ - '
      '; - options.style += ';background-color: #ECECEC'; - options.index = 0; - for (var i in options.items) options.items[i].hidden = false; - } - html += ''; - var ret = $(this).w2overlay(html, options); - setTimeout(function () { - $('#w2ui-overlay'+ name +' #menu-search') - .on('keyup', change) - .on('keydown', function (event) { - // cancel tab key - if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); } - }); - }, 200); - mresize(); - return ret; - } - - function mresize() { - setTimeout(function () { - // show selected - $('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected'); - var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']'); - var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); - cur.addClass('w2ui-selected'); - if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10); - if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width(); - $('#w2ui-overlay'+ name)[0].resize(); - // scroll into view - if (cur.length > 0) { - var top = cur[0].offsetTop - 5; // 5 is margin top - var el = $('#w2ui-overlay'+ name +' div.menu'); - var height = el.height(); - $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); - if (top < scrTop || top + cur.height() > scrTop + height) { - $('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); - } - } - }, 1); - } - - function change(event) { - var search = this.value; - var key = event.keyCode; - var cancel = false; - switch (key) { - case 13: // enter - $('#w2ui-overlay'+ name).remove(); - $.fn.w2menuHandler(event, options.index); - break; - case 9: // tab - case 27: // escape - $('#w2ui-overlay'+ name).remove(); - $.fn.w2menuHandler(event, -1); - break; - case 38: // up - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index--; - while (options.index > 0 && options.items[options.index].hidden) options.index--; - if (options.index === 0 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } - if (options.index < 0) options.index = 0; - cancel = true; - break; - case 40: // down - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index++; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (options.index === options.items.length-1 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index--; - } - if (options.index >= options.items.length) options.index = options.items.length - 1; - cancel = true; - break; - } - // filter - if (!cancel) { - var shown = 0; - for (var i in options.items) { - var item = options.items[i]; - var prefix = ''; - var suffix = ''; - if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^'; - if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$'; - try { - var re = new RegExp(prefix + search + suffix, 'i'); - if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true; - if (options.applyFilter !== true) item.hidden = false; - } catch (e) {} - // do not show selected items - if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true; - if (item.hidden !== true) shown++; - } - options.index = 0; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (shown <= 0) options.index = -1; - } - $(obj).w2menu('refresh', options); - mresize(); - } - - function getMenuHTML () { - if (options.spinner) { - return '
      '+ - '
      '+ - '
      Loading...
      '+ - '
      '; - } - var count = 0; - var menu_html = ''; - var img = null, icon = null; - for (var f = 0; f < options.items.length; f++) { - var mitem = options.items[f]; - if (typeof mitem === 'string') { - mitem = { id: mitem, text: mitem }; - } else { - if (mitem.text != null && mitem.id == null) mitem.id = mitem.text; - if (mitem.text == null && mitem.id != null) mitem.text = mitem.id; - if (mitem.caption != null) mitem.text = mitem.caption; - img = mitem.img; - icon = mitem.icon; - if (img == null) img = null; - if (icon == null) icon = null; - } - if (mitem.hidden !== true) { - var imgd = ''; - var txt = mitem.text; - if (typeof options.render === 'function') txt = options.render(mitem, options); - if (img) imgd = ''; - if (icon) imgd = ''; - // render only if non-empty - if (typeof txt !== 'undefined' && txt !== '' && !(/^-+$/.test(txt))) { - var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd'); - if (options.altRows !== true) bg = ''; - menu_html += - ''+ - imgd + - ' '+ - ''; - count++; - } else { - // horizontal line - menu_html += ''; - } - } - options.items[f] = mitem; - } - if (count === 0) { - menu_html += ''; - } - menu_html += "
      '+ txt +'
      '+ options.msgNoItems +'
      "; - return menu_html; - } - }; + $.fn.w2render = function (name) { + if ($(this).length > 0) { + if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]); + if (typeof name === 'object') name.render($(this)[0]); + } + }; + + $.fn.w2destroy = function (name) { + if (!name && this.length > 0) name = this.attr('name'); + if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy(); + if (typeof name === 'object') name.destroy(); + }; + + $.fn.w2marker = function (str) { + if (str === '' || str == null) { // remove marker + return $(this).each(function (index, el) { + el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark + }); + } else { // add marker + return $(this).each(function (index, el) { + if (typeof str === 'string') str = [str]; + el.innerHTML = el.innerHTML.replace(/\(.*)\<\/span\>/ig, '$1'); // unmark + for (var s in str) { + var tmp = str[s]; + if (typeof tmp !== 'string') tmp = String(tmp); + // escape regex special chars + tmp = tmp.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&").replace(/&/g, '&').replace(//g, '<'); + var regex = new RegExp(tmp + '(?!([^<]+)?>)', "gi"); // only outside tags + el.innerHTML = el.innerHTML.replace(regex, replaceValue); + } + function replaceValue(matched) { // mark new + return '' + matched + ''; + } + }); + } + }; + + // -- w2tag - appears on the right side from element, there can be multiple on screen at a time + + $.fn.w2tag = function (text, options) { + if (!$.isPlainObject(options)) options = {}; + if (!$.isPlainObject(options.css)) options.css = {}; + if (typeof options['class'] === 'undefined') options['class'] = ''; + // remove all tags + if ($(this).length === 0) { + $('.w2ui-tag').each(function (index, elem) { + var opt = $(elem).data('options'); + if (opt == null) opt = {}; + $($(elem).data('taged-el')).removeClass( opt['class'] ); + clearInterval($(elem).data('timer')); + $(elem).remove(); + }); + return; + } + return $(this).each(function (index, el) { + // show or hide tag + var tagOrigID = el.id; + var tagID = w2utils.escapeId(el.id); + if (text === '' || text == null) { + $('#w2ui-tag-'+tagID).css('opacity', 0); + setTimeout(function () { + // remmove element + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + $('#w2ui-tag-'+tagID).remove(); + }, 300); + } else { + // remove elements + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + $('#w2ui-tag-'+tagID).remove(); + // insert + $('body').append( + '
      '); + + var timer = setInterval(function () { + // monitor if destroyed + if ($(el).length === 0 || ($(el).offset().left === 0 && $(el).offset().top === 0)) { + clearInterval($('#w2ui-tag-'+tagID).data('timer')); + tmp_hide(); + return; + } + // monitor if moved + if ($('#w2ui-tag-'+tagID).data('position') !== ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) { + $('#w2ui-tag-'+tagID).css({ + '-webkit-transition' : '.2s', + '-moz-transition' : '.2s', + '-ms-transition' : '.2s', + '-o-transition' : '.2s', + left: ($(el).offset().left + el.offsetWidth) + 'px', + top: $(el).offset().top + 'px' + }).data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top); + } + }, 100); + setTimeout(function () { + if (!$(el).offset()) return; + $('#w2ui-tag-'+tagID).css({ + opacity: '1', + left: ($(el).offset().left + el.offsetWidth) + 'px', + top: $(el).offset().top + 'px' + }).html('
      '+ text +'
      ') + .data('text', text) + .data('taged-el', el) + .data('options', options) + .data('position', ($(el).offset().left + el.offsetWidth) + 'x' + $(el).offset().top) + .data('timer', timer); + $(el).off('keypress', tmp_hide).on('keypress', tmp_hide).off('change', tmp_hide).on('change', tmp_hide) + .css(options.css).addClass(options['class']); + if (typeof options.onShow === 'function') options.onShow(); + }, 1); + var originalCSS = ''; + if ($(el).length > 0) originalCSS = $(el)[0].style.cssText; + // bind event to hide it + function tmp_hide() { + $tag = $('#w2ui-tag-'+tagID); + if ($tag.length <= 0) return; + clearInterval($tag.data('timer')); + $tag.remove(); + $(el).off('keypress', tmp_hide).removeClass(options['class']); + if ($(el).length > 0) $(el)[0].style.cssText = originalCSS; + if (typeof options.onHide === 'function') options.onHide(); + } + } + }); + }; + + // w2overlay - appears under the element, there can be only one at a time + + $.fn.w2overlay = function (html, options) { + var obj = this; + var name = ''; + var defaults = { + name : null, // it not null, then allows multiple concurent overlays + align : 'none', // can be none, left, right, both + left : 0, // offset left + top : 0, // offset top + tipLeft : 30, // tip offset left + width : 0, // fixed width + height : 0, // fixed height + maxWidth : null, // max width if any + maxHeight : null, // max height if any + style : '', // additional style for main div + 'class' : '', // additional class name for main dvi + onShow : null, // event on show + onHide : null, // event on hide + openAbove : false, // show abover control + tmp : {} + }; + if (!$.isPlainObject(options)) options = {}; + options = $.extend({}, defaults, options); + if (options.name) name = '-' + options.name; + // if empty then hide + var tmp_hide; + if (this.length === 0 || html === '' || html == null) { + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + if (typeof tmp_hide === 'function') tmp_hide(); + } else { + $('#w2ui-overlay'+ name).remove(); + } + return $(this); + } + if ($('#w2ui-overlay'+ name).length > 0) { + tmp_hide = $('#w2ui-overlay'+ name)[0].hide; + $(document).off('click', tmp_hide); + if (typeof tmp_hide === 'function') tmp_hide(); + } + $('body').append( + '' + ); + // init + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + div2.html(html); + // pick bg color of first div + var bc = div2.css('background-color'); + if (bc != null && bc !== 'rgba(0, 0, 0, 0)' && bc !== 'transparent') div1.css('background-color', bc); + + div1.data('element', obj.length > 0 ? obj[0] : null) + .data('options', options) + .data('position', $(obj).offset().left + 'x' + $(obj).offset().top) + .fadeIn('fast').on('mousedown', function (event) { + $('#w2ui-overlay'+ name).data('keepOpen', true); + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName) === -1) event.preventDefault(); + }); + div1[0].hide = hide; + div1[0].resize = resize; + + // need time to display + resize(); + setTimeout(function () { + resize(); + $(document).off('click', hide).on('click', hide); + if (typeof options.onShow === 'function') options.onShow(); + }, 10); + + monitor(); + return $(this); + + // monitor position + function monitor() { + var tmp = $('#w2ui-overlay'+ name); + if (tmp.data('element') !== obj[0]) return; // it if it different overlay + if (tmp.length === 0) return; + var pos = $(obj).offset().left + 'x' + $(obj).offset().top; + if (tmp.data('position') !== pos) { + hide(); + } else { + setTimeout(monitor, 250); + } + } + + // click anywhere else hides the drop down + function hide () { + var div1 = $('#w2ui-overlay'+ name); + if (div1.data('keepOpen') === true) { + div1.removeData('keepOpen'); + return; + } + var result; + if (typeof options.onHide === 'function') result = options.onHide(); + if (result === false) return; + div1.remove(); + $(document).off('click', hide); + clearInterval(div1.data('timer')); + } + + function resize () { + var div1 = $('#w2ui-overlay'+ name); + var div2 = div1.find(' > div'); + // if goes over the screen, limit height and width + if (div1.length > 0) { + div2.height('auto').width('auto'); + // width/height + var overflowX = false; + var overflowY = false; + var h = div2.height(); + var w = div2.width(); + if (options.width && options.width < w) w = options.width; + if (w < 30) w = 30; + // if content of specific height + if (options.tmp.contentHeight) { + h = options.tmp.contentHeight; + div2.height(h); + setTimeout(function () { + if (div2.height() > div2.find('div.menu > table').height()) { + div2.find('div.menu').css('overflow-y', 'hidden'); + } + }, 1); + setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); + } + if (options.tmp.contentWidth) { + w = options.tmp.contentWidth; + div2.width(w); + setTimeout(function () { + if (div2.width() > div2.find('div.menu > table').width()) { + div2.find('div.menu').css('overflow-x', 'hidden'); + } + }, 1); + setTimeout(function () { div2.find('div.menu').css('overflow-y', 'auto'); }, 10); + } + // alignment + switch (options.align) { + case 'both': + options.left = 17; + if (options.width === 0) options.width = w2utils.getSize($(obj), 'width'); + break; + case 'left': + options.left = 17; + break; + case 'right': + options.tipLeft = w - 45; + options.left = w2utils.getSize($(obj), 'width') - w + 10; + break; + } + // adjust position + var tmp = (w - 17) / 2; + var boxLeft = options.left; + var boxWidth = options.width; + var tipLeft = options.tipLeft; + if (w === 30 && !boxWidth) boxWidth = 30; else boxWidth = (options.width ? options.width : 'auto'); + if (tmp < 25) { + boxLeft = 25 - tmp; + tipLeft = Math.floor(tmp); + } + // Y coord + div1.css({ + top : (obj.offset().top + w2utils.getSize(obj, 'height') + options.top + 7) + 'px', + left : ((obj.offset().left > 25 ? obj.offset().left : 25) + boxLeft) + 'px', + 'min-width' : boxWidth, + 'min-height': (options.height ? options.height : 'auto') + }); + // $(window).height() - has a problem in FF20 + var maxHeight = window.innerHeight + $(document).scrollTop() - div2.offset().top - 7; + var maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; + if ((maxHeight > -50 && maxHeight < 210) || options.openAbove === true) { + // show on top + maxHeight = div2.offset().top - $(document).scrollTop() - 7; + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + h = maxHeight; + } + div1.css('top', ($(obj).offset().top - h - 24 + options.top) + 'px'); + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { display: none; margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { display: block; margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } else { + // show under + if (options.maxHeight && maxHeight > options.maxHeight) maxHeight = options.maxHeight; + if (h > maxHeight) { + overflowY = true; + div2.height(maxHeight).width(w).css({ 'overflow-y': 'auto' }); + } + div1.find('>style').html( + '#w2ui-overlay'+ name +':before { display: block; margin-left: '+ parseInt(tipLeft) +'px; }'+ + '#w2ui-overlay'+ name +':after { display: none; margin-left: '+ parseInt(tipLeft) +'px; }' + ); + } + // check width + w = div2.width(); + maxWidth = window.innerWidth + $(document).scrollLeft() - div2.offset().left - 7; + if (options.maxWidth && maxWidth > options.maxWidth) maxWidth = options.maxWidth; + if (w > maxWidth && options.align !== 'both') { + options.align = 'right'; + setTimeout(function () { resize(); }, 1); + } + // check scroll bar + if (overflowY && overflowX) div2.width(w + w2utils.scrollBarSize() + 2); + } + } + }; + + $.fn.w2menu = function (menu, options) { + /* + ITEM STRUCTURE + item : { + id : null, + text : '', + style : '', + hidden : true + ... + } + */ + var defaults = { + index : null, // current selected + items : [], + render : null, + msgNoItems : 'No items', + onSelect : null, + tmp : {} + }; + var obj = this; + var name = ''; + if (menu === 'refresh') { + // if not show - call blur + if ($('#w2ui-overlay'+ name).length > 0) { + options = $.extend($.fn.w2menuOptions, options); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + $('#w2ui-overlay'+ name +' div.menu').html(getMenuHTML()); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + mresize(); + } else { + $(this).w2menu(options); + } + } else { + if (arguments.length === 1) options = menu; else options.items = menu; + if (typeof options !== 'object') options = {}; + options = $.extend({}, defaults, options); + $.fn.w2menuOptions = options; + if (options.name) name = '-' + options.name; + if (typeof options.select === 'function' && typeof options.onSelect !== 'function') options.onSelect = options.select; + if (typeof options.onRender === 'function' && typeof options.render !== 'function') options.render = options.onRender; + // since only one overlay can exist at a time + $.fn.w2menuHandler = function (event, index) { + if (typeof options.onSelect === 'function') { + // need time so that menu first hides + setTimeout(function () { + options.onSelect({ + index : index, + item : options.items[index], + originalEvent: event + }); + }, 10); + } + }; + var html = ''; + if (options.search) { + html += + '
      '+ + ' '+ + ' '+ + '
      '; + options.style += ';background-color: #ECECEC'; + options.index = 0; + for (var i in options.items) options.items[i].hidden = false; + } + html += ''; + var ret = $(this).w2overlay(html, options); + setTimeout(function () { + $('#w2ui-overlay'+ name +' #menu-search') + .on('keyup', change) + .on('keydown', function (event) { + // cancel tab key + if (event.keyCode === 9) { event.stopPropagation(); event.preventDefault(); } + }); + }, 200); + mresize(); + return ret; + } + + function mresize() { + setTimeout(function () { + // show selected + $('#w2ui-overlay'+ name +' tr.w2ui-selected').removeClass('w2ui-selected'); + var cur = $('#w2ui-overlay'+ name +' tr[index='+ options.index +']'); + var scrTop = $('#w2ui-overlay'+ name +' div.menu').scrollTop(); + cur.addClass('w2ui-selected'); + if (options.tmp) options.tmp.contentHeight = $('#w2ui-overlay'+ name +' table').height() + (options.search ? 50 : 10); + if (options.tmp) options.tmp.contentWidth = $('#w2ui-overlay'+ name +' table').width(); + $('#w2ui-overlay'+ name)[0].resize(); + // scroll into view + if (cur.length > 0) { + var top = cur[0].offsetTop - 5; // 5 is margin top + var el = $('#w2ui-overlay'+ name +' div.menu'); + var height = el.height(); + $('#w2ui-overlay'+ name +' div.menu').scrollTop(scrTop); + if (top < scrTop || top + cur.height() > scrTop + height) { + $('#w2ui-overlay'+ name +' div.menu').animate({ 'scrollTop': top - (height - cur.height() * 2) / 2 }, 200, 'linear'); + } + } + }, 1); + } + + function change(event) { + var search = this.value; + var key = event.keyCode; + var cancel = false; + switch (key) { + case 13: // enter + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuHandler(event, options.index); + break; + case 9: // tab + case 27: // escape + $('#w2ui-overlay'+ name).remove(); + $.fn.w2menuHandler(event, -1); + break; + case 38: // up + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index--; + while (options.index > 0 && options.items[options.index].hidden) options.index--; + if (options.index === 0 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index++; + } + if (options.index < 0) options.index = 0; + cancel = true; + break; + case 40: // down + options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; + options.index++; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (options.index === options.items.length-1 && options.items[options.index].hidden) { + while (options.items[options.index] && options.items[options.index].hidden) options.index--; + } + if (options.index >= options.items.length) options.index = options.items.length - 1; + cancel = true; + break; + } + // filter + if (!cancel) { + var shown = 0; + for (var i in options.items) { + var item = options.items[i]; + var prefix = ''; + var suffix = ''; + if (['is', 'begins with'].indexOf(options.match) !== -1) prefix = '^'; + if (['is', 'ends with'].indexOf(options.match) !== -1) suffix = '$'; + try { + var re = new RegExp(prefix + search + suffix, 'i'); + if (re.test(item.text) || item.text === '...') item.hidden = false; else item.hidden = true; + if (options.applyFilter !== true) item.hidden = false; + } catch (e) {} + // do not show selected items + if (obj.type === 'enum' && $.inArray(item.id, ids) !== -1) item.hidden = true; + if (item.hidden !== true) shown++; + } + options.index = 0; + while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; + if (shown <= 0) options.index = -1; + } + $(obj).w2menu('refresh', options); + mresize(); + } + + function getMenuHTML () { + if (options.spinner) { + return '
      '+ + '
      '+ + '
      Loading...
      '+ + '
      '; + } + var count = 0; + var menu_html = ''; + var img = null, icon = null; + for (var f = 0; f < options.items.length; f++) { + var mitem = options.items[f]; + if (typeof mitem === 'string') { + mitem = { id: mitem, text: mitem }; + } else { + if (mitem.text != null && mitem.id == null) mitem.id = mitem.text; + if (mitem.text == null && mitem.id != null) mitem.text = mitem.id; + if (mitem.caption != null) mitem.text = mitem.caption; + img = mitem.img; + icon = mitem.icon; + if (img == null) img = null; + if (icon == null) icon = null; + } + if (mitem.hidden !== true) { + var imgd = ''; + var txt = mitem.text; + if (typeof options.render === 'function') txt = options.render(mitem, options); + if (img) imgd = ''; + if (icon) imgd = ''; + // render only if non-empty + if (typeof txt !== 'undefined' && txt !== '' && !(/^-+$/.test(txt))) { + var bg = (count % 2 === 0 ? 'w2ui-item-even' : 'w2ui-item-odd'); + if (options.altRows !== true) bg = ''; + menu_html += + ''+ + imgd + + ' '+ + ''; + count++; + } else { + // horizontal line + menu_html += ''; + } + } + options.items[f] = mitem; + } + if (count === 0) { + menu_html += ''; + } + menu_html += "
      '+ txt +'
      '+ options.msgNoItems +'
      "; + return menu_html; + } + }; })(); diff --git a/test/data.php b/test/data.php index 753e4ac3d..492bef6f5 100644 --- a/test/data.php +++ b/test/data.php @@ -8,39 +8,39 @@ $db->connect("127.0.0.1", "postgres", "", "postgres", "5432"); // $fname = Array('Vitali', 'Katie', 'John', 'Peter', 'Sue', 'Olivia', 'Thomas', 'Sergei', 'Sue', 'Frank', 'Divia', -// 'Amy', 'Bill', 'Thomas', 'Emma', 'Gloria', 'Jack', 'April', 'Rose'); +// 'Amy', 'Bill', 'Thomas', 'Emma', 'Gloria', 'Jack', 'April', 'Rose'); // $lname = Array('Peterson', 'Rene', 'Johnson', 'Petrov', 'Sannikov', 'Ivanov', 'Smirnov', 'Cuban', 'Twist', 'Sidorov', 'Vasiliev', 'Homchan', 'Stalone', -// 'Cruz', 'Mascovits', 'Welldo', 'Duck', 'Green', 'Silver', 'Behe', 'Gould'); +// 'Cruz', 'Mascovits', 'Welldo', 'Duck', 'Green', 'Silver', 'Behe', 'Gould'); // for ($i=1; $i<=0; $i++) { -// $fname1 = $fname[rand(0, count($fname)-1)]; -// $lname1 = $lname[rand(0, count($lname)-1)]; -// $sql = "INSERT INTO people (fname, lname, email, manager) -// VALUES('".$fname1."', -// '".$lname1."', -// '".strtolower(substr($fname1, 0, 1).$lname1)."@mail.com', -// '".$lname[rand(0, count($lname)-1)]."')"; -// $db->execute($sql); -// if ($i % 100 == 0) { print("*"); ob_flush(); flush(); } +// $fname1 = $fname[rand(0, count($fname)-1)]; +// $lname1 = $lname[rand(0, count($lname)-1)]; +// $sql = "INSERT INTO people (fname, lname, email, manager) +// VALUES('".$fname1."', +// '".$lname1."', +// '".strtolower(substr($fname1, 0, 1).$lname1)."@mail.com', +// '".$lname[rand(0, count($lname)-1)]."')"; +// $db->execute($sql); +// if ($i % 100 == 0) { print("*"); ob_flush(); flush(); } // } switch ($_REQUEST['name']."::".$_REQUEST['cmd']) { - case 'grid::get-records': - $sql = "SELECT * FROM (SELECT * FROM people ORDER BY OID LIMIT 224) as sub - WHERE ~search~ ORDER BY ~sort~"; - $res = $w2grid->getRecords($sql, null, $_REQUEST); - $w2grid->outputJSON($res); - break; - - default: - $res = Array(); - $res['status'] = 'error'; - $res['message'] = 'Command "'.$_REQUEST['cmd'].'" is not recognized.'; - $res['postData']= $_REQUEST; - $w2grid->outputJSON($res); - break; + case 'grid::get-records': + $sql = "SELECT * FROM (SELECT * FROM people ORDER BY OID LIMIT 224) as sub + WHERE ~search~ ORDER BY ~sort~"; + $res = $w2grid->getRecords($sql, null, $_REQUEST); + $w2grid->outputJSON($res); + break; + + default: + $res = Array(); + $res['status'] = 'error'; + $res['message'] = 'Command "'.$_REQUEST['cmd'].'" is not recognized.'; + $res['postData']= $_REQUEST; + $w2grid->outputJSON($res); + break; } ?> \ No newline at end of file diff --git a/test/fields-old.html b/test/fields-old.html index 173ad13a2..27345aac1 100644 --- a/test/fields-old.html +++ b/test/fields-old.html @@ -4,19 +4,19 @@ -
      - -
      - -
      - -
      +
      + +
      + +
      + +
      \ No newline at end of file diff --git a/test/fields.html b/test/fields.html index 31b5acef4..6f9ccb6c0 100644 --- a/test/fields.html +++ b/test/fields.html @@ -6,277 +6,277 @@ - - Date Range: - - - - -
      -
      -
      -
      text:
      -
      - -
      -
      color:
      -
      - -
      -
      textarea:
      -
      - -
      -
      int:
      -
      - -
      -
      float:
      -
      - -
      -
      percent:
      -
      - -
      -
      money:
      -
      - -
      -
      hex:
      -
      - -
      -
      alpha-numeric:
      -
      - -
      -
      date:
      -
      - -
      -
      time:
      -
      - -
      -
      combo:
      -
      - -
      -
      list:
      -
      - -
      -
      enum:
      -
      - -
      -
      file:
      -
      - -
      -
      + + Date Range: - - + + +
      +
      +
      +
      text:
      +
      + +
      +
      color:
      +
      + +
      +
      textarea:
      +
      + +
      +
      int:
      +
      + +
      +
      float:
      +
      + +
      +
      percent:
      +
      + +
      +
      money:
      +
      + +
      +
      hex:
      +
      + +
      +
      alpha-numeric:
      +
      + +
      +
      date:
      +
      + +
      +
      time:
      +
      + +
      +
      combo:
      +
      + +
      +
      list:
      +
      + +
      +
      enum:
      +
      + +
      +
      file:
      +
      + +
      +
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      text:
      textarea:
      int:
      float:
      money:
      hex:
      alphanumeric:
      date:
      date2:
      list:
      enum:
      file:
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      text:
      textarea:
      int:
      float:
      money:
      hex:
      alphanumeric:
      date:
      date2:
      list:
      enum:
      file:
      diff --git a/test/form-old.html b/test/form-old.html index c70df4cf7..c416b70b2 100644 --- a/test/form-old.html +++ b/test/form-old.html @@ -4,117 +4,117 @@ -
      -
      -
      -
      Text:
      -
      - -
      -
      Text (alpha-numeric):
      -
      - -
      -
      Number (int):
      -
      - -
      -
      Number (float):
      -
      - -
      -
      -
      Date:
      -
      - -
      -
      List:
      -
      - -
      -
      Multi Select:
      -
      - -
      -
      Text Area:
      -
      - -
      -
      +
      +
      +
      +
      Text:
      +
      + +
      +
      Text (alpha-numeric):
      +
      + +
      +
      Number (int):
      +
      + +
      +
      Number (float):
      +
      + +
      +
      +
      Date:
      +
      + +
      +
      List:
      +
      + +
      +
      Multi Select:
      +
      + +
      +
      Text Area:
      +
      + +
      +
      -
      -
      Text:
      -
      - -
      -
      Text:
      -
      - -
      -
      Text:
      -
      - -
      -
      Text:
      -
      - -
      -
      +
      +
      Text:
      +
      + +
      +
      Text:
      +
      + +
      +
      Text:
      +
      + +
      +
      Text:
      +
      + +
      +
      -
      - - -
      -
      +
      + + +
      +
      \ No newline at end of file diff --git a/test/form-template.html b/test/form-template.html index 2cd02c1b2..69705dc20 100644 --- a/test/form-template.html +++ b/test/form-template.html @@ -1,70 +1,70 @@
      -
      -
      Text:
      -
      - -
      -
      Text (alpha-numeric):
      -
      - -
      -
      Number (int):
      -
      - -
      -
      Number (float):
      -
      - -
      -
      -
      -
      Date:
      -
      - -
      -
      List:
      -
      - -
      -
      List2:
      -
      - -
      -
      -
      Files:
      -
      - -
      -
      Multi Select:
      -
      - -
      -
      Text Area:
      -
      - -
      +
      +
      Text:
      +
      + +
      +
      Text (alpha-numeric):
      +
      + +
      +
      Number (int):
      +
      + +
      +
      Number (float):
      +
      + +
      +
      +
      +
      Date:
      +
      + +
      +
      List:
      +
      + +
      +
      List2:
      +
      + +
      +
      +
      Files:
      +
      + +
      +
      Multi Select:
      +
      + +
      +
      Text Area:
      +
      + +
      -
      Text:
      -
      - -
      -
      Text:
      -
      - -
      -
      Text:
      -
      - -
      -
      Text:
      -
      - -
      +
      Text:
      +
      + +
      +
      Text:
      +
      + +
      +
      Text:
      +
      + +
      +
      Text:
      +
      + +
      - - + +
      \ No newline at end of file diff --git a/test/form.html b/test/form.html index 042e87b1c..277214054 100755 --- a/test/form.html +++ b/test/form.html @@ -9,272 +9,272 @@ - -
      -
      -
      - Fields with overlays -
      -
      -
      Text:
      -
      - -
      -
      Text Area:
      -
      - -
      -
      Date:
      -
      - -
      -
      Time:
      -
      - -
      -
      Color:
      -
      - -
      -
      List:
      -
      - -
      -
      Combo:
      -
      - (from url) -
      -
      -
      - Enum and file -
      -
      -
      Enum:
      -
      - -
      -
      Files:
      -
      - -
      -
      -
      + +
      +
      +
      + Fields with overlays +
      +
      +
      Text:
      +
      + +
      +
      Text Area:
      +
      + +
      +
      Date:
      +
      + +
      +
      Time:
      +
      + +
      +
      Color:
      +
      + +
      +
      List:
      +
      + +
      +
      Combo:
      +
      + (from url) +
      +
      +
      + Enum and file +
      +
      +
      Enum:
      +
      + +
      +
      Files:
      +
      + +
      +
      +
      -
      -
      - Date/Time fields -
      -
      -
      Email:
      -
      - -
      -
      Password:
      -
      - -
      -
      Number (int):
      -
      - -
      -
      Number (float):
      -
      - -
      -
      Money:
      -
      - -
      -
      Currency:
      -
      - -
      -
      Percent:
      -
      - -
      -
      Alpha-Numeric:
      -
      - -
      -
      -
      +
      +
      + Date/Time fields +
      +
      +
      Email:
      +
      + +
      +
      Password:
      +
      + +
      +
      Number (int):
      +
      + +
      +
      Number (float):
      +
      + +
      +
      Money:
      +
      + +
      +
      Currency:
      +
      + +
      +
      Percent:
      +
      + +
      +
      Alpha-Numeric:
      +
      + +
      +
      +
      -
      -
      - Standard HTML fields -
      -
      -
      Select:
      -
      - -
      -
      Check:
      -
      - -
      -
      Radio:
      -
      - -
      - -
      - -
      -
      -
      +
      +
      + Standard HTML fields +
      +
      +
      Select:
      +
      + +
      +
      Check:
      +
      + +
      +
      Radio:
      +
      + +
      + +
      + +
      +
      +
      -
      - - -
      -
      +
      + + +
      +
      \ No newline at end of file diff --git a/test/form.php b/test/form.php index 2ad96f1a9..e9e6075ee 100644 --- a/test/form.php +++ b/test/form.php @@ -1,18 +1,18 @@ - { - "status": "error1", - "message": "who cares", - "record": { - "field.date" : "2013-3-15", - "field.list" : "0", - "field.list0" : "Adams, John", - "field.text" : "1", - "field.alpha" : "2", - "field.int" : "3", - "field.float" : "4", - "field.enum" : [ - { id: 1, text: "Adams, John" }, - { id: "Cruz, Steve", text: "Cruz, Steve" }, - { id: "Lewis, Frank", text: "Lewis, Frank" } + { + "status": "error1", + "message": "who cares", + "record": { + "field.date" : "2013-3-15", + "field.list" : "0", + "field.list0" : "Adams, John", + "field.text" : "1", + "field.alpha" : "2", + "field.int" : "3", + "field.float" : "4", + "field.enum" : [ + { id: 1, text: "Adams, John" }, + { id: "Cruz, Steve", text: "Cruz, Steve" }, + { id: "Lewis, Frank", text: "Lewis, Frank" } ] - } - } + } + } diff --git a/test/form2.html b/test/form2.html index ab2ea7b56..05e270f6f 100644 --- a/test/form2.html +++ b/test/form2.html @@ -9,73 +9,73 @@ -
      +
      \ No newline at end of file diff --git a/test/grid-old.html b/test/grid-old.html index 6b94111d8..4c1151c04 100644 --- a/test/grid-old.html +++ b/test/grid-old.html @@ -6,82 +6,82 @@ -
      - +
      + diff --git a/test/grid-stop-request.html b/test/grid-stop-request.html index 57a49d81a..c54fa617e 100644 --- a/test/grid-stop-request.html +++ b/test/grid-stop-request.html @@ -9,9 +9,9 @@ -
      - +
      + diff --git a/test/grid.html b/test/grid.html index d775a25a1..5b06e3024 100644 --- a/test/grid.html +++ b/test/grid.html @@ -12,214 +12,214 @@ -
      -
      - - - - - - -
      -
      +
      +
      + + + + + + +
      +
      diff --git a/test/grid.json b/test/grid.json index 0d7d3ffbd..03980f35b 100644 --- a/test/grid.json +++ b/test/grid.json @@ -1,24 +1,24 @@ { - "status" : "success", - "total" : 18, - "records" : [ - { "recid": 1, "person": { "fname": "John", "lname": "Duran" }, "text": "Some long text that might not be long", "email": "vitali@gmail.com", "sdate": "1/3/2012" }, - { "recid": "2 3", "person": { "fname": "Stuart", "lname": "Motzart" }, "text": "Some long text that might or might not be long", "email": "jdoe@gmail.com", "sdate": "2/4/2012" }, - { "recid": "3.1", "person": { "fname": "Jin", "lname": "Franson" }, "email": "jdoe@gmail.com", "sdate": "4/23/2012" }, - { "recid": "4-1", "person": { "fname": "Susan", "lname": "Ottie" }, "email": "jdoe@gmail.com", "sdate": "5/3/2012" }, - { "recid": "#5", "person": { "fname": "Kelly", "lname": "Silver" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, - { "recid": "6>", "person": { "fname": "Francis", "lname": "Gatos" }, "email": "vitali@gmail.com", "sdate": "2/5/2012" }, - { "recid": "[7]", "person": { "fname": "Mark", "lname": "Welldo" }, "text": "Some long text", "email": "jdoe@gmail.com", "sdate": "8/25/2012" }, - { "recid": "8<", "person": { "fname": "Thomas", "lname": "Bahh" }, "email": "jdoe@gmail.com", "sdate": "9/3/2012" }, - { "recid": "9", "person": { "fname": "Sergei", "lname": "Rachmaninov" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, - { "recid": "!20", "person": { "fname": "Jill", "lname": "Doe" }, "email": "jdoe@gmail.com", "sdate": "10/3/2012" }, - { "recid": "@21", "person": { "fname": "Frank", "lname": "Motzart" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, - { "recid": "$22", "person": { "fname": "Peter", "lname": "Franson" }, "email": "vitali@gmail.com", "sdate": "4/3/2012" }, - { "recid": 23, "person": { "fname": "Andrew", "lname": "Ottie" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, - { "recid": 24, "person": { "fname": "Manny", "lname": "Silver" }, "email": "jim@gmail.com", "sdate": "12/3/2012" }, - { "recid": 25, "person": { "fname": "Ben", "lname": "Gatos" }, "email": "jim@gmail.com", "sdate": "4/3/2012" }, - { "recid": 26, "person": { "fname": "Doer", "lname": "Welldo" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, - { "recid": 27, "person": { "fname": "Shashi", "lname": "bahh" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012", "summary": true }, - { "recid": 28, "person": { "fname": "Av", "lname": "Rachmaninov" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012", "summary": true } - ] + "status" : "success", + "total" : 18, + "records" : [ + { "recid": 1, "person": { "fname": "John", "lname": "Duran" }, "text": "Some long text that might not be long", "email": "vitali@gmail.com", "sdate": "1/3/2012" }, + { "recid": "2 3", "person": { "fname": "Stuart", "lname": "Motzart" }, "text": "Some long text that might or might not be long", "email": "jdoe@gmail.com", "sdate": "2/4/2012" }, + { "recid": "3.1", "person": { "fname": "Jin", "lname": "Franson" }, "email": "jdoe@gmail.com", "sdate": "4/23/2012" }, + { "recid": "4-1", "person": { "fname": "Susan", "lname": "Ottie" }, "email": "jdoe@gmail.com", "sdate": "5/3/2012" }, + { "recid": "#5", "person": { "fname": "Kelly", "lname": "Silver" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, + { "recid": "6>", "person": { "fname": "Francis", "lname": "Gatos" }, "email": "vitali@gmail.com", "sdate": "2/5/2012" }, + { "recid": "[7]", "person": { "fname": "Mark", "lname": "Welldo" }, "text": "Some long text", "email": "jdoe@gmail.com", "sdate": "8/25/2012" }, + { "recid": "8<", "person": { "fname": "Thomas", "lname": "Bahh" }, "email": "jdoe@gmail.com", "sdate": "9/3/2012" }, + { "recid": "9", "person": { "fname": "Sergei", "lname": "Rachmaninov" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, + { "recid": "!20", "person": { "fname": "Jill", "lname": "Doe" }, "email": "jdoe@gmail.com", "sdate": "10/3/2012" }, + { "recid": "@21", "person": { "fname": "Frank", "lname": "Motzart" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, + { "recid": "$22", "person": { "fname": "Peter", "lname": "Franson" }, "email": "vitali@gmail.com", "sdate": "4/3/2012" }, + { "recid": 23, "person": { "fname": "Andrew", "lname": "Ottie" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, + { "recid": 24, "person": { "fname": "Manny", "lname": "Silver" }, "email": "jim@gmail.com", "sdate": "12/3/2012" }, + { "recid": 25, "person": { "fname": "Ben", "lname": "Gatos" }, "email": "jim@gmail.com", "sdate": "4/3/2012" }, + { "recid": 26, "person": { "fname": "Doer", "lname": "Welldo" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012" }, + { "recid": 27, "person": { "fname": "Shashi", "lname": "bahh" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012", "summary": true }, + { "recid": 28, "person": { "fname": "Av", "lname": "Rachmaninov" }, "email": "jdoe@gmail.com", "sdate": "4/3/2012", "summary": true } + ] } \ No newline at end of file diff --git a/test/grid2.html b/test/grid2.html index 6c85a51b3..0a6e0b62c 100644 --- a/test/grid2.html +++ b/test/grid2.html @@ -10,89 +10,89 @@ -
      +
      diff --git a/test/ks.html b/test/ks.html index c10bdc3c4..38c7633f7 100644 --- a/test/ks.html +++ b/test/ks.html @@ -1,13 +1,13 @@ - - - + + + diff --git a/test/ks.js b/test/ks.js deleted file mode 100644 index d8cc566e6..000000000 --- a/test/ks.js +++ /dev/null @@ -1 +0,0 @@ -ks.js \ No newline at end of file diff --git a/test/layout-grid-form.html b/test/layout-grid-form.html index 264f1c4fb..706ff15f1 100644 --- a/test/layout-grid-form.html +++ b/test/layout-grid-form.html @@ -8,123 +8,123 @@ -
      +
      \ No newline at end of file diff --git a/test/layout-old.html b/test/layout-old.html index d2b39889f..665db4ce9 100644 --- a/test/layout-old.html +++ b/test/layout-old.html @@ -5,29 +5,29 @@ -
      +
      \ No newline at end of file diff --git a/test/layout.html b/test/layout.html index d0fa948e8..a76c29c1f 100644 --- a/test/layout.html +++ b/test/layout.html @@ -8,72 +8,72 @@ -
      +
      \ No newline at end of file diff --git a/test/listdat.json b/test/listdat.json index 0d667d35a..1a68dd0cf 100644 --- a/test/listdat.json +++ b/test/listdat.json @@ -1,7 +1,7 @@ { - "status": "success", - "items": [ - { "id": 1, "text": "item 1" }, - { "id": 2, "text": "item 2" } - ] + "status": "success", + "items": [ + { "id": 1, "text": "item 1" }, + { "id": 2, "text": "item 2" } + ] } \ No newline at end of file diff --git a/test/popup-old.html b/test/popup-old.html index cf08e08b8..43480cece 100644 --- a/test/popup-old.html +++ b/test/popup-old.html @@ -1,56 +1,56 @@ - - - + + + - - + + - + - + - + \ No newline at end of file diff --git a/test/popup-template.html b/test/popup-template.html index 12065752f..fb5a25c24 100644 --- a/test/popup-template.html +++ b/test/popup-template.html @@ -4,7 +4,7 @@
      -
      +
      This is body of popup #1. You can put any text or HTML inside the body (as well as title and buttons). This is body of popup #1. You can put any text or HTML inside the body (as well as title and buttons). diff --git a/test/popup.html b/test/popup.html index 306971dcd..02139dd98 100644 --- a/test/popup.html +++ b/test/popup.html @@ -6,97 +6,97 @@ - - - + + + - - + + - + - + - + - + \ No newline at end of file diff --git a/test/qunit/index.html b/test/qunit/index.html index cc46802ca..f77853e63 100644 --- a/test/qunit/index.html +++ b/test/qunit/index.html @@ -1,18 +1,18 @@ - - QUnit Example - - - + + QUnit Example + + + -
      -
      - - - - +
      +
      + + + + \ No newline at end of file diff --git a/test/qunit/index2.html b/test/qunit/index2.html index 17d57dd44..f701a8302 100644 --- a/test/qunit/index2.html +++ b/test/qunit/index2.html @@ -1,19 +1,19 @@ - - QUnit Example - - + + QUnit Example + + -
      -
      - - +
      +
      + + \ No newline at end of file diff --git a/test/qunit/lib/qunit.css b/test/qunit/lib/qunit.css index cb4815b79..6b3fd3d6b 100644 --- a/test/qunit/lib/qunit.css +++ b/test/qunit/lib/qunit.css @@ -11,7 +11,7 @@ /** Font Family and Sizes */ #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { - font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; } #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } @@ -21,147 +21,147 @@ /** Resets */ #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { - margin: 0; - padding: 0; + margin: 0; + padding: 0; } /** Header */ #qunit-header { - padding: 0.5em 0 0.5em 1em; + padding: 0.5em 0 0.5em 1em; - color: #8699a4; - background-color: #0d3349; + color: #8699a4; + background-color: #0d3349; - font-size: 1.5em; - line-height: 1em; - font-weight: normal; + font-size: 1.5em; + line-height: 1em; + font-weight: normal; - border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - -webkit-border-top-right-radius: 5px; - -webkit-border-top-left-radius: 5px; + border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + -webkit-border-top-right-radius: 5px; + -webkit-border-top-left-radius: 5px; } #qunit-header a { - text-decoration: none; - color: #c2ccd1; + text-decoration: none; + color: #c2ccd1; } #qunit-header a:hover, #qunit-header a:focus { - color: #fff; + color: #fff; } #qunit-testrunner-toolbar label { - display: inline-block; - padding: 0 .5em 0 .1em; + display: inline-block; + padding: 0 .5em 0 .1em; } #qunit-banner { - height: 5px; + height: 5px; } #qunit-testrunner-toolbar { - padding: 0.5em 0 0.5em 2em; - color: #5E740B; - background-color: #eee; - overflow: hidden; + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; + overflow: hidden; } #qunit-userAgent { - padding: 0.5em 0 0.5em 2.5em; - background-color: #2b81af; - color: #fff; - text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; } #qunit-modulefilter-container { - float: right; + float: right; } /** Tests: Pass/Fail */ #qunit-tests { - list-style-position: inside; + list-style-position: inside; } #qunit-tests li { - padding: 0.4em 0.5em 0.4em 2.5em; - border-bottom: 1px solid #fff; - list-style-position: inside; + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; } #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { - display: none; + display: none; } #qunit-tests li strong { - cursor: pointer; + cursor: pointer; } #qunit-tests li a { - padding: 0.5em; - color: #c2ccd1; - text-decoration: none; + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; } #qunit-tests li a:hover, #qunit-tests li a:focus { - color: #000; + color: #000; } #qunit-tests li .runtime { - float: right; - font-size: smaller; + float: right; + font-size: smaller; } .qunit-assert-list { - margin-top: 0.5em; - padding: 0.5em; + margin-top: 0.5em; + padding: 0.5em; - background-color: #fff; + background-color: #fff; - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; } .qunit-collapsed { - display: none; + display: none; } #qunit-tests table { - border-collapse: collapse; - margin-top: .2em; + border-collapse: collapse; + margin-top: .2em; } #qunit-tests th { - text-align: right; - vertical-align: top; - padding: 0 .5em 0 0; + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; } #qunit-tests td { - vertical-align: top; + vertical-align: top; } #qunit-tests pre { - margin: 0; - white-space: pre-wrap; - word-wrap: break-word; + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; } #qunit-tests del { - background-color: #e0f2be; - color: #374e0c; - text-decoration: none; + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; } #qunit-tests ins { - background-color: #ffcaca; - color: #500; - text-decoration: none; + background-color: #ffcaca; + color: #500; + text-decoration: none; } /*** Test Counts */ @@ -171,18 +171,18 @@ #qunit-tests b.failed { color: #710909; } #qunit-tests li li { - padding: 5px; - background-color: #fff; - border-bottom: none; - list-style-position: inside; + padding: 5px; + background-color: #fff; + border-bottom: none; + list-style-position: inside; } /*** Passing Styles */ #qunit-tests li li.pass { - color: #3c510c; - background-color: #fff; - border-left: 10px solid #C6E746; + color: #3c510c; + background-color: #fff; + border-left: 10px solid #C6E746; } #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } @@ -196,17 +196,17 @@ /*** Failing Styles */ #qunit-tests li li.fail { - color: #710909; - background-color: #fff; - border-left: 10px solid #EE5757; - white-space: pre; + color: #710909; + background-color: #fff; + border-left: 10px solid #EE5757; + white-space: pre; } #qunit-tests > li:last-child { - border-radius: 0 0 5px 5px; - -moz-border-radius: 0 0 5px 5px; - -webkit-border-bottom-right-radius: 5px; - -webkit-border-bottom-left-radius: 5px; + border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + -webkit-border-bottom-right-radius: 5px; + -webkit-border-bottom-left-radius: 5px; } #qunit-tests .fail { color: #000000; background-color: #EE5757; } @@ -222,23 +222,23 @@ /** Result */ #qunit-testresult { - padding: 0.5em 0.5em 0.5em 2.5em; + padding: 0.5em 0.5em 0.5em 2.5em; - color: #2b81af; - background-color: #D2E0E6; + color: #2b81af; + background-color: #D2E0E6; - border-bottom: 1px solid white; + border-bottom: 1px solid white; } #qunit-testresult .module-name { - font-weight: bold; + font-weight: bold; } /** Fixture */ #qunit-fixture { - position: absolute; - top: -10000px; - left: -10000px; - width: 1000px; - height: 1000px; + position: absolute; + top: -10000px; + left: -10000px; + width: 1000px; + height: 1000px; } \ No newline at end of file diff --git a/test/qunit/lib/qunit.js b/test/qunit/lib/qunit.js index 972941870..c6ddcad84 100644 --- a/test/qunit/lib/qunit.js +++ b/test/qunit/lib/qunit.js @@ -11,479 +11,479 @@ (function( window ) { var QUnit, - assert, - config, - onErrorFnPrev, - testId = 0, - fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - // Keep a local reference to Date (GH-283) - Date = window.Date, - defined = { - setTimeout: typeof window.setTimeout !== "undefined", - sessionStorage: (function() { - var x = "qunit-test-string"; - try { - sessionStorage.setItem( x, x ); - sessionStorage.removeItem( x ); - return true; - } catch( e ) { - return false; - } - }()) - }, - /** - * Provides a normalized error string, correcting an issue - * with IE 7 (and prior) where Error.prototype.toString is - * not properly implemented - * - * Based on http://es5.github.com/#x15.11.4.4 - * - * @param {String|Error} error - * @return {String} error message - */ - errorString = function( error ) { - var name, message, - errorString = error.toString(); - if ( errorString.substring( 0, 7 ) === "[object" ) { - name = error.name ? error.name.toString() : "Error"; - message = error.message ? error.message.toString() : ""; - if ( name && message ) { - return name + ": " + message; - } else if ( name ) { - return name; - } else if ( message ) { - return message; - } else { - return "Error"; - } - } else { - return errorString; - } - }, - /** - * Makes a clone of an object using only Array or Object as base, - * and copies over the own enumerable properties. - * - * @param {Object} obj - * @return {Object} New object with only the own properties (recursively). - */ - objectValues = function( obj ) { - // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. - /*jshint newcap: false */ - var key, val, - vals = QUnit.is( "array", obj ) ? [] : {}; - for ( key in obj ) { - if ( hasOwn.call( obj, key ) ) { - val = obj[key]; - vals[key] = val === Object(val) ? objectValues(val) : val; - } - } - return vals; - }; + assert, + config, + onErrorFnPrev, + testId = 0, + fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + // Keep a local reference to Date (GH-283) + Date = window.Date, + defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + var x = "qunit-test-string"; + try { + sessionStorage.setItem( x, x ); + sessionStorage.removeItem( x ); + return true; + } catch( e ) { + return false; + } + }()) + }, + /** + * Provides a normalized error string, correcting an issue + * with IE 7 (and prior) where Error.prototype.toString is + * not properly implemented + * + * Based on http://es5.github.com/#x15.11.4.4 + * + * @param {String|Error} error + * @return {String} error message + */ + errorString = function( error ) { + var name, message, + errorString = error.toString(); + if ( errorString.substring( 0, 7 ) === "[object" ) { + name = error.name ? error.name.toString() : "Error"; + message = error.message ? error.message.toString() : ""; + if ( name && message ) { + return name + ": " + message; + } else if ( name ) { + return name; + } else if ( message ) { + return message; + } else { + return "Error"; + } + } else { + return errorString; + } + }, + /** + * Makes a clone of an object using only Array or Object as base, + * and copies over the own enumerable properties. + * + * @param {Object} obj + * @return {Object} New object with only the own properties (recursively). + */ + objectValues = function( obj ) { + // Grunt 0.3.x uses an older version of jshint that still has jshint/jshint#392. + /*jshint newcap: false */ + var key, val, + vals = QUnit.is( "array", obj ) ? [] : {}; + for ( key in obj ) { + if ( hasOwn.call( obj, key ) ) { + val = obj[key]; + vals[key] = val === Object(val) ? objectValues(val) : val; + } + } + return vals; + }; function Test( settings ) { - extend( this, settings ); - this.assertions = []; - this.testNumber = ++Test.count; + extend( this, settings ); + this.assertions = []; + this.testNumber = ++Test.count; } Test.count = 0; Test.prototype = { - init: function() { - var a, b, li, - tests = id( "qunit-tests" ); - - if ( tests ) { - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml; - - // `a` initialized at top of scope - a = document.createElement( "a" ); - a.innerHTML = "Rerun"; - a.href = QUnit.url({ testNumber: this.testNumber }); - - li = document.createElement( "li" ); - li.appendChild( b ); - li.appendChild( a ); - li.className = "running"; - li.id = this.id = "qunit-test-output" + testId++; - - tests.appendChild( li ); - } - }, - setup: function() { - if ( this.module !== config.previousModule ) { - if ( config.previousModule ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - config.previousModule = this.module; - config.moduleStats = { all: 0, bad: 0 }; - runLoggingCallbacks( "moduleStart", QUnit, { - name: this.module - }); - } else if ( config.autorun ) { - runLoggingCallbacks( "moduleStart", QUnit, { - name: this.module - }); - } - - config.current = this; - - this.testEnvironment = extend({ - setup: function() {}, - teardown: function() {} - }, this.moduleTestEnvironment ); - - this.started = +new Date(); - runLoggingCallbacks( "testStart", QUnit, { - name: this.testName, - module: this.module - }); - - // allow utility functions to access the current test environment - // TODO why?? - QUnit.current_testEnvironment = this.testEnvironment; - - if ( !config.pollution ) { - saveGlobal(); - } - if ( config.notrycatch ) { - this.testEnvironment.setup.call( this.testEnvironment ); - return; - } - try { - this.testEnvironment.setup.call( this.testEnvironment ); - } catch( e ) { - QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - }, - run: function() { - config.current = this; - - var running = id( "qunit-testresult" ); - - if ( running ) { - running.innerHTML = "Running:
      " + this.nameHtml; - } - - if ( this.async ) { - QUnit.stop(); - } - - this.callbackStarted = +new Date(); - - if ( config.notrycatch ) { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - return; - } - - try { - this.callback.call( this.testEnvironment, QUnit.assert ); - this.callbackRuntime = +new Date() - this.callbackStarted; - } catch( e ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - - QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); - // else next test will carry the responsibility - saveGlobal(); - - // Restart the tests if they're blocking - if ( config.blocking ) { - QUnit.start(); - } - } - }, - teardown: function() { - config.current = this; - if ( config.notrycatch ) { - if ( typeof this.callbackRuntime === "undefined" ) { - this.callbackRuntime = +new Date() - this.callbackStarted; - } - this.testEnvironment.teardown.call( this.testEnvironment ); - return; - } else { - try { - this.testEnvironment.teardown.call( this.testEnvironment ); - } catch( e ) { - QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); - } - } - checkPollution(); - }, - finish: function() { - config.current = this; - if ( config.requireExpects && this.expected === null ) { - QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); - } else if ( this.expected !== null && this.expected !== this.assertions.length ) { - QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); - } else if ( this.expected === null && !this.assertions.length ) { - QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); - } - - var i, assertion, a, b, time, li, ol, - test = this, - good = 0, - bad = 0, - tests = id( "qunit-tests" ); - - this.runtime = +new Date() - this.started; - config.stats.all += this.assertions.length; - config.moduleStats.all += this.assertions.length; - - if ( tests ) { - ol = document.createElement( "ol" ); - ol.className = "qunit-assert-list"; - - for ( i = 0; i < this.assertions.length; i++ ) { - assertion = this.assertions[i]; - - li = document.createElement( "li" ); - li.className = assertion.result ? "pass" : "fail"; - li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); - ol.appendChild( li ); - - if ( assertion.result ) { - good++; - } else { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - - // store result when possible - if ( QUnit.config.reorder && defined.sessionStorage ) { - if ( bad ) { - sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); - } else { - sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); - } - } - - if ( bad === 0 ) { - addClass( ol, "qunit-collapsed" ); - } - - // `b` initialized at top of scope - b = document.createElement( "strong" ); - b.innerHTML = this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; - - addEvent(b, "click", function() { - var next = b.parentNode.lastChild, - collapsed = hasClass( next, "qunit-collapsed" ); - ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); - }); - - addEvent(b, "dblclick", function( e ) { - var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { - target = target.parentNode; - } - if ( window.location && target.nodeName.toLowerCase() === "strong" ) { - window.location = QUnit.url({ testNumber: test.testNumber }); - } - }); - - // `time` initialized at top of scope - time = document.createElement( "span" ); - time.className = "runtime"; - time.innerHTML = this.runtime + " ms"; - - // `li` initialized at top of scope - li = id( this.id ); - li.className = bad ? "fail" : "pass"; - li.removeChild( li.firstChild ); - a = li.firstChild; - li.appendChild( b ); - li.appendChild( a ); - li.appendChild( time ); - li.appendChild( ol ); - - } else { - for ( i = 0; i < this.assertions.length; i++ ) { - if ( !this.assertions[i].result ) { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - } - - runLoggingCallbacks( "testDone", QUnit, { - name: this.testName, - module: this.module, - failed: bad, - passed: this.assertions.length - bad, - total: this.assertions.length, - duration: this.runtime - }); - - QUnit.reset(); - - config.current = undefined; - }, - - queue: function() { - var bad, - test = this; - - synchronize(function() { - test.init(); - }); - function run() { - // each of these can by async - synchronize(function() { - test.setup(); - }); - synchronize(function() { - test.run(); - }); - synchronize(function() { - test.teardown(); - }); - synchronize(function() { - test.finish(); - }); - } - - // `bad` initialized at top of scope - // defer when previous test run passed, if storage is available - bad = QUnit.config.reorder && defined.sessionStorage && - +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); - - if ( bad ) { - run(); - } else { - synchronize( run, true ); - } - } + init: function() { + var a, b, li, + tests = id( "qunit-tests" ); + + if ( tests ) { + b = document.createElement( "strong" ); + b.innerHTML = this.nameHtml; + + // `a` initialized at top of scope + a = document.createElement( "a" ); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ testNumber: this.testNumber }); + + li = document.createElement( "li" ); + li.appendChild( b ); + li.appendChild( a ); + li.className = "running"; + li.id = this.id = "qunit-test-output" + testId++; + + tests.appendChild( li ); + } + }, + setup: function() { + if ( this.module !== config.previousModule ) { + if ( config.previousModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } else if ( config.autorun ) { + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } + + config.current = this; + + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment ); + + this.started = +new Date(); + runLoggingCallbacks( "testStart", QUnit, { + name: this.testName, + module: this.module + }); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + if ( !config.pollution ) { + saveGlobal(); + } + if ( config.notrycatch ) { + this.testEnvironment.setup.call( this.testEnvironment ); + return; + } + try { + this.testEnvironment.setup.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); + } + }, + run: function() { + config.current = this; + + var running = id( "qunit-testresult" ); + + if ( running ) { + running.innerHTML = "Running:
      " + this.nameHtml; + } + + if ( this.async ) { + QUnit.stop(); + } + + this.callbackStarted = +new Date(); + + if ( config.notrycatch ) { + this.callback.call( this.testEnvironment, QUnit.assert ); + this.callbackRuntime = +new Date() - this.callbackStarted; + return; + } + + try { + this.callback.call( this.testEnvironment, QUnit.assert ); + this.callbackRuntime = +new Date() - this.callbackStarted; + } catch( e ) { + this.callbackRuntime = +new Date() - this.callbackStarted; + + QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + QUnit.start(); + } + } + }, + teardown: function() { + config.current = this; + if ( config.notrycatch ) { + if ( typeof this.callbackRuntime === "undefined" ) { + this.callbackRuntime = +new Date() - this.callbackStarted; + } + this.testEnvironment.teardown.call( this.testEnvironment ); + return; + } else { + try { + this.testEnvironment.teardown.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); + } + } + checkPollution(); + }, + finish: function() { + config.current = this; + if ( config.requireExpects && this.expected === null ) { + QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); + } else if ( this.expected !== null && this.expected !== this.assertions.length ) { + QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); + } else if ( this.expected === null && !this.assertions.length ) { + QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); + } + + var i, assertion, a, b, time, li, ol, + test = this, + good = 0, + bad = 0, + tests = id( "qunit-tests" ); + + this.runtime = +new Date() - this.started; + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + ol = document.createElement( "ol" ); + ol.className = "qunit-assert-list"; + + for ( i = 0; i < this.assertions.length; i++ ) { + assertion = this.assertions[i]; + + li = document.createElement( "li" ); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if ( bad ) { + sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); + } else { + sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); + } + } + + if ( bad === 0 ) { + addClass( ol, "qunit-collapsed" ); + } + + // `b` initialized at top of scope + b = document.createElement( "strong" ); + b.innerHTML = this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + addEvent(b, "click", function() { + var next = b.parentNode.lastChild, + collapsed = hasClass( next, "qunit-collapsed" ); + ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); + }); + + addEvent(b, "dblclick", function( e ) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ testNumber: test.testNumber }); + } + }); + + // `time` initialized at top of scope + time = document.createElement( "span" ); + time.className = "runtime"; + time.innerHTML = this.runtime + " ms"; + + // `li` initialized at top of scope + li = id( this.id ); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + a = li.firstChild; + li.appendChild( b ); + li.appendChild( a ); + li.appendChild( time ); + li.appendChild( ol ); + + } else { + for ( i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + runLoggingCallbacks( "testDone", QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length, + duration: this.runtime + }); + + QUnit.reset(); + + config.current = undefined; + }, + + queue: function() { + var bad, + test = this; + + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + + // `bad` initialized at top of scope + // defer when previous test run passed, if storage is available + bad = QUnit.config.reorder && defined.sessionStorage && + +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); + + if ( bad ) { + run(); + } else { + synchronize( run, true ); + } + } }; // Root QUnit object. // `QUnit` initialized at top of scope QUnit = { - // call on start of module test to prepend name to all tests - module: function( name, testEnvironment ) { - config.currentModule = name; - config.currentModuleTestEnvironment = testEnvironment; - config.modules[name] = true; - }, - - asyncTest: function( testName, expected, callback ) { - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - QUnit.test( testName, expected, callback, true ); - }, - - test: function( testName, expected, callback, async ) { - var test, - nameHtml = "" + escapeText( testName ) + ""; - - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - - if ( config.currentModule ) { - nameHtml = "" + escapeText( config.currentModule ) + ": " + nameHtml; - } - - test = new Test({ - nameHtml: nameHtml, - testName: testName, - expected: expected, - async: async, - callback: callback, - module: config.currentModule, - moduleTestEnvironment: config.currentModuleTestEnvironment, - stack: sourceFromStacktrace( 2 ) - }); - - if ( !validTest( test ) ) { - return; - } - - test.queue(); - }, - - // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. - expect: function( asserts ) { - if (arguments.length === 1) { - config.current.expected = asserts; - } else { - return config.current.expected; - } - }, - - start: function( count ) { - // QUnit hasn't been initialized yet. - // Note: RequireJS (et al) may delay onLoad - if ( config.semaphore === undefined ) { - QUnit.begin(function() { - // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first - setTimeout(function() { - QUnit.start( count ); - }); - }); - return; - } - - config.semaphore -= count || 1; - // don't start until equal number of stop-calls - if ( config.semaphore > 0 ) { - return; - } - // ignore if start is called more often then stop - if ( config.semaphore < 0 ) { - config.semaphore = 0; - QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) ); - return; - } - // A slight delay, to avoid any current callbacks - if ( defined.setTimeout ) { - window.setTimeout(function() { - if ( config.semaphore > 0 ) { - return; - } - if ( config.timeout ) { - clearTimeout( config.timeout ); - } - - config.blocking = false; - process( true ); - }, 13); - } else { - config.blocking = false; - process( true ); - } - }, - - stop: function( count ) { - config.semaphore += count || 1; - config.blocking = true; - - if ( config.testTimeout && defined.setTimeout ) { - clearTimeout( config.timeout ); - config.timeout = window.setTimeout(function() { - QUnit.ok( false, "Test timed out" ); - config.semaphore = 1; - QUnit.start(); - }, config.testTimeout ); - } - } + // call on start of module test to prepend name to all tests + module: function( name, testEnvironment ) { + config.currentModule = name; + config.currentModuleTestEnvironment = testEnvironment; + config.modules[name] = true; + }, + + asyncTest: function( testName, expected, callback ) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + QUnit.test( testName, expected, callback, true ); + }, + + test: function( testName, expected, callback, async ) { + var test, + nameHtml = "" + escapeText( testName ) + ""; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + if ( config.currentModule ) { + nameHtml = "" + escapeText( config.currentModule ) + ": " + nameHtml; + } + + test = new Test({ + nameHtml: nameHtml, + testName: testName, + expected: expected, + async: async, + callback: callback, + module: config.currentModule, + moduleTestEnvironment: config.currentModuleTestEnvironment, + stack: sourceFromStacktrace( 2 ) + }); + + if ( !validTest( test ) ) { + return; + } + + test.queue(); + }, + + // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + expect: function( asserts ) { + if (arguments.length === 1) { + config.current.expected = asserts; + } else { + return config.current.expected; + } + }, + + start: function( count ) { + // QUnit hasn't been initialized yet. + // Note: RequireJS (et al) may delay onLoad + if ( config.semaphore === undefined ) { + QUnit.begin(function() { + // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first + setTimeout(function() { + QUnit.start( count ); + }); + }); + return; + } + + config.semaphore -= count || 1; + // don't start until equal number of stop-calls + if ( config.semaphore > 0 ) { + return; + } + // ignore if start is called more often then stop + if ( config.semaphore < 0 ) { + config.semaphore = 0; + QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) ); + return; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if ( config.semaphore > 0 ) { + return; + } + if ( config.timeout ) { + clearTimeout( config.timeout ); + } + + config.blocking = false; + process( true ); + }, 13); + } else { + config.blocking = false; + process( true ); + } + }, + + stop: function( count ) { + config.semaphore += count || 1; + config.blocking = true; + + if ( config.testTimeout && defined.setTimeout ) { + clearTimeout( config.timeout ); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout ); + } + } }; // `assert` initialized at top of scope @@ -494,157 +494,157 @@ QUnit = { // We attach it to the QUnit object *after* we expose the public API, // otherwise `assert` will become a global variable in browsers (#341). assert = { - /** - * Asserts rough true-ish result. - * @name ok - * @function - * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); - */ - ok: function( result, msg ) { - if ( !config.current ) { - throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - result = !!result; - - var source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: msg - }; - - msg = escapeText( msg || (result ? "okay" : "failed" ) ); - msg = "" + msg + ""; - - if ( !result ) { - source = sourceFromStacktrace( 2 ); - if ( source ) { - details.source = source; - msg += "
      Source:
      " + escapeText( source ) + "
      "; - } - } - runLoggingCallbacks( "log", QUnit, details ); - config.current.assertions.push({ - result: result, - message: msg - }); - }, - - /** - * Assert that the first two arguments are equal, with an optional message. - * Prints out both actual and expected values. - * @name equal - * @function - * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); - */ - equal: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected == actual, actual, expected, message ); - }, - - /** - * @name notEqual - * @function - */ - notEqual: function( actual, expected, message ) { - /*jshint eqeqeq:false */ - QUnit.push( expected != actual, actual, expected, message ); - }, - - /** - * @name propEqual - * @function - */ - propEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notPropEqual - * @function - */ - notPropEqual: function( actual, expected, message ) { - actual = objectValues(actual); - expected = objectValues(expected); - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name deepEqual - * @function - */ - deepEqual: function( actual, expected, message ) { - QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name notDeepEqual - * @function - */ - notDeepEqual: function( actual, expected, message ) { - QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); - }, - - /** - * @name strictEqual - * @function - */ - strictEqual: function( actual, expected, message ) { - QUnit.push( expected === actual, actual, expected, message ); - }, - - /** - * @name notStrictEqual - * @function - */ - notStrictEqual: function( actual, expected, message ) { - QUnit.push( expected !== actual, actual, expected, message ); - }, - - "throws": function( block, expected, message ) { - var actual, - expectedOutput = expected, - ok = false; - - // 'expected' is optional - if ( typeof expected === "string" ) { - message = expected; - expected = null; - } - - config.current.ignoreGlobalErrors = true; - try { - block.call( config.current.testEnvironment ); - } catch (e) { - actual = e; - } - config.current.ignoreGlobalErrors = false; - - if ( actual ) { - // we don't want to validate thrown error - if ( !expected ) { - ok = true; - expectedOutput = null; - // expected is a regexp - } else if ( QUnit.objectType( expected ) === "regexp" ) { - ok = expected.test( errorString( actual ) ); - // expected is a constructor - } else if ( actual instanceof expected ) { - ok = true; - // expected is a validation function which returns true is validation passed - } else if ( expected.call( {}, actual ) === true ) { - expectedOutput = null; - ok = true; - } - - QUnit.push( ok, actual, expectedOutput, message ); - } else { - QUnit.pushFailure( message, null, 'No exception was thrown.' ); - } - } + /** + * Asserts rough true-ish result. + * @name ok + * @function + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function( result, msg ) { + if ( !config.current ) { + throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + result = !!result; + + var source, + details = { + module: config.current.module, + name: config.current.testName, + result: result, + message: msg + }; + + msg = escapeText( msg || (result ? "okay" : "failed" ) ); + msg = "" + msg + ""; + + if ( !result ) { + source = sourceFromStacktrace( 2 ); + if ( source ) { + details.source = source; + msg += "
      Source:
      " + escapeText( source ) + "
      "; + } + } + runLoggingCallbacks( "log", QUnit, details ); + config.current.assertions.push({ + result: result, + message: msg + }); + }, + + /** + * Assert that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * @name equal + * @function + * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); + */ + equal: function( actual, expected, message ) { + /*jshint eqeqeq:false */ + QUnit.push( expected == actual, actual, expected, message ); + }, + + /** + * @name notEqual + * @function + */ + notEqual: function( actual, expected, message ) { + /*jshint eqeqeq:false */ + QUnit.push( expected != actual, actual, expected, message ); + }, + + /** + * @name propEqual + * @function + */ + propEqual: function( actual, expected, message ) { + actual = objectValues(actual); + expected = objectValues(expected); + QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name notPropEqual + * @function + */ + notPropEqual: function( actual, expected, message ) { + actual = objectValues(actual); + expected = objectValues(expected); + QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name deepEqual + * @function + */ + deepEqual: function( actual, expected, message ) { + QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name notDeepEqual + * @function + */ + notDeepEqual: function( actual, expected, message ) { + QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name strictEqual + * @function + */ + strictEqual: function( actual, expected, message ) { + QUnit.push( expected === actual, actual, expected, message ); + }, + + /** + * @name notStrictEqual + * @function + */ + notStrictEqual: function( actual, expected, message ) { + QUnit.push( expected !== actual, actual, expected, message ); + }, + + "throws": function( block, expected, message ) { + var actual, + expectedOutput = expected, + ok = false; + + // 'expected' is optional + if ( typeof expected === "string" ) { + message = expected; + expected = null; + } + + config.current.ignoreGlobalErrors = true; + try { + block.call( config.current.testEnvironment ); + } catch (e) { + actual = e; + } + config.current.ignoreGlobalErrors = false; + + if ( actual ) { + // we don't want to validate thrown error + if ( !expected ) { + ok = true; + expectedOutput = null; + // expected is a regexp + } else if ( QUnit.objectType( expected ) === "regexp" ) { + ok = expected.test( errorString( actual ) ); + // expected is a constructor + } else if ( actual instanceof expected ) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if ( expected.call( {}, actual ) === true ) { + expectedOutput = null; + ok = true; + } + + QUnit.push( ok, actual, expectedOutput, message ); + } else { + QUnit.pushFailure( message, null, 'No exception was thrown.' ); + } + } }; /** @@ -665,19 +665,19 @@ QUnit.raises = assert[ "throws" ]; * Kept to avoid TypeErrors for undefined methods. */ QUnit.equals = function() { - QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); + QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); }; QUnit.same = function() { - QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); + QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); }; // We want access to the constructor's prototype (function() { - function F() {} - F.prototype = QUnit; - QUnit = new F(); - // Make F QUnit's constructor so that we can add to the prototype later - QUnit.constructor = F; + function F() {} + F.prototype = QUnit; + QUnit = new F(); + // Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; }()); /** @@ -686,319 +686,319 @@ QUnit.same = function() { * `config` initialized at top of scope */ config = { - // The queue of tests to run - queue: [], - - // block until document ready - blocking: true, - - // when enabled, show only failing tests - // gets persisted through sessionStorage and can be changed in UI via checkbox - hidepassed: false, - - // by default, run previously failed tests first - // very useful in combination with "Hide passed tests" checked - reorder: true, - - // by default, modify document.title when suite is done - altertitle: true, - - // when enabled, all tests must call expect() - requireExpects: false, - - // add checkboxes that are persisted in the query-string - // when enabled, the id is set to `true` as a `QUnit.config` property - urlConfig: [ - { - id: "noglobals", - label: "Check for Globals", - tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." - }, - { - id: "notrycatch", - label: "No try-catch", - tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." - } - ], - - // Set of all modules. - modules: {}, - - // logging callback queues - begin: [], - done: [], - log: [], - testStart: [], - testDone: [], - moduleStart: [], - moduleDone: [] + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + // when enabled, all tests must call expect() + requireExpects: false, + + // add checkboxes that are persisted in the query-string + // when enabled, the id is set to `true` as a `QUnit.config` property + urlConfig: [ + { + id: "noglobals", + label: "Check for Globals", + tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." + }, + { + id: "notrycatch", + label: "No try-catch", + tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." + } + ], + + // Set of all modules. + modules: {}, + + // logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] }; // Export global variables, unless an 'exports' object exists, // in that case we assume we're in CommonJS (dealt with on the bottom of the script) if ( typeof exports === "undefined" ) { - extend( window, QUnit ); + extend( window, QUnit ); - // Expose QUnit object - window.QUnit = QUnit; + // Expose QUnit object + window.QUnit = QUnit; } // Initialize more QUnit.config and QUnit.urlParams (function() { - var i, - location = window.location || { search: "", protocol: "file:" }, - params = location.search.slice( 1 ).split( "&" ), - length = params.length, - urlParams = {}, - current; - - if ( params[ 0 ] ) { - for ( i = 0; i < length; i++ ) { - current = params[ i ].split( "=" ); - current[ 0 ] = decodeURIComponent( current[ 0 ] ); - // allow just a key to turn on a flag, e.g., test.html?noglobals - current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; - urlParams[ current[ 0 ] ] = current[ 1 ]; - } - } - - QUnit.urlParams = urlParams; - - // String search anywhere in moduleName+testName - config.filter = urlParams.filter; - - // Exact match of the module name - config.module = urlParams.module; - - config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; - - // Figure out if we're running the tests from a server or not - QUnit.isLocal = location.protocol === "file:"; + var i, + location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + } + } + + QUnit.urlParams = urlParams; + + // String search anywhere in moduleName+testName + config.filter = urlParams.filter; + + // Exact match of the module name + config.module = urlParams.module; + + config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = location.protocol === "file:"; }()); // Extend QUnit object, // these after set here because they should not be exposed as global functions extend( QUnit, { - assert: assert, - - config: config, - - // Initialize the configuration options - init: function() { - extend( config, { - stats: { all: 0, bad: 0 }, - moduleStats: { all: 0, bad: 0 }, - started: +new Date(), - updateRate: 1000, - blocking: false, - autostart: true, - autorun: false, - filter: "", - queue: [], - semaphore: 1 - }); - - var tests, banner, result, - qunit = id( "qunit" ); - - if ( qunit ) { - qunit.innerHTML = - "

      " + escapeText( document.title ) + "

      " + - "

      " + - "
      " + - "

      " + - "
        "; - } - - tests = id( "qunit-tests" ); - banner = id( "qunit-banner" ); - result = id( "qunit-testresult" ); - - if ( tests ) { - tests.innerHTML = ""; - } - - if ( banner ) { - banner.className = ""; - } - - if ( result ) { - result.parentNode.removeChild( result ); - } - - if ( tests ) { - result = document.createElement( "p" ); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests ); - result.innerHTML = "Running...
         "; - } - }, - - // Resets the test setup. Useful for tests that modify the DOM. - reset: function() { - var fixture = id( "qunit-fixture" ); - if ( fixture ) { - fixture.innerHTML = config.fixture; - } - }, - - // Trigger an event on an element. - // @example triggerEvent( document.body, "click" ); - triggerEvent: function( elem, type, event ) { - if ( document.createEvent ) { - event = document.createEvent( "MouseEvents" ); - event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, - 0, 0, 0, 0, 0, false, false, false, false, 0, null); - - elem.dispatchEvent( event ); - } else if ( elem.fireEvent ) { - elem.fireEvent( "on" + type ); - } - }, - - // Safe object type checking - is: function( type, obj ) { - return QUnit.objectType( obj ) === type; - }, - - objectType: function( obj ) { - if ( typeof obj === "undefined" ) { - return "undefined"; - // consider: typeof null === object - } - if ( obj === null ) { - return "null"; - } - - var match = toString.call( obj ).match(/^\[object\s(.*)\]$/), - type = match && match[1] || ""; - - switch ( type ) { - case "Number": - if ( isNaN(obj) ) { - return "nan"; - } - return "number"; - case "String": - case "Boolean": - case "Array": - case "Date": - case "RegExp": - case "Function": - return type.toLowerCase(); - } - if ( typeof obj === "object" ) { - return "object"; - } - return undefined; - }, - - push: function( result, actual, expected, message ) { - if ( !config.current ) { - throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); - } - - var output, source, - details = { - module: config.current.module, - name: config.current.testName, - result: result, - message: message, - actual: actual, - expected: expected - }; - - message = escapeText( message ) || ( result ? "okay" : "failed" ); - message = "" + message + ""; - output = message; - - if ( !result ) { - expected = escapeText( QUnit.jsDump.parse(expected) ); - actual = escapeText( QUnit.jsDump.parse(actual) ); - output += ""; - - if ( actual !== expected ) { - output += ""; - output += ""; - } - - source = sourceFromStacktrace(); - - if ( source ) { - details.source = source; - output += ""; - } - - output += "
        Expected:
        " + expected + "
        Result:
        " + actual + "
        Diff:
        " + QUnit.diff( expected, actual ) + "
        Source:
        " + escapeText( source ) + "
        "; - } - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: !!result, - message: output - }); - }, - - pushFailure: function( message, source, actual ) { - if ( !config.current ) { - throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); - } - - var output, - details = { - module: config.current.module, - name: config.current.testName, - result: false, - message: message - }; - - message = escapeText( message ) || "error"; - message = "" + message + ""; - output = message; - - output += ""; - - if ( actual ) { - output += ""; - } - - if ( source ) { - details.source = source; - output += ""; - } - - output += "
        Result:
        " + escapeText( actual ) + "
        Source:
        " + escapeText( source ) + "
        "; - - runLoggingCallbacks( "log", QUnit, details ); - - config.current.assertions.push({ - result: false, - message: output - }); - }, - - url: function( params ) { - params = extend( extend( {}, QUnit.urlParams ), params ); - var key, - querystring = "?"; - - for ( key in params ) { - if ( !hasOwn.call( params, key ) ) { - continue; - } - querystring += encodeURIComponent( key ) + "=" + - encodeURIComponent( params[ key ] ) + "&"; - } - return window.location.protocol + "//" + window.location.host + - window.location.pathname + querystring.slice( 0, -1 ); - }, - - extend: extend, - id: id, - addEvent: addEvent - // load, equiv, jsDump, diff: Attached later + assert: assert, + + config: config, + + // Initialize the configuration options + init: function() { + extend( config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date(), + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 1 + }); + + var tests, banner, result, + qunit = id( "qunit" ); + + if ( qunit ) { + qunit.innerHTML = + "

        " + escapeText( document.title ) + "

        " + + "

        " + + "
        " + + "

        " + + "
          "; + } + + tests = id( "qunit-tests" ); + banner = id( "qunit-banner" ); + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = "Running...
           "; + } + }, + + // Resets the test setup. Useful for tests that modify the DOM. + reset: function() { + var fixture = id( "qunit-fixture" ); + if ( fixture ) { + fixture.innerHTML = config.fixture; + } + }, + + // Trigger an event on an element. + // @example triggerEvent( document.body, "click" ); + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent( "MouseEvents" ); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + + elem.dispatchEvent( event ); + } else if ( elem.fireEvent ) { + elem.fireEvent( "on" + type ); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) === type; + }, + + objectType: function( obj ) { + if ( typeof obj === "undefined" ) { + return "undefined"; + // consider: typeof null === object + } + if ( obj === null ) { + return "null"; + } + + var match = toString.call( obj ).match(/^\[object\s(.*)\]$/), + type = match && match[1] || ""; + + switch ( type ) { + case "Number": + if ( isNaN(obj) ) { + return "nan"; + } + return "number"; + case "String": + case "Boolean": + case "Array": + case "Date": + case "RegExp": + case "Function": + return type.toLowerCase(); + } + if ( typeof obj === "object" ) { + return "object"; + } + return undefined; + }, + + push: function( result, actual, expected, message ) { + if ( !config.current ) { + throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); + } + + var output, source, + details = { + module: config.current.module, + name: config.current.testName, + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeText( message ) || ( result ? "okay" : "failed" ); + message = "" + message + ""; + output = message; + + if ( !result ) { + expected = escapeText( QUnit.jsDump.parse(expected) ); + actual = escapeText( QUnit.jsDump.parse(actual) ); + output += ""; + + if ( actual !== expected ) { + output += ""; + output += ""; + } + + source = sourceFromStacktrace(); + + if ( source ) { + details.source = source; + output += ""; + } + + output += "
          Expected:
          " + expected + "
          Result:
          " + actual + "
          Diff:
          " + QUnit.diff( expected, actual ) + "
          Source:
          " + escapeText( source ) + "
          "; + } + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + pushFailure: function( message, source, actual ) { + if ( !config.current ) { + throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + + var output, + details = { + module: config.current.module, + name: config.current.testName, + result: false, + message: message + }; + + message = escapeText( message ) || "error"; + message = "" + message + ""; + output = message; + + output += ""; + + if ( actual ) { + output += ""; + } + + if ( source ) { + details.source = source; + output += ""; + } + + output += "
          Result:
          " + escapeText( actual ) + "
          Source:
          " + escapeText( source ) + "
          "; + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: false, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var key, + querystring = "?"; + + for ( key in params ) { + if ( !hasOwn.call( params, key ) ) { + continue; + } + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.protocol + "//" + window.location.host + + window.location.pathname + querystring.slice( 0, -1 ); + }, + + extend: extend, + id: id, + addEvent: addEvent + // load, equiv, jsDump, diff: Attached later }); /** @@ -1010,175 +1010,175 @@ extend( QUnit, { */ extend( QUnit.constructor.prototype, { - // Logging callbacks; all receive a single argument with the listed properties - // run test/logs.html for any related changes - begin: registerLoggingCallback( "begin" ), + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback( "begin" ), - // done: { failed, passed, total, runtime } - done: registerLoggingCallback( "done" ), + // done: { failed, passed, total, runtime } + done: registerLoggingCallback( "done" ), - // log: { result, actual, expected, message } - log: registerLoggingCallback( "log" ), + // log: { result, actual, expected, message } + log: registerLoggingCallback( "log" ), - // testStart: { name } - testStart: registerLoggingCallback( "testStart" ), + // testStart: { name } + testStart: registerLoggingCallback( "testStart" ), - // testDone: { name, failed, passed, total, duration } - testDone: registerLoggingCallback( "testDone" ), + // testDone: { name, failed, passed, total, duration } + testDone: registerLoggingCallback( "testDone" ), - // moduleStart: { name } - moduleStart: registerLoggingCallback( "moduleStart" ), + // moduleStart: { name } + moduleStart: registerLoggingCallback( "moduleStart" ), - // moduleDone: { name, failed, passed, total } - moduleDone: registerLoggingCallback( "moduleDone" ) + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback( "moduleDone" ) }); if ( typeof document === "undefined" || document.readyState === "complete" ) { - config.autorun = true; + config.autorun = true; } QUnit.load = function() { - runLoggingCallbacks( "begin", QUnit, {} ); - - // Initialize the config, saving the execution queue - var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, - urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter, - numModules = 0, - moduleFilterHtml = "", - urlConfigHtml = "", - oldconfig = extend( {}, config ); - - QUnit.init(); - extend(config, oldconfig); - - config.blocking = false; - - len = config.urlConfig.length; - - for ( i = 0; i < len; i++ ) { - val = config.urlConfig[i]; - if ( typeof val === "string" ) { - val = { - id: val, - label: val, - tooltip: "[no tooltip available]" - }; - } - config[ val.id ] = QUnit.urlParams[ val.id ]; - urlConfigHtml += ""; - } - - moduleFilterHtml += ""; - - // `userAgent` initialized at top of scope - userAgent = id( "qunit-userAgent" ); - if ( userAgent ) { - userAgent.innerHTML = navigator.userAgent; - } - - // `banner` initialized at top of scope - banner = id( "qunit-header" ); - if ( banner ) { - banner.innerHTML = "" + banner.innerHTML + " "; - } - - // `toolbar` initialized at top of scope - toolbar = id( "qunit-testrunner-toolbar" ); - if ( toolbar ) { - // `filter` initialized at top of scope - filter = document.createElement( "input" ); - filter.type = "checkbox"; - filter.id = "qunit-filter-pass"; - - addEvent( filter, "click", function() { - var tmp, - ol = document.getElementById( "qunit-tests" ); - - if ( filter.checked ) { - ol.className = ol.className + " hidepass"; - } else { - tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; - ol.className = tmp.replace( / hidepass /, " " ); - } - if ( defined.sessionStorage ) { - if (filter.checked) { - sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); - } else { - sessionStorage.removeItem( "qunit-filter-passed-tests" ); - } - } - }); - - if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { - filter.checked = true; - // `ol` initialized at top of scope - ol = document.getElementById( "qunit-tests" ); - ol.className = ol.className + " hidepass"; - } - toolbar.appendChild( filter ); - - // `label` initialized at top of scope - label = document.createElement( "label" ); - label.setAttribute( "for", "qunit-filter-pass" ); - label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." ); - label.innerHTML = "Hide passed tests"; - toolbar.appendChild( label ); - - urlConfigCheckboxesContainer = document.createElement("span"); - urlConfigCheckboxesContainer.innerHTML = urlConfigHtml; - urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input"); - // For oldIE support: - // * Add handlers to the individual elements instead of the container - // * Use "click" instead of "change" - // * Fallback from event.target to event.srcElement - addEvents( urlConfigCheckboxes, "click", function( event ) { - var params = {}, - target = event.target || event.srcElement; - params[ target.name ] = target.checked ? true : undefined; - window.location = QUnit.url( params ); - }); - toolbar.appendChild( urlConfigCheckboxesContainer ); - - if (numModules > 1) { - moduleFilter = document.createElement( 'span' ); - moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' ); - moduleFilter.innerHTML = moduleFilterHtml; - addEvent( moduleFilter.lastChild, "change", function() { - var selectBox = moduleFilter.getElementsByTagName("select")[0], - selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); - - window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } ); - }); - toolbar.appendChild(moduleFilter); - } - } - - // `main` initialized at top of scope - main = id( "qunit-fixture" ); - if ( main ) { - config.fixture = main.innerHTML; - } - - if ( config.autostart ) { - QUnit.start(); - } + runLoggingCallbacks( "begin", QUnit, {} ); + + // Initialize the config, saving the execution queue + var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, + urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter, + numModules = 0, + moduleFilterHtml = "", + urlConfigHtml = "", + oldconfig = extend( {}, config ); + + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + len = config.urlConfig.length; + + for ( i = 0; i < len; i++ ) { + val = config.urlConfig[i]; + if ( typeof val === "string" ) { + val = { + id: val, + label: val, + tooltip: "[no tooltip available]" + }; + } + config[ val.id ] = QUnit.urlParams[ val.id ]; + urlConfigHtml += ""; + } + + moduleFilterHtml += ""; + + // `userAgent` initialized at top of scope + userAgent = id( "qunit-userAgent" ); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + + // `banner` initialized at top of scope + banner = id( "qunit-header" ); + if ( banner ) { + banner.innerHTML = "" + banner.innerHTML + " "; + } + + // `toolbar` initialized at top of scope + toolbar = id( "qunit-testrunner-toolbar" ); + if ( toolbar ) { + // `filter` initialized at top of scope + filter = document.createElement( "input" ); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + + addEvent( filter, "click", function() { + var tmp, + ol = document.getElementById( "qunit-tests" ); + + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace( / hidepass /, " " ); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); + } else { + sessionStorage.removeItem( "qunit-filter-passed-tests" ); + } + } + }); + + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { + filter.checked = true; + // `ol` initialized at top of scope + ol = document.getElementById( "qunit-tests" ); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + // `label` initialized at top of scope + label = document.createElement( "label" ); + label.setAttribute( "for", "qunit-filter-pass" ); + label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." ); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + + urlConfigCheckboxesContainer = document.createElement("span"); + urlConfigCheckboxesContainer.innerHTML = urlConfigHtml; + urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input"); + // For oldIE support: + // * Add handlers to the individual elements instead of the container + // * Use "click" instead of "change" + // * Fallback from event.target to event.srcElement + addEvents( urlConfigCheckboxes, "click", function( event ) { + var params = {}, + target = event.target || event.srcElement; + params[ target.name ] = target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + toolbar.appendChild( urlConfigCheckboxesContainer ); + + if (numModules > 1) { + moduleFilter = document.createElement( 'span' ); + moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' ); + moduleFilter.innerHTML = moduleFilterHtml; + addEvent( moduleFilter.lastChild, "change", function() { + var selectBox = moduleFilter.getElementsByTagName("select")[0], + selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); + + window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } ); + }); + toolbar.appendChild(moduleFilter); + } + } + + // `main` initialized at top of scope + main = id( "qunit-fixture" ); + if ( main ) { + config.fixture = main.innerHTML; + } + + if ( config.autostart ) { + QUnit.start(); + } }; addEvent( window, "load", QUnit.load ); @@ -1191,305 +1191,305 @@ onErrorFnPrev = window.onerror; // Returning true will surpress the default browser handler, // returning false will let it run. window.onerror = function ( error, filePath, linerNr ) { - var ret = false; - if ( onErrorFnPrev ) { - ret = onErrorFnPrev( error, filePath, linerNr ); - } - - // Treat return value as window.onerror itself does, - // Only do our handling if not surpressed. - if ( ret !== true ) { - if ( QUnit.config.current ) { - if ( QUnit.config.current.ignoreGlobalErrors ) { - return true; - } - QUnit.pushFailure( error, filePath + ":" + linerNr ); - } else { - QUnit.test( "global failure", extend( function() { - QUnit.pushFailure( error, filePath + ":" + linerNr ); - }, { validTest: validTest } ) ); - } - return false; - } - - return ret; + var ret = false; + if ( onErrorFnPrev ) { + ret = onErrorFnPrev( error, filePath, linerNr ); + } + + // Treat return value as window.onerror itself does, + // Only do our handling if not surpressed. + if ( ret !== true ) { + if ( QUnit.config.current ) { + if ( QUnit.config.current.ignoreGlobalErrors ) { + return true; + } + QUnit.pushFailure( error, filePath + ":" + linerNr ); + } else { + QUnit.test( "global failure", extend( function() { + QUnit.pushFailure( error, filePath + ":" + linerNr ); + }, { validTest: validTest } ) ); + } + return false; + } + + return ret; }; function done() { - config.autorun = true; - - // Log the last module results - if ( config.currentModule ) { - runLoggingCallbacks( "moduleDone", QUnit, { - name: config.currentModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - }); - } - - var i, key, - banner = id( "qunit-banner" ), - tests = id( "qunit-tests" ), - runtime = +new Date() - config.started, - passed = config.stats.all - config.stats.bad, - html = [ - "Tests completed in ", - runtime, - " milliseconds.
          ", - "", - passed, - " assertions of ", - config.stats.all, - " passed, ", - config.stats.bad, - " failed." - ].join( "" ); - - if ( banner ) { - banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); - } - - if ( tests ) { - id( "qunit-testresult" ).innerHTML = html; - } - - if ( config.altertitle && typeof document !== "undefined" && document.title ) { - // show ✖ for good, ✔ for bad suite result in title - // use escape sequences in case file gets loaded with non-utf-8-charset - document.title = [ - ( config.stats.bad ? "\u2716" : "\u2714" ), - document.title.replace( /^[\u2714\u2716] /i, "" ) - ].join( " " ); - } - - // clear own sessionStorage items if all tests passed - if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { - // `key` & `i` initialized at top of scope - for ( i = 0; i < sessionStorage.length; i++ ) { - key = sessionStorage.key( i++ ); - if ( key.indexOf( "qunit-test-" ) === 0 ) { - sessionStorage.removeItem( key ); - } - } - } - - // scroll back to top to show results - if ( window.scrollTo ) { - window.scrollTo(0, 0); - } - - runLoggingCallbacks( "done", QUnit, { - failed: config.stats.bad, - passed: passed, - total: config.stats.all, - runtime: runtime - }); + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + + var i, key, + banner = id( "qunit-banner" ), + tests = id( "qunit-tests" ), + runtime = +new Date() - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + "Tests completed in ", + runtime, + " milliseconds.
          ", + "", + passed, + " assertions of ", + config.stats.all, + " passed, ", + config.stats.bad, + " failed." + ].join( "" ); + + if ( banner ) { + banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( config.altertitle && typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + ( config.stats.bad ? "\u2716" : "\u2714" ), + document.title.replace( /^[\u2714\u2716] /i, "" ) + ].join( " " ); + } + + // clear own sessionStorage items if all tests passed + if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { + // `key` & `i` initialized at top of scope + for ( i = 0; i < sessionStorage.length; i++ ) { + key = sessionStorage.key( i++ ); + if ( key.indexOf( "qunit-test-" ) === 0 ) { + sessionStorage.removeItem( key ); + } + } + } + + // scroll back to top to show results + if ( window.scrollTo ) { + window.scrollTo(0, 0); + } + + runLoggingCallbacks( "done", QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + }); } /** @return Boolean: true if this test should be ran */ function validTest( test ) { - var include, - filter = config.filter && config.filter.toLowerCase(), - module = config.module && config.module.toLowerCase(), - fullName = (test.module + ": " + test.testName).toLowerCase(); - - // Internally-generated tests are always valid - if ( test.callback && test.callback.validTest === validTest ) { - delete test.callback.validTest; - return true; - } - - if ( config.testNumber ) { - return test.testNumber === config.testNumber; - } - - if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { - return false; - } - - if ( !filter ) { - return true; - } - - include = filter.charAt( 0 ) !== "!"; - if ( !include ) { - filter = filter.slice( 1 ); - } - - // If the filter matches, we need to honour include - if ( fullName.indexOf( filter ) !== -1 ) { - return include; - } - - // Otherwise, do the opposite - return !include; + var include, + filter = config.filter && config.filter.toLowerCase(), + module = config.module && config.module.toLowerCase(), + fullName = (test.module + ": " + test.testName).toLowerCase(); + + // Internally-generated tests are always valid + if ( test.callback && test.callback.validTest === validTest ) { + delete test.callback.validTest; + return true; + } + + if ( config.testNumber ) { + return test.testNumber === config.testNumber; + } + + if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { + return false; + } + + if ( !filter ) { + return true; + } + + include = filter.charAt( 0 ) !== "!"; + if ( !include ) { + filter = filter.slice( 1 ); + } + + // If the filter matches, we need to honour include + if ( fullName.indexOf( filter ) !== -1 ) { + return include; + } + + // Otherwise, do the opposite + return !include; } // so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) // Later Safari and IE10 are supposed to support error.stack as well // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack function extractStacktrace( e, offset ) { - offset = offset === undefined ? 3 : offset; - - var stack, include, i; - - if ( e.stacktrace ) { - // Opera - return e.stacktrace.split( "\n" )[ offset + 3 ]; - } else if ( e.stack ) { - // Firefox, Chrome - stack = e.stack.split( "\n" ); - if (/^error$/i.test( stack[0] ) ) { - stack.shift(); - } - if ( fileName ) { - include = []; - for ( i = offset; i < stack.length; i++ ) { - if ( stack[ i ].indexOf( fileName ) !== -1 ) { - break; - } - include.push( stack[ i ] ); - } - if ( include.length ) { - return include.join( "\n" ); - } - } - return stack[ offset ]; - } else if ( e.sourceURL ) { - // Safari, PhantomJS - // hopefully one day Safari provides actual stacktraces - // exclude useless self-reference for generated Error objects - if ( /qunit.js$/.test( e.sourceURL ) ) { - return; - } - // for actual exceptions, this is useful - return e.sourceURL + ":" + e.line; - } + offset = offset === undefined ? 3 : offset; + + var stack, include, i; + + if ( e.stacktrace ) { + // Opera + return e.stacktrace.split( "\n" )[ offset + 3 ]; + } else if ( e.stack ) { + // Firefox, Chrome + stack = e.stack.split( "\n" ); + if (/^error$/i.test( stack[0] ) ) { + stack.shift(); + } + if ( fileName ) { + include = []; + for ( i = offset; i < stack.length; i++ ) { + if ( stack[ i ].indexOf( fileName ) !== -1 ) { + break; + } + include.push( stack[ i ] ); + } + if ( include.length ) { + return include.join( "\n" ); + } + } + return stack[ offset ]; + } else if ( e.sourceURL ) { + // Safari, PhantomJS + // hopefully one day Safari provides actual stacktraces + // exclude useless self-reference for generated Error objects + if ( /qunit.js$/.test( e.sourceURL ) ) { + return; + } + // for actual exceptions, this is useful + return e.sourceURL + ":" + e.line; + } } function sourceFromStacktrace( offset ) { - try { - throw new Error(); - } catch ( e ) { - return extractStacktrace( e, offset ); - } + try { + throw new Error(); + } catch ( e ) { + return extractStacktrace( e, offset ); + } } /** * Escape text for attribute or text content. */ function escapeText( s ) { - if ( !s ) { - return ""; - } - s = s + ""; - // Both single quotes and double quotes (for attributes) - return s.replace( /['"<>&]/g, function( s ) { - switch( s ) { - case '\'': - return '''; - case '"': - return '"'; - case '<': - return '<'; - case '>': - return '>'; - case '&': - return '&'; - } - }); + if ( !s ) { + return ""; + } + s = s + ""; + // Both single quotes and double quotes (for attributes) + return s.replace( /['"<>&]/g, function( s ) { + switch( s ) { + case '\'': + return '''; + case '"': + return '"'; + case '<': + return '<'; + case '>': + return '>'; + case '&': + return '&'; + } + }); } function synchronize( callback, last ) { - config.queue.push( callback ); + config.queue.push( callback ); - if ( config.autorun && !config.blocking ) { - process( last ); - } + if ( config.autorun && !config.blocking ) { + process( last ); + } } function process( last ) { - function next() { - process( last ); - } - var start = new Date().getTime(); - config.depth = config.depth ? config.depth + 1 : 1; - - while ( config.queue.length && !config.blocking ) { - if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { - config.queue.shift()(); - } else { - window.setTimeout( next, 13 ); - break; - } - } - config.depth--; - if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { - done(); - } + function next() { + process( last ); + } + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while ( config.queue.length && !config.blocking ) { + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { + config.queue.shift()(); + } else { + window.setTimeout( next, 13 ); + break; + } + } + config.depth--; + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { + done(); + } } function saveGlobal() { - config.pollution = []; - - if ( config.noglobals ) { - for ( var key in window ) { - // in Opera sometimes DOM element ids show up here, ignore them - if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) { - continue; - } - config.pollution.push( key ); - } - } + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + // in Opera sometimes DOM element ids show up here, ignore them + if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) { + continue; + } + config.pollution.push( key ); + } + } } function checkPollution() { - var newGlobals, - deletedGlobals, - old = config.pollution; + var newGlobals, + deletedGlobals, + old = config.pollution; - saveGlobal(); + saveGlobal(); - newGlobals = diff( config.pollution, old ); - if ( newGlobals.length > 0 ) { - QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); - } + newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); + } - deletedGlobals = diff( old, config.pollution ); - if ( deletedGlobals.length > 0 ) { - QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); - } + deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } } // returns a new Array with the elements that are in a but not in b function diff( a, b ) { - var i, j, - result = a.slice(); - - for ( i = 0; i < result.length; i++ ) { - for ( j = 0; j < b.length; j++ ) { - if ( result[i] === b[j] ) { - result.splice( i, 1 ); - i--; - break; - } - } - } - return result; + var i, j, + result = a.slice(); + + for ( i = 0; i < result.length; i++ ) { + for ( j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice( i, 1 ); + i--; + break; + } + } + } + return result; } function extend( a, b ) { - for ( var prop in b ) { - if ( b[ prop ] === undefined ) { - delete a[ prop ]; + for ( var prop in b ) { + if ( b[ prop ] === undefined ) { + delete a[ prop ]; - // Avoid "Member not found" error in IE8 caused by setting window.constructor - } else if ( prop !== "constructor" || a !== window ) { - a[ prop ] = b[ prop ]; - } - } + // Avoid "Member not found" error in IE8 caused by setting window.constructor + } else if ( prop !== "constructor" || a !== window ) { + a[ prop ] = b[ prop ]; + } + } - return a; + return a; } /** @@ -1498,13 +1498,13 @@ function extend( a, b ) { * @param {Function} fn */ function addEvent( elem, type, fn ) { - // Standards-based browsers - if ( elem.addEventListener ) { - elem.addEventListener( type, fn, false ); - // IE - } else { - elem.attachEvent( "on" + type, fn ); - } + // Standards-based browsers + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + // IE + } else { + elem.attachEvent( "on" + type, fn ); + } } /** @@ -1513,240 +1513,240 @@ function addEvent( elem, type, fn ) { * @param {Function} fn */ function addEvents( elems, type, fn ) { - var i = elems.length; - while ( i-- ) { - addEvent( elems[i], type, fn ); - } + var i = elems.length; + while ( i-- ) { + addEvent( elems[i], type, fn ); + } } function hasClass( elem, name ) { - return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; + return (" " + elem.className + " ").indexOf(" " + name + " ") > -1; } function addClass( elem, name ) { - if ( !hasClass( elem, name ) ) { - elem.className += (elem.className ? " " : "") + name; - } + if ( !hasClass( elem, name ) ) { + elem.className += (elem.className ? " " : "") + name; + } } function removeClass( elem, name ) { - var set = " " + elem.className + " "; - // Class name may appear multiple times - while ( set.indexOf(" " + name + " ") > -1 ) { - set = set.replace(" " + name + " " , " "); - } - // If possible, trim it for prettiness, but not neccecarily - elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set ); + var set = " " + elem.className + " "; + // Class name may appear multiple times + while ( set.indexOf(" " + name + " ") > -1 ) { + set = set.replace(" " + name + " " , " "); + } + // If possible, trim it for prettiness, but not neccecarily + elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set ); } function id( name ) { - return !!( typeof document !== "undefined" && document && document.getElementById ) && - document.getElementById( name ); + return !!( typeof document !== "undefined" && document && document.getElementById ) && + document.getElementById( name ); } function registerLoggingCallback( key ) { - return function( callback ) { - config[key].push( callback ); - }; + return function( callback ) { + config[key].push( callback ); + }; } // Supports deprecated method of completely overwriting logging callbacks function runLoggingCallbacks( key, scope, args ) { - var i, callbacks; - if ( QUnit.hasOwnProperty( key ) ) { - QUnit[ key ].call(scope, args ); - } else { - callbacks = config[ key ]; - for ( i = 0; i < callbacks.length; i++ ) { - callbacks[ i ].call( scope, args ); - } - } + var i, callbacks; + if ( QUnit.hasOwnProperty( key ) ) { + QUnit[ key ].call(scope, args ); + } else { + callbacks = config[ key ]; + for ( i = 0; i < callbacks.length; i++ ) { + callbacks[ i ].call( scope, args ); + } + } } // Test for equality any JavaScript type. // Author: Philippe Rathé QUnit.equiv = (function() { - // Call the o related callback with the given arguments. - function bindCallbacks( o, callbacks, args ) { - var prop = QUnit.objectType( o ); - if ( prop ) { - if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { - return callbacks[ prop ].apply( callbacks, args ); - } else { - return callbacks[ prop ]; // or undefined - } - } - } - - // the real equiv function - var innerEquiv, - // stack to decide between skip/abort functions - callers = [], - // stack to avoiding loops from circular referencing - parents = [], - - getProto = Object.getPrototypeOf || function ( obj ) { - return obj.__proto__; - }, - callbacks = (function () { - - // for string, boolean, number and null - function useStrictEquality( b, a ) { - /*jshint eqeqeq:false */ - if ( b instanceof a.constructor || a instanceof b.constructor ) { - // to catch short annotaion VS 'new' annotation of a - // declaration - // e.g. var i = 1; - // var j = new Number(1); - return a == b; - } else { - return a === b; - } - } - - return { - "string": useStrictEquality, - "boolean": useStrictEquality, - "number": useStrictEquality, - "null": useStrictEquality, - "undefined": useStrictEquality, - - "nan": function( b ) { - return isNaN( b ); - }, - - "date": function( b, a ) { - return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); - }, - - "regexp": function( b, a ) { - return QUnit.objectType( b ) === "regexp" && - // the regex itself - a.source === b.source && - // and its modifers - a.global === b.global && - // (gmi) ... - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline && - a.sticky === b.sticky; - }, - - // - skip when the property is a method of an instance (OOP) - // - abort otherwise, - // initial === would have catch identical references anyway - "function": function() { - var caller = callers[callers.length - 1]; - return caller !== Object && typeof caller !== "undefined"; - }, - - "array": function( b, a ) { - var i, j, len, loop; - - // b could be an object literal here - if ( QUnit.objectType( b ) !== "array" ) { - return false; - } - - len = a.length; - if ( len !== b.length ) { - // safe and faster - return false; - } - - // track reference to avoid circular references - parents.push( a ); - for ( i = 0; i < len; i++ ) { - loop = false; - for ( j = 0; j < parents.length; j++ ) { - if ( parents[j] === a[i] ) { - loop = true;// dont rewalk array - } - } - if ( !loop && !innerEquiv(a[i], b[i]) ) { - parents.pop(); - return false; - } - } - parents.pop(); - return true; - }, - - "object": function( b, a ) { - var i, j, loop, - // Default to true - eq = true, - aProperties = [], - bProperties = []; - - // comparing constructors is more strict than using - // instanceof - if ( a.constructor !== b.constructor ) { - // Allow objects with no prototype to be equivalent to - // objects with Object as their constructor. - if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || - ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { - return false; - } - } - - // stack constructor before traversing properties - callers.push( a.constructor ); - // track reference to avoid circular references - parents.push( a ); - - for ( i in a ) { // be strict: don't ensures hasOwnProperty - // and go deep - loop = false; - for ( j = 0; j < parents.length; j++ ) { - if ( parents[j] === a[i] ) { - // don't go down the same path twice - loop = true; - } - } - aProperties.push(i); // collect a's properties - - if (!loop && !innerEquiv( a[i], b[i] ) ) { - eq = false; - break; - } - } - - callers.pop(); // unstack, we are done - parents.pop(); - - for ( i in b ) { - bProperties.push( i ); // collect b's properties - } - - // Ensures identical properties name - return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); - } - }; - }()); - - innerEquiv = function() { // can take multiple arguments - var args = [].slice.apply( arguments ); - if ( args.length < 2 ) { - return true; // end transition - } - - return (function( a, b ) { - if ( a === b ) { - return true; // catch the most you can - } else if ( a === null || b === null || typeof a === "undefined" || - typeof b === "undefined" || - QUnit.objectType(a) !== QUnit.objectType(b) ) { - return false; // don't lose time with error prone cases - } else { - return bindCallbacks(a, callbacks, [ b, a ]); - } - - // apply transition with (1..n) arguments - }( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) ); - }; - - return innerEquiv; + // Call the o related callback with the given arguments. + function bindCallbacks( o, callbacks, args ) { + var prop = QUnit.objectType( o ); + if ( prop ) { + if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { + return callbacks[ prop ].apply( callbacks, args ); + } else { + return callbacks[ prop ]; // or undefined + } + } + } + + // the real equiv function + var innerEquiv, + // stack to decide between skip/abort functions + callers = [], + // stack to avoiding loops from circular referencing + parents = [], + + getProto = Object.getPrototypeOf || function ( obj ) { + return obj.__proto__; + }, + callbacks = (function () { + + // for string, boolean, number and null + function useStrictEquality( b, a ) { + /*jshint eqeqeq:false */ + if ( b instanceof a.constructor || a instanceof b.constructor ) { + // to catch short annotaion VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function( b ) { + return isNaN( b ); + }, + + "date": function( b, a ) { + return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function( b, a ) { + return QUnit.objectType( b ) === "regexp" && + // the regex itself + a.source === b.source && + // and its modifers + a.global === b.global && + // (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline && + a.sticky === b.sticky; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function() { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array": function( b, a ) { + var i, j, len, loop; + + // b could be an object literal here + if ( QUnit.objectType( b ) !== "array" ) { + return false; + } + + len = a.length; + if ( len !== b.length ) { + // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push( a ); + for ( i = 0; i < len; i++ ) { + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + loop = true;// dont rewalk array + } + } + if ( !loop && !innerEquiv(a[i], b[i]) ) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object": function( b, a ) { + var i, j, loop, + // Default to true + eq = true, + aProperties = [], + bProperties = []; + + // comparing constructors is more strict than using + // instanceof + if ( a.constructor !== b.constructor ) { + // Allow objects with no prototype to be equivalent to + // objects with Object as their constructor. + if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || + ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { + return false; + } + } + + // stack constructor before traversing properties + callers.push( a.constructor ); + // track reference to avoid circular references + parents.push( a ); + + for ( i in a ) { // be strict: don't ensures hasOwnProperty + // and go deep + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + // don't go down the same path twice + loop = true; + } + } + aProperties.push(i); // collect a's properties + + if (!loop && !innerEquiv( a[i], b[i] ) ) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for ( i in b ) { + bProperties.push( i ); // collect b's properties + } + + // Ensures identical properties name + return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); + } + }; + }()); + + innerEquiv = function() { // can take multiple arguments + var args = [].slice.apply( arguments ); + if ( args.length < 2 ) { + return true; // end transition + } + + return (function( a, b ) { + if ( a === b ) { + return true; // catch the most you can + } else if ( a === null || b === null || typeof a === "undefined" || + typeof b === "undefined" || + QUnit.objectType(a) !== QUnit.objectType(b) ) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [ b, a ]); + } + + // apply transition with (1..n) arguments + }( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) ); + }; + + return innerEquiv; }()); /** @@ -1760,238 +1760,238 @@ QUnit.equiv = (function() { * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} */ QUnit.jsDump = (function() { - function quote( str ) { - return '"' + str.toString().replace( /"/g, '\\"' ) + '"'; - } - function literal( o ) { - return o + ""; - } - function join( pre, arr, post ) { - var s = jsDump.separator(), - base = jsDump.indent(), - inner = jsDump.indent(1); - if ( arr.join ) { - arr = arr.join( "," + s + inner ); - } - if ( !arr ) { - return pre + post; - } - return [ pre, inner + arr, base + post ].join(s); - } - function array( arr, stack ) { - var i = arr.length, ret = new Array(i); - this.up(); - while ( i-- ) { - ret[i] = this.parse( arr[i] , undefined , stack); - } - this.down(); - return join( "[", ret, "]" ); - } - - var reName = /^function (\w+)/, - jsDump = { - // type is used mostly internally, you can fix a (custom)type in advance - parse: function( obj, type, stack ) { - stack = stack || [ ]; - var inStack, res, - parser = this.parsers[ type || this.typeOf(obj) ]; - - type = typeof parser; - inStack = inArray( obj, stack ); - - if ( inStack !== -1 ) { - return "recursion(" + (inStack - stack.length) + ")"; - } - if ( type === "function" ) { - stack.push( obj ); - res = parser.call( this, obj, stack ); - stack.pop(); - return res; - } - return ( type === "string" ) ? parser : this.parsers.error; - }, - typeOf: function( obj ) { - var type; - if ( obj === null ) { - type = "null"; - } else if ( typeof obj === "undefined" ) { - type = "undefined"; - } else if ( QUnit.is( "regexp", obj) ) { - type = "regexp"; - } else if ( QUnit.is( "date", obj) ) { - type = "date"; - } else if ( QUnit.is( "function", obj) ) { - type = "function"; - } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { - type = "window"; - } else if ( obj.nodeType === 9 ) { - type = "document"; - } else if ( obj.nodeType ) { - type = "node"; - } else if ( - // native arrays - toString.call( obj ) === "[object Array]" || - // NodeList objects - ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) - ) { - type = "array"; - } else if ( obj.constructor === Error.prototype.constructor ) { - type = "error"; - } else { - type = typeof obj; - } - return type; - }, - separator: function() { - return this.multiline ? this.HTML ? "
          " : "\n" : this.HTML ? " " : " "; - }, - // extra can be a number, shortcut for increasing-calling-decreasing - indent: function( extra ) { - if ( !this.multiline ) { - return ""; - } - var chr = this.indentChar; - if ( this.HTML ) { - chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); - } - return new Array( this._depth_ + (extra||0) ).join(chr); - }, - up: function( a ) { - this._depth_ += a || 1; - }, - down: function( a ) { - this._depth_ -= a || 1; - }, - setParser: function( name, parser ) { - this.parsers[name] = parser; - }, - // The next 3 are exposed so you can use them - quote: quote, - literal: literal, - join: join, - // - _depth_: 1, - // This is the list of parsers, to modify them, use jsDump.setParser - parsers: { - window: "[Window]", - document: "[Document]", - error: function(error) { - return "Error(\"" + error.message + "\")"; - }, - unknown: "[Unknown]", - "null": "null", - "undefined": "undefined", - "function": function( fn ) { - var ret = "function", - // functions never have name in IE - name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; - - if ( name ) { - ret += " " + name; - } - ret += "( "; - - ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); - return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); - }, - array: array, - nodelist: array, - "arguments": array, - object: function( map, stack ) { - var ret = [ ], keys, key, val, i; - QUnit.jsDump.up(); - keys = []; - for ( key in map ) { - keys.push( key ); - } - keys.sort(); - for ( i = 0; i < keys.length; i++ ) { - key = keys[ i ]; - val = map[ key ]; - ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); - } - QUnit.jsDump.down(); - return join( "{", ret, "}" ); - }, - node: function( node ) { - var len, i, val, - open = QUnit.jsDump.HTML ? "<" : "<", - close = QUnit.jsDump.HTML ? ">" : ">", - tag = node.nodeName.toLowerCase(), - ret = open + tag, - attrs = node.attributes; - - if ( attrs ) { - for ( i = 0, len = attrs.length; i < len; i++ ) { - val = attrs[i].nodeValue; - // IE6 includes all attributes in .attributes, even ones not explicitly set. - // Those have values like undefined, null, 0, false, "" or "inherit". - if ( val && val !== "inherit" ) { - ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" ); - } - } - } - ret += close; - - // Show content of TextNode or CDATASection - if ( node.nodeType === 3 || node.nodeType === 4 ) { - ret += node.nodeValue; - } - - return ret + open + "/" + tag + close; - }, - // function calls it internally, it's the arguments part of the function - functionArgs: function( fn ) { - var args, - l = fn.length; - - if ( !l ) { - return ""; - } - - args = new Array(l); - while ( l-- ) { - // 97 is 'a' - args[l] = String.fromCharCode(97+l); - } - return " " + args.join( ", " ) + " "; - }, - // object calls it internally, the key part of an item in a map - key: quote, - // function calls it internally, it's the content of the function - functionCode: "[code]", - // node calls it internally, it's an html attribute value - attribute: quote, - string: quote, - date: quote, - regexp: literal, - number: literal, - "boolean": literal - }, - // if true, entities are escaped ( <, >, \t, space and \n ) - HTML: false, - // indentation unit - indentChar: " ", - // if true, items in a collection, are separated by a \n, else just a space. - multiline: true - }; - - return jsDump; + function quote( str ) { + return '"' + str.toString().replace( /"/g, '\\"' ) + '"'; + } + function literal( o ) { + return o + ""; + } + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) { + arr = arr.join( "," + s + inner ); + } + if ( !arr ) { + return pre + post; + } + return [ pre, inner + arr, base + post ].join(s); + } + function array( arr, stack ) { + var i = arr.length, ret = new Array(i); + this.up(); + while ( i-- ) { + ret[i] = this.parse( arr[i] , undefined , stack); + } + this.down(); + return join( "[", ret, "]" ); + } + + var reName = /^function (\w+)/, + jsDump = { + // type is used mostly internally, you can fix a (custom)type in advance + parse: function( obj, type, stack ) { + stack = stack || [ ]; + var inStack, res, + parser = this.parsers[ type || this.typeOf(obj) ]; + + type = typeof parser; + inStack = inArray( obj, stack ); + + if ( inStack !== -1 ) { + return "recursion(" + (inStack - stack.length) + ")"; + } + if ( type === "function" ) { + stack.push( obj ); + res = parser.call( this, obj, stack ); + stack.pop(); + return res; + } + return ( type === "string" ) ? parser : this.parsers.error; + }, + typeOf: function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if ( typeof obj === "undefined" ) { + type = "undefined"; + } else if ( QUnit.is( "regexp", obj) ) { + type = "regexp"; + } else if ( QUnit.is( "date", obj) ) { + type = "date"; + } else if ( QUnit.is( "function", obj) ) { + type = "function"; + } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { + type = "window"; + } else if ( obj.nodeType === 9 ) { + type = "document"; + } else if ( obj.nodeType ) { + type = "node"; + } else if ( + // native arrays + toString.call( obj ) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else if ( obj.constructor === Error.prototype.constructor ) { + type = "error"; + } else { + type = typeof obj; + } + return type; + }, + separator: function() { + return this.multiline ? this.HTML ? "
          " : "\n" : this.HTML ? " " : " "; + }, + // extra can be a number, shortcut for increasing-calling-decreasing + indent: function( extra ) { + if ( !this.multiline ) { + return ""; + } + var chr = this.indentChar; + if ( this.HTML ) { + chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); + } + return new Array( this._depth_ + (extra||0) ).join(chr); + }, + up: function( a ) { + this._depth_ += a || 1; + }, + down: function( a ) { + this._depth_ -= a || 1; + }, + setParser: function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote: quote, + literal: literal, + join: join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers: { + window: "[Window]", + document: "[Document]", + error: function(error) { + return "Error(\"" + error.message + "\")"; + }, + unknown: "[Unknown]", + "null": "null", + "undefined": "undefined", + "function": function( fn ) { + var ret = "function", + // functions never have name in IE + name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1]; + + if ( name ) { + ret += " " + name; + } + ret += "( "; + + ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); + return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); + }, + array: array, + nodelist: array, + "arguments": array, + object: function( map, stack ) { + var ret = [ ], keys, key, val, i; + QUnit.jsDump.up(); + keys = []; + for ( key in map ) { + keys.push( key ); + } + keys.sort(); + for ( i = 0; i < keys.length; i++ ) { + key = keys[ i ]; + val = map[ key ]; + ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); + } + QUnit.jsDump.down(); + return join( "{", ret, "}" ); + }, + node: function( node ) { + var len, i, val, + open = QUnit.jsDump.HTML ? "<" : "<", + close = QUnit.jsDump.HTML ? ">" : ">", + tag = node.nodeName.toLowerCase(), + ret = open + tag, + attrs = node.attributes; + + if ( attrs ) { + for ( i = 0, len = attrs.length; i < len; i++ ) { + val = attrs[i].nodeValue; + // IE6 includes all attributes in .attributes, even ones not explicitly set. + // Those have values like undefined, null, 0, false, "" or "inherit". + if ( val && val !== "inherit" ) { + ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" ); + } + } + } + ret += close; + + // Show content of TextNode or CDATASection + if ( node.nodeType === 3 || node.nodeType === 4 ) { + ret += node.nodeValue; + } + + return ret + open + "/" + tag + close; + }, + // function calls it internally, it's the arguments part of the function + functionArgs: function( fn ) { + var args, + l = fn.length; + + if ( !l ) { + return ""; + } + + args = new Array(l); + while ( l-- ) { + // 97 is 'a' + args[l] = String.fromCharCode(97+l); + } + return " " + args.join( ", " ) + " "; + }, + // object calls it internally, the key part of an item in a map + key: quote, + // function calls it internally, it's the content of the function + functionCode: "[code]", + // node calls it internally, it's an html attribute value + attribute: quote, + string: quote, + date: quote, + regexp: literal, + number: literal, + "boolean": literal + }, + // if true, entities are escaped ( <, >, \t, space and \n ) + HTML: false, + // indentation unit + indentChar: " ", + // if true, items in a collection, are separated by a \n, else just a space. + multiline: true + }; + + return jsDump; }()); // from jquery.js function inArray( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } + if ( array.indexOf ) { + return array.indexOf( elem ); + } - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } - return -1; + return -1; } /* @@ -2009,143 +2009,143 @@ function inArray( elem, array ) { * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" */ QUnit.diff = (function() { - /*jshint eqeqeq:false, eqnull:true */ - function diff( o, n ) { - var i, - ns = {}, - os = {}; - - for ( i = 0; i < n.length; i++ ) { - if ( !hasOwn.call( ns, n[i] ) ) { - ns[ n[i] ] = { - rows: [], - o: null - }; - } - ns[ n[i] ].rows.push( i ); - } - - for ( i = 0; i < o.length; i++ ) { - if ( !hasOwn.call( os, o[i] ) ) { - os[ o[i] ] = { - rows: [], - n: null - }; - } - os[ o[i] ].rows.push( i ); - } - - for ( i in ns ) { - if ( !hasOwn.call( ns, i ) ) { - continue; - } - if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) { - n[ ns[i].rows[0] ] = { - text: n[ ns[i].rows[0] ], - row: os[i].rows[0] - }; - o[ os[i].rows[0] ] = { - text: o[ os[i].rows[0] ], - row: ns[i].rows[0] - }; - } - } - - for ( i = 0; i < n.length - 1; i++ ) { - if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && - n[ i + 1 ] == o[ n[i].row + 1 ] ) { - - n[ i + 1 ] = { - text: n[ i + 1 ], - row: n[i].row + 1 - }; - o[ n[i].row + 1 ] = { - text: o[ n[i].row + 1 ], - row: i + 1 - }; - } - } - - for ( i = n.length - 1; i > 0; i-- ) { - if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && - n[ i - 1 ] == o[ n[i].row - 1 ]) { - - n[ i - 1 ] = { - text: n[ i - 1 ], - row: n[i].row - 1 - }; - o[ n[i].row - 1 ] = { - text: o[ n[i].row - 1 ], - row: i - 1 - }; - } - } - - return { - o: o, - n: n - }; - } - - return function( o, n ) { - o = o.replace( /\s+$/, "" ); - n = n.replace( /\s+$/, "" ); - - var i, pre, - str = "", - out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), - oSpace = o.match(/\s+/g), - nSpace = n.match(/\s+/g); - - if ( oSpace == null ) { - oSpace = [ " " ]; - } - else { - oSpace.push( " " ); - } - - if ( nSpace == null ) { - nSpace = [ " " ]; - } - else { - nSpace.push( " " ); - } - - if ( out.n.length === 0 ) { - for ( i = 0; i < out.o.length; i++ ) { - str += "" + out.o[i] + oSpace[i] + ""; - } - } - else { - if ( out.n[0].text == null ) { - for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { - str += "" + out.o[n] + oSpace[n] + ""; - } - } - - for ( i = 0; i < out.n.length; i++ ) { - if (out.n[i].text == null) { - str += "" + out.n[i] + nSpace[i] + ""; - } - else { - // `pre` initialized at top of scope - pre = ""; - - for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { - pre += "" + out.o[n] + oSpace[n] + ""; - } - str += " " + out.n[i].text + nSpace[i] + pre; - } - } - } - - return str; - }; + /*jshint eqeqeq:false, eqnull:true */ + function diff( o, n ) { + var i, + ns = {}, + os = {}; + + for ( i = 0; i < n.length; i++ ) { + if ( !hasOwn.call( ns, n[i] ) ) { + ns[ n[i] ] = { + rows: [], + o: null + }; + } + ns[ n[i] ].rows.push( i ); + } + + for ( i = 0; i < o.length; i++ ) { + if ( !hasOwn.call( os, o[i] ) ) { + os[ o[i] ] = { + rows: [], + n: null + }; + } + os[ o[i] ].rows.push( i ); + } + + for ( i in ns ) { + if ( !hasOwn.call( ns, i ) ) { + continue; + } + if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) { + n[ ns[i].rows[0] ] = { + text: n[ ns[i].rows[0] ], + row: os[i].rows[0] + }; + o[ os[i].rows[0] ] = { + text: o[ os[i].rows[0] ], + row: ns[i].rows[0] + }; + } + } + + for ( i = 0; i < n.length - 1; i++ ) { + if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && + n[ i + 1 ] == o[ n[i].row + 1 ] ) { + + n[ i + 1 ] = { + text: n[ i + 1 ], + row: n[i].row + 1 + }; + o[ n[i].row + 1 ] = { + text: o[ n[i].row + 1 ], + row: i + 1 + }; + } + } + + for ( i = n.length - 1; i > 0; i-- ) { + if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && + n[ i - 1 ] == o[ n[i].row - 1 ]) { + + n[ i - 1 ] = { + text: n[ i - 1 ], + row: n[i].row - 1 + }; + o[ n[i].row - 1 ] = { + text: o[ n[i].row - 1 ], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function( o, n ) { + o = o.replace( /\s+$/, "" ); + n = n.replace( /\s+$/, "" ); + + var i, pre, + str = "", + out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), + oSpace = o.match(/\s+/g), + nSpace = n.match(/\s+/g); + + if ( oSpace == null ) { + oSpace = [ " " ]; + } + else { + oSpace.push( " " ); + } + + if ( nSpace == null ) { + nSpace = [ " " ]; + } + else { + nSpace.push( " " ); + } + + if ( out.n.length === 0 ) { + for ( i = 0; i < out.o.length; i++ ) { + str += "" + out.o[i] + oSpace[i] + ""; + } + } + else { + if ( out.n[0].text == null ) { + for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { + str += "" + out.o[n] + oSpace[n] + ""; + } + } + + for ( i = 0; i < out.n.length; i++ ) { + if (out.n[i].text == null) { + str += "" + out.n[i] + nSpace[i] + ""; + } + else { + // `pre` initialized at top of scope + pre = ""; + + for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { + pre += "" + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; }()); // for CommonJS enviroments, export everything if ( typeof exports !== "undefined" ) { - extend( exports, QUnit ); + extend( exports, QUnit ); } // get at whatever the global object is, like window in browsers diff --git a/test/qunit/tests/w2fields.js b/test/qunit/tests/w2fields.js index 6eda4a0ed..aaa0a40dd 100644 --- a/test/qunit/tests/w2fields.js +++ b/test/qunit/tests/w2fields.js @@ -2,135 +2,135 @@ // -- Unit Tests: w2utils // test( "w2fields('enum')", function() { -// var items; -// var values = [ -// { // # 0 -// input: [ 'item1', 'item2', 'item3', null, undefined, '' ], -// result: [ -// { id: 'item1', text: 'item1' }, -// { id: 'item2', text: 'item2' }, -// { id: 'item3', text: 'item3' } -// ], -// }, -// { // # 1 -// input: [ -// null, -// { id: -1, text: 'item-1' }, -// { id: 0, text: 'item0' }, -// { id: 1, text: 'item1' } -// ], -// result: [ -// { id: -1, text: 'item-1' }, -// { id: 0, text: 'item0' }, -// { id: 1, text: 'item1' } -// ] -// }, -// { // # 2 -// input: { -// "-1" : 'item-1', -// "0" : 'item0', -// "1" : 'item1', -// "2" : 'item2', -// }, -// result: [ -// { id: 0, text: 'item0' }, -// { id: 1, text: 'item1' }, -// { id: 2, text: 'item2' }, -// { id: -1, text: 'item-1' } -// ] -// }, -// { // # 3 -// input: { -// "a" : 'item-1', -// "b" : 'item0', -// "c" : 'item1', -// "d" : 'item2', -// }, -// result: [ -// { id: 'a', text: 'item-1' }, -// { id: 'b', text: 'item0' }, -// { id: 'c', text: 'item1' }, -// { id: 'd', text: 'item2' } -// ] -// } -// ]; -// $('body').append(''); +// var items; +// var values = [ +// { // # 0 +// input: [ 'item1', 'item2', 'item3', null, undefined, '' ], +// result: [ +// { id: 'item1', text: 'item1' }, +// { id: 'item2', text: 'item2' }, +// { id: 'item3', text: 'item3' } +// ], +// }, +// { // # 1 +// input: [ +// null, +// { id: -1, text: 'item-1' }, +// { id: 0, text: 'item0' }, +// { id: 1, text: 'item1' } +// ], +// result: [ +// { id: -1, text: 'item-1' }, +// { id: 0, text: 'item0' }, +// { id: 1, text: 'item1' } +// ] +// }, +// { // # 2 +// input: { +// "-1" : 'item-1', +// "0" : 'item0', +// "1" : 'item1', +// "2" : 'item2', +// }, +// result: [ +// { id: 0, text: 'item0' }, +// { id: 1, text: 'item1' }, +// { id: 2, text: 'item2' }, +// { id: -1, text: 'item-1' } +// ] +// }, +// { // # 3 +// input: { +// "a" : 'item-1', +// "b" : 'item0', +// "c" : 'item1', +// "d" : 'item2', +// }, +// result: [ +// { id: 'a', text: 'item-1' }, +// { id: 'b', text: 'item0' }, +// { id: 'c', text: 'item1' }, +// { id: 'd', text: 'item2' } +// ] +// } +// ]; +// $('body').append(''); -// for (var v in values) { -// $('#enum').w2field('clear'); -// $('#enum').w2field({ type: 'enum', items: values[v].input, selected: values[v].input }); -// var items = $('#enum').data('settings').items; -// var selected = $('#enum').data('selected'); -// deepEqual(items, values[v].result, 'Enum items convertion #' + v); -// deepEqual(selected, values[v].result, 'Enum selected convertion #' + v); -// } +// for (var v in values) { +// $('#enum').w2field('clear'); +// $('#enum').w2field({ type: 'enum', items: values[v].input, selected: values[v].input }); +// var items = $('#enum').data('settings').items; +// var selected = $('#enum').data('selected'); +// deepEqual(items, values[v].result, 'Enum items convertion #' + v); +// deepEqual(selected, values[v].result, 'Enum selected convertion #' + v); +// } -// $('#enum').w2field('clear'); -// $('#enum').remove(); +// $('#enum').w2field('clear'); +// $('#enum').remove(); // }); // test( "w2fields('list')", function() { -// var items; -// var values = [ -// { // # 0 -// input: [ 'item1', 'item2', 'item3', null, undefined, '' ], -// result: [ -// { id: 'item1', text: 'item1' }, -// { id: 'item2', text: 'item2' }, -// { id: 'item3', text: 'item3' } -// ], -// }, -// { // # 1 -// input: [ -// null, -// { id: -1, text: 'item-1' }, -// { id: 0, text: 'item0' }, -// { id: 1, text: 'item1' } -// ], -// result: [ -// { id: -1, text: 'item-1' }, -// { id: 0, text: 'item0' }, -// { id: 1, text: 'item1' } -// ] -// }, -// { // # 2 -// input: { -// "-1" : 'item-1', -// "0" : 'item0', -// "1" : 'item1', -// "2" : 'item2', -// }, -// result: [ -// { id: 0, text: 'item0' }, -// { id: 1, text: 'item1' }, -// { id: 2, text: 'item2' }, -// { id: -1, text: 'item-1' } -// ] -// }, -// { // # 3 -// input: { -// "a" : 'item-1', -// "b" : 'item0', -// "c" : 'item1', -// "d" : 'item2', -// }, -// result: [ -// { id: 'a', text: 'item-1' }, -// { id: 'b', text: 'item0' }, -// { id: 'c', text: 'item1' }, -// { id: 'd', text: 'item2' } -// ] -// } -// ]; -// $('body').append(''); +// var items; +// var values = [ +// { // # 0 +// input: [ 'item1', 'item2', 'item3', null, undefined, '' ], +// result: [ +// { id: 'item1', text: 'item1' }, +// { id: 'item2', text: 'item2' }, +// { id: 'item3', text: 'item3' } +// ], +// }, +// { // # 1 +// input: [ +// null, +// { id: -1, text: 'item-1' }, +// { id: 0, text: 'item0' }, +// { id: 1, text: 'item1' } +// ], +// result: [ +// { id: -1, text: 'item-1' }, +// { id: 0, text: 'item0' }, +// { id: 1, text: 'item1' } +// ] +// }, +// { // # 2 +// input: { +// "-1" : 'item-1', +// "0" : 'item0', +// "1" : 'item1', +// "2" : 'item2', +// }, +// result: [ +// { id: 0, text: 'item0' }, +// { id: 1, text: 'item1' }, +// { id: 2, text: 'item2' }, +// { id: -1, text: 'item-1' } +// ] +// }, +// { // # 3 +// input: { +// "a" : 'item-1', +// "b" : 'item0', +// "c" : 'item1', +// "d" : 'item2', +// }, +// result: [ +// { id: 'a', text: 'item-1' }, +// { id: 'b', text: 'item0' }, +// { id: 'c', text: 'item1' }, +// { id: 'd', text: 'item2' } +// ] +// } +// ]; +// $('body').append(''); -// for (var v in values) { -// $('#list').w2field('clear'); -// $('#list').w2field({ type: 'list', items: values[v].input, selected: values[v].input }); -// var items = $('#list').data('settings').items; -// deepEqual(items, values[v].result, 'Enum items convertion #' + v); -// } +// for (var v in values) { +// $('#list').w2field('clear'); +// $('#list').w2field({ type: 'list', items: values[v].input, selected: values[v].input }); +// var items = $('#list').data('settings').items; +// deepEqual(items, values[v].result, 'Enum items convertion #' + v); +// } -// $('#list').w2field('clear'); -// $('#list').remove(); +// $('#list').w2field('clear'); +// $('#list').remove(); // }); \ No newline at end of file diff --git a/test/qunit/tests/w2grid.js b/test/qunit/tests/w2grid.js index 9ecb63613..a3e19875c 100644 --- a/test/qunit/tests/w2grid.js +++ b/test/qunit/tests/w2grid.js @@ -5,100 +5,100 @@ test( "w2grid().getColumn()", function() { - $().w2grid({ - name: 'grid', - columns: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] - }); - - deepEqual(w2ui['grid'].getColumn('recid'), { field: 'recid', caption: 'ID' }, 'Get column #1'); - deepEqual(w2ui['grid'].getColumn('recid1'), null, 'Get column #2'); - equal(w2ui['grid'].getColumn('recid2', true), 1, 'Get column #3'); - - $().w2destroy('grid'); + $().w2grid({ + name: 'grid', + columns: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] + }); + + deepEqual(w2ui['grid'].getColumn('recid'), { field: 'recid', caption: 'ID' }, 'Get column #1'); + deepEqual(w2ui['grid'].getColumn('recid1'), null, 'Get column #2'); + equal(w2ui['grid'].getColumn('recid2', true), 1, 'Get column #3'); + + $().w2destroy('grid'); }); test( "w2grid().addColumn(), w2grid.removeColumn()", function() { - $().w2grid({ name: 'grid' }); - - w2ui['grid'].addColumn({ field: 'recid', caption: 'ID' }); - deepEqual(w2ui['grid'].columns, [{ field: 'recid', caption: 'ID' }], 'Add column #1'); + $().w2grid({ name: 'grid' }); + + w2ui['grid'].addColumn({ field: 'recid', caption: 'ID' }); + deepEqual(w2ui['grid'].columns, [{ field: 'recid', caption: 'ID' }], 'Add column #1'); - w2ui['grid'].addColumn('recid', { field: 'recid2', caption: 'ID' }); - deepEqual(w2ui['grid'].columns, [{ field: 'recid2', caption: 'ID' }, { field: 'recid', caption: 'ID' }], 'Add column #2'); + w2ui['grid'].addColumn('recid', { field: 'recid2', caption: 'ID' }); + deepEqual(w2ui['grid'].columns, [{ field: 'recid2', caption: 'ID' }, { field: 'recid', caption: 'ID' }], 'Add column #2'); - w2ui['grid'].removeColumn('recid', 'recid2'); - deepEqual(w2ui['grid'].columns, [], 'Remove column #1'); + w2ui['grid'].removeColumn('recid', 'recid2'); + deepEqual(w2ui['grid'].columns, [], 'Remove column #1'); - w2ui['grid'].addColumn([{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }]); - deepEqual(w2ui['grid'].columns, [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }], 'Add column #3'); + w2ui['grid'].addColumn([{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }]); + deepEqual(w2ui['grid'].columns, [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }], 'Add column #3'); - equal(w2ui['grid'].removeColumn('recid', 'recid2'), 2, 'Remove column #2'); + equal(w2ui['grid'].removeColumn('recid', 'recid2'), 2, 'Remove column #2'); - $().w2destroy('grid'); + $().w2destroy('grid'); }); test( "w2grid().hideColumn(), w2grid.showColumn()", function() { - $().w2grid({ - name: 'grid', - columns: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] - }); - - equal(w2ui['grid'].hideColumn('recid', 'recid2'), 2, 'Hide column #1'); - equal(w2ui['grid'].hideColumn('recid', 'recid2'), 0, 'Hide column #2'); - equal(w2ui['grid'].showColumn('recid', 'recid2'), 2, 'Show column #1'); - equal(w2ui['grid'].showColumn('recid', 'recid2'), 0, 'Show column #2'); - - $().w2destroy('grid'); + $().w2grid({ + name: 'grid', + columns: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] + }); + + equal(w2ui['grid'].hideColumn('recid', 'recid2'), 2, 'Hide column #1'); + equal(w2ui['grid'].hideColumn('recid', 'recid2'), 0, 'Hide column #2'); + equal(w2ui['grid'].showColumn('recid', 'recid2'), 2, 'Show column #1'); + equal(w2ui['grid'].showColumn('recid', 'recid2'), 0, 'Show column #2'); + + $().w2destroy('grid'); }); // === Searches test( "w2grid().getSearch()", function() { - $().w2grid({ - name: 'grid', - searches: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] - }); - - deepEqual(w2ui['grid'].getSearch('recid'), { field: 'recid', caption: 'ID' }, 'Get search #1'); - deepEqual(w2ui['grid'].getSearch('recid1'), null, 'Get search #2'); - equal(w2ui['grid'].getSearch('recid2', true), 1, 'Get search #3'); + $().w2grid({ + name: 'grid', + searches: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] + }); + + deepEqual(w2ui['grid'].getSearch('recid'), { field: 'recid', caption: 'ID' }, 'Get search #1'); + deepEqual(w2ui['grid'].getSearch('recid1'), null, 'Get search #2'); + equal(w2ui['grid'].getSearch('recid2', true), 1, 'Get search #3'); - $().w2destroy('grid'); + $().w2destroy('grid'); }); test( "w2grid().addSearch(), w2grid.removeSearch()", function() { - $().w2grid({ name: 'grid' }); - - w2ui['grid'].addSearch({ field: 'recid', caption: 'ID' }); - deepEqual(w2ui['grid'].searches, [{ field: 'recid', caption: 'ID' }], 'Add search #1'); + $().w2grid({ name: 'grid' }); + + w2ui['grid'].addSearch({ field: 'recid', caption: 'ID' }); + deepEqual(w2ui['grid'].searches, [{ field: 'recid', caption: 'ID' }], 'Add search #1'); - w2ui['grid'].addSearch('recid', { field: 'recid2', caption: 'ID' }); - deepEqual(w2ui['grid'].searches, [{ field: 'recid2', caption: 'ID' }, { field: 'recid', caption: 'ID' }], 'Add search #2'); + w2ui['grid'].addSearch('recid', { field: 'recid2', caption: 'ID' }); + deepEqual(w2ui['grid'].searches, [{ field: 'recid2', caption: 'ID' }, { field: 'recid', caption: 'ID' }], 'Add search #2'); - w2ui['grid'].removeSearch('recid', 'recid2'); - deepEqual(w2ui['grid'].searches, [], 'Remove search #1'); + w2ui['grid'].removeSearch('recid', 'recid2'); + deepEqual(w2ui['grid'].searches, [], 'Remove search #1'); - w2ui['grid'].addSearch([{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }]); - deepEqual(w2ui['grid'].searches, [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }], 'Add search #3'); + w2ui['grid'].addSearch([{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }]); + deepEqual(w2ui['grid'].searches, [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }], 'Add search #3'); - equal(w2ui['grid'].removeSearch('recid', 'recid2'), 2, 'Remove search #2'); + equal(w2ui['grid'].removeSearch('recid', 'recid2'), 2, 'Remove search #2'); - $().w2destroy('grid'); + $().w2destroy('grid'); }); test( "w2grid().hideSearch(), w2grid.showSearch()", function() { - $().w2grid({ - name: 'grid', - searches: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] - }); - - equal(w2ui['grid'].hideSearch('recid', 'recid2'), 2, 'Hide search #1'); - equal(w2ui['grid'].hideSearch('recid', 'recid2'), 0, 'Hide search #2'); - equal(w2ui['grid'].showSearch('recid', 'recid2'), 2, 'Show search #1'); - equal(w2ui['grid'].showSearch('recid', 'recid2'), 0, 'Show search #2'); - - $().w2destroy('grid'); + $().w2grid({ + name: 'grid', + searches: [{ field: 'recid', caption: 'ID' }, { field: 'recid2', caption: 'ID' }] + }); + + equal(w2ui['grid'].hideSearch('recid', 'recid2'), 2, 'Hide search #1'); + equal(w2ui['grid'].hideSearch('recid', 'recid2'), 0, 'Hide search #2'); + equal(w2ui['grid'].showSearch('recid', 'recid2'), 2, 'Show search #1'); + equal(w2ui['grid'].showSearch('recid', 'recid2'), 0, 'Show search #2'); + + $().w2destroy('grid'); }); \ No newline at end of file diff --git a/test/qunit/tests/w2utils.js b/test/qunit/tests/w2utils.js index 78c69f60e..a09c92b7e 100644 --- a/test/qunit/tests/w2utils.js +++ b/test/qunit/tests/w2utils.js @@ -2,295 +2,295 @@ // -- Unit Tests: w2utils test( "w2utils.formatNumber()", function () { - var values = { - '1,000' : '1000', - '1,000.01' : '1000.01', - '1,000.0001' : '1000.0001' - } - equal( w2utils.formatNumber(), '', "- no argument -" ); - equal( w2utils.formatNumber(''), '', "- blank -" ); - equal( w2utils.formatNumber(null), '', "- null -" ); - equal( w2utils.formatNumber(undefined), '', "- undefined -" ); - equal( w2utils.formatNumber({}), '', "- object -" ); - equal( w2utils.formatNumber([]), '', "- array -" ); + var values = { + '1,000' : '1000', + '1,000.01' : '1000.01', + '1,000.0001' : '1000.0001' + } + equal( w2utils.formatNumber(), '', "- no argument -" ); + equal( w2utils.formatNumber(''), '', "- blank -" ); + equal( w2utils.formatNumber(null), '', "- null -" ); + equal( w2utils.formatNumber(undefined), '', "- undefined -" ); + equal( w2utils.formatNumber({}), '', "- object -" ); + equal( w2utils.formatNumber([]), '', "- array -" ); - for (var v in values) { - equal( w2utils.formatNumber(values[v]), v, 'Test: ' + values[v] + ' = ' + v); - } + for (var v in values) { + equal( w2utils.formatNumber(values[v]), v, 'Test: ' + values[v] + ' = ' + v); + } }); test( "w2utils.size()", function() { - var values = { - '' : 0, - '1 Bt' : 1, - '512 Bt' : 512, - '1023 Bt' : 1023, - '1.0 KB' : 1024, - '1.4 KB' : 1500, - '1023.9 KB' : 1024*1024-1, - '1.0 MB' : 1024*1024+1, - '2.1 MB' : 1024*1024*2.1, - '2.5 GB' : 1024*1024*1024*2.5, - '2.9 TB' : 1024*1024*1024*1024*2.99 - } - equal( w2utils.size(), '', "- no argument -" ); - equal( w2utils.size(''), '', "- blank -" ); - equal( w2utils.size(null), '', "- null -" ); - equal( w2utils.size(undefined), '', "- undefined -" ); - equal( w2utils.size({}), '', "- object -" ); - equal( w2utils.size([]), '', "- array -" ); + var values = { + '' : 0, + '1 Bt' : 1, + '512 Bt' : 512, + '1023 Bt' : 1023, + '1.0 KB' : 1024, + '1.4 KB' : 1500, + '1023.9 KB' : 1024*1024-1, + '1.0 MB' : 1024*1024+1, + '2.1 MB' : 1024*1024*2.1, + '2.5 GB' : 1024*1024*1024*2.5, + '2.9 TB' : 1024*1024*1024*1024*2.99 + } + equal( w2utils.size(), '', "- no argument -" ); + equal( w2utils.size(''), '', "- blank -" ); + equal( w2utils.size(null), '', "- null -" ); + equal( w2utils.size(undefined), '', "- undefined -" ); + equal( w2utils.size({}), '', "- object -" ); + equal( w2utils.size([]), '', "- array -" ); - for (var v in values) { - equal( w2utils.size(values[v]), v, 'Test: ' + values[v] + ' = ' + v); - } + for (var v in values) { + equal( w2utils.size(values[v]), v, 'Test: ' + values[v] + ' = ' + v); + } }); test( "w2utils.isInt()", function() { - var values = { - 1 : true, - 0 : true, - '2' : true, - '-1' : true, - '+1' : true, - '1.' : false, - '1.0' : false, - '1.0.0' : false, - '1-0' : false, - '--1' : false, - '1--' : false, - '1,000' : false // should have no commas - } - ok( w2utils.isInt() === false, "- no argument -" ); - ok( w2utils.isInt('') === false, "- blank -" ); - ok( w2utils.isInt(null) === false, "- null -" ); - ok( w2utils.isInt(undefined) === false, "- undefined -" ); - ok( w2utils.isInt({}) === false, "- object -" ); - ok( w2utils.isInt([]) === false, "- array -" ); - for (var v in values) { - ok( w2utils.isInt(v) === values[v], 'Test: ' + v); - } + var values = { + 1 : true, + 0 : true, + '2' : true, + '-1' : true, + '+1' : true, + '1.' : false, + '1.0' : false, + '1.0.0' : false, + '1-0' : false, + '--1' : false, + '1--' : false, + '1,000' : false // should have no commas + } + ok( w2utils.isInt() === false, "- no argument -" ); + ok( w2utils.isInt('') === false, "- blank -" ); + ok( w2utils.isInt(null) === false, "- null -" ); + ok( w2utils.isInt(undefined) === false, "- undefined -" ); + ok( w2utils.isInt({}) === false, "- object -" ); + ok( w2utils.isInt([]) === false, "- array -" ); + for (var v in values) { + ok( w2utils.isInt(v) === values[v], 'Test: ' + v); + } }); test( "w2utils.isFloat()", function() { - var values = { - 1 : true, - 0 : true, - 1.0e3 : true, - 'x' : false, - '-1x' : false, - 'x-1' : false, - '2' : true, - '-1' : true, - '+1' : true, - '1.' : true, - '1.0' : true, - '1.0.0' : false, - '1-0' : false, - '--1' : false, - '1--' : false, - '1,000' : false, - '3.0E+2' : true, - '3.0E-2' : true - } - ok( w2utils.isFloat() === false, "- no argument -" ); - ok( w2utils.isFloat('') === false, "- blank -" ); - ok( w2utils.isFloat(null) === false, "- null -" ); - ok( w2utils.isFloat(undefined) === false, "- undefined -" ); - ok( w2utils.isFloat({}) === false, "- object -" ); - ok( w2utils.isFloat([]) === false, "- array -" ); - ok( w2utils.isFloat(1/0) === true, "- +Infinity is a float -" ); - ok( w2utils.isFloat(-1/0) === true, "- -Infinity is a float -" ); - ok( w2utils.isFloat(0/0) === false, "- NaN is NOT a float -" ); + var values = { + 1 : true, + 0 : true, + 1.0e3 : true, + 'x' : false, + '-1x' : false, + 'x-1' : false, + '2' : true, + '-1' : true, + '+1' : true, + '1.' : true, + '1.0' : true, + '1.0.0' : false, + '1-0' : false, + '--1' : false, + '1--' : false, + '1,000' : false, + '3.0E+2' : true, + '3.0E-2' : true + } + ok( w2utils.isFloat() === false, "- no argument -" ); + ok( w2utils.isFloat('') === false, "- blank -" ); + ok( w2utils.isFloat(null) === false, "- null -" ); + ok( w2utils.isFloat(undefined) === false, "- undefined -" ); + ok( w2utils.isFloat({}) === false, "- object -" ); + ok( w2utils.isFloat([]) === false, "- array -" ); + ok( w2utils.isFloat(1/0) === true, "- +Infinity is a float -" ); + ok( w2utils.isFloat(-1/0) === true, "- -Infinity is a float -" ); + ok( w2utils.isFloat(0/0) === false, "- NaN is NOT a float -" ); - for (var v in values) { - ok( w2utils.isFloat(v) === values[v], 'Test: ' + v); - } + for (var v in values) { + ok( w2utils.isFloat(v) === values[v], 'Test: ' + v); + } }); test( "w2utils.isMoney() - Default Format", function() { - var values = { - 1 : true, - 0 : true, - '2' : true, - '-1' : true, - '+1' : true, - '1.' : false, - '1.0' : true, - '1.0.0' : false, - '1-0' : false, - '--1' : false, - '1--' : false, - '1,000' : true, - '$4.00' : true, - '$4,000' : true, - '$-4,000' : true, - '$+4,000' : true, - '1 000' : false, - '4.0€' : false, - '4 000€' : false, - '-4 000€' : false, - '+4 000€' : false - } - ok( w2utils.isMoney() === false, "- no argument -" ); - ok( w2utils.isMoney('') === false, "- blank -" ); - ok( w2utils.isMoney(null) === false, "- null -" ); - ok( w2utils.isMoney(undefined) === false, "- undefined -" ); - ok( w2utils.isMoney({}) === false, "- object -" ); - ok( w2utils.isMoney([]) === false, "- array -" ); - for (var v in values) { - ok( w2utils.isMoney(v) === values[v], 'Test: ' + v); - } + var values = { + 1 : true, + 0 : true, + '2' : true, + '-1' : true, + '+1' : true, + '1.' : false, + '1.0' : true, + '1.0.0' : false, + '1-0' : false, + '--1' : false, + '1--' : false, + '1,000' : true, + '$4.00' : true, + '$4,000' : true, + '$-4,000' : true, + '$+4,000' : true, + '1 000' : false, + '4.0€' : false, + '4 000€' : false, + '-4 000€' : false, + '+4 000€' : false + } + ok( w2utils.isMoney() === false, "- no argument -" ); + ok( w2utils.isMoney('') === false, "- blank -" ); + ok( w2utils.isMoney(null) === false, "- null -" ); + ok( w2utils.isMoney(undefined) === false, "- undefined -" ); + ok( w2utils.isMoney({}) === false, "- object -" ); + ok( w2utils.isMoney([]) === false, "- array -" ); + for (var v in values) { + ok( w2utils.isMoney(v) === values[v], 'Test: ' + v); + } }); test( "w2utils.isMoney() - EU Format", function() { - // $\€\£\¥ - $.extend(w2utils.settings, { currencyPrefix: "", currencySuffix: "€", groupSymbol : " " }); - var values = { - 1 : true, - 0 : true, - '2' : true, - '-1' : true, - '+1' : true, - '1.' : false, - '1.0' : true, - '1.0.0' : false, - '1-0' : false, - '--1' : false, - '1--' : false, - '$4.00' : false, - '$4,000' : false, - '$-4,000' : false, - '$+4,000' : false, - '1 000' : true, - '4.00€' : true, - '4 000€' : true, - '-4 000€' : true, - '+4 000€' : true, - } - ok( w2utils.isMoney() === false, "- no argument -" ); - ok( w2utils.isMoney('') === false, "- blank -" ); - ok( w2utils.isMoney(null) === false, "- null -" ); - ok( w2utils.isMoney(undefined) === false, "- undefined -" ); - ok( w2utils.isMoney({}) === false, "- object -" ); - ok( w2utils.isMoney([]) === false, "- array -" ); - for (var v in values) { - ok( w2utils.isMoney(v) === values[v], 'Test: ' + v); - } - $.extend(w2utils.settings, { currencyPrefix: "$", currencySuffix: "", groupSymbol : "," }); + // $\€\£\¥ + $.extend(w2utils.settings, { currencyPrefix: "", currencySuffix: "€", groupSymbol : " " }); + var values = { + 1 : true, + 0 : true, + '2' : true, + '-1' : true, + '+1' : true, + '1.' : false, + '1.0' : true, + '1.0.0' : false, + '1-0' : false, + '--1' : false, + '1--' : false, + '$4.00' : false, + '$4,000' : false, + '$-4,000' : false, + '$+4,000' : false, + '1 000' : true, + '4.00€' : true, + '4 000€' : true, + '-4 000€' : true, + '+4 000€' : true, + } + ok( w2utils.isMoney() === false, "- no argument -" ); + ok( w2utils.isMoney('') === false, "- blank -" ); + ok( w2utils.isMoney(null) === false, "- null -" ); + ok( w2utils.isMoney(undefined) === false, "- undefined -" ); + ok( w2utils.isMoney({}) === false, "- object -" ); + ok( w2utils.isMoney([]) === false, "- array -" ); + for (var v in values) { + ok( w2utils.isMoney(v) === values[v], 'Test: ' + v); + } + $.extend(w2utils.settings, { currencyPrefix: "$", currencySuffix: "", groupSymbol : "," }); }); test( "w2utils.isDate()", function() { - ok( w2utils.isDate('1/31/2013', 'mm/dd/yyyy') === true, "'1/31/2013', 'mm/dd/yyyy'" ); - ok( w2utils.isDate('1.31.2013', 'mm.dd.yyyy') === true, "'1.31.2013', 'mm.dd.yyyy'" ); - ok( w2utils.isDate('1-31-2013', 'mm-dd-yyyy') === true, "'1-31-2013', 'mm-dd-yyyy'" ); - ok( w2utils.isDate('31/1/2013', 'dd/mm/yyyy') === true, "'31/1/2013', 'dd/mm/yyyy'" ); - ok( w2utils.isDate('31.1.2013', 'dd.mm.yyyy') === true, "'31.1.2013', 'dd.mm.yyyy'" ); - ok( w2utils.isDate('31-1-2013', 'dd-mm-yyyy') === true, "'31-1-2013', 'dd-mm-yyyy'" ); - ok( w2utils.isDate('2013/31/1', 'yyyy/dd/mm') === true, "'2013/31/1', 'yyyy/dd/mm'" ); - ok( w2utils.isDate('2013.31.1', 'yyyy.dd.mm') === true, "'2013.31.1', 'yyyy.dd.mm'" ); - ok( w2utils.isDate('2013-31-1', 'yyyy-dd-mm') === true, "'2013-31-1', 'yyyy-dd-mm'" ); - ok( w2utils.isDate('2013/1/31', 'yyyy/mm/dd') === true, "'2013/1/31', 'yyyy/mm/dd'" ); - ok( w2utils.isDate('2013.1.31', 'yyyy.mm.dd') === true, "'2013.1.31', 'yyyy.mm.dd'" ); - ok( w2utils.isDate('2013-1-31', 'yyyy-mm-dd') === true, "'2013-1-1', 'yyyy-mm-dd'" ); - ok( w2utils.isDate('13-1-31', 'yy-mm-dd') === true, "'13-1-31', 'yy-mm-dd'" ); - ok( w2utils.isDate('31-1-13', 'dd-mm-yy') === true, "'31-1-13', 'dd-mm-yy'" ); - ok( w2utils.isDate('2/29/2008', 'mm/dd/yyyy') === true, "'2/29/2008', 'mm/dd/yyyy' - Leap Year" ); - ok( w2utils.isDate('2/29/2009', 'mm/dd/yyyy') === false, "'2/29/2009', 'mm/dd/yyyy' - Not Leap Year" ); - ok( w2utils.isDate('24/29/2009', 'mm/dd/yyyy') === false, "'24/29/2009', Wrong date" ); - ok( w2utils.isDate('dk3', '') === false, "'dk3', Wrong date" ); - ok( w2utils.isDate('31 Jan, 2013', 'dd Mon, yyyy') === true, "'1 Jun, 2013', 'dd Mon, yyyy'"); - ok( w2utils.isDate('30 Feb, 2013', 'dd Mon, yyyy') === false, "'30 Feb, 2013', 'dd Mon, yyyy'"); - ok( w2utils.isDate('1 January, 2013', 'dd Month, yyyy') === true, "'1 January, 2013', 'dd Month, yyyy'"); - ok( w2utils.isDate('January 5, 2013', 'Month dd, yyyy') === true, "'January 5, 2013', 'Month dd, yyyy'"); + ok( w2utils.isDate('1/31/2013', 'mm/dd/yyyy') === true, "'1/31/2013', 'mm/dd/yyyy'" ); + ok( w2utils.isDate('1.31.2013', 'mm.dd.yyyy') === true, "'1.31.2013', 'mm.dd.yyyy'" ); + ok( w2utils.isDate('1-31-2013', 'mm-dd-yyyy') === true, "'1-31-2013', 'mm-dd-yyyy'" ); + ok( w2utils.isDate('31/1/2013', 'dd/mm/yyyy') === true, "'31/1/2013', 'dd/mm/yyyy'" ); + ok( w2utils.isDate('31.1.2013', 'dd.mm.yyyy') === true, "'31.1.2013', 'dd.mm.yyyy'" ); + ok( w2utils.isDate('31-1-2013', 'dd-mm-yyyy') === true, "'31-1-2013', 'dd-mm-yyyy'" ); + ok( w2utils.isDate('2013/31/1', 'yyyy/dd/mm') === true, "'2013/31/1', 'yyyy/dd/mm'" ); + ok( w2utils.isDate('2013.31.1', 'yyyy.dd.mm') === true, "'2013.31.1', 'yyyy.dd.mm'" ); + ok( w2utils.isDate('2013-31-1', 'yyyy-dd-mm') === true, "'2013-31-1', 'yyyy-dd-mm'" ); + ok( w2utils.isDate('2013/1/31', 'yyyy/mm/dd') === true, "'2013/1/31', 'yyyy/mm/dd'" ); + ok( w2utils.isDate('2013.1.31', 'yyyy.mm.dd') === true, "'2013.1.31', 'yyyy.mm.dd'" ); + ok( w2utils.isDate('2013-1-31', 'yyyy-mm-dd') === true, "'2013-1-1', 'yyyy-mm-dd'" ); + ok( w2utils.isDate('13-1-31', 'yy-mm-dd') === true, "'13-1-31', 'yy-mm-dd'" ); + ok( w2utils.isDate('31-1-13', 'dd-mm-yy') === true, "'31-1-13', 'dd-mm-yy'" ); + ok( w2utils.isDate('2/29/2008', 'mm/dd/yyyy') === true, "'2/29/2008', 'mm/dd/yyyy' - Leap Year" ); + ok( w2utils.isDate('2/29/2009', 'mm/dd/yyyy') === false, "'2/29/2009', 'mm/dd/yyyy' - Not Leap Year" ); + ok( w2utils.isDate('24/29/2009', 'mm/dd/yyyy') === false, "'24/29/2009', Wrong date" ); + ok( w2utils.isDate('dk3', '') === false, "'dk3', Wrong date" ); + ok( w2utils.isDate('31 Jan, 2013', 'dd Mon, yyyy') === true, "'1 Jun, 2013', 'dd Mon, yyyy'"); + ok( w2utils.isDate('30 Feb, 2013', 'dd Mon, yyyy') === false, "'30 Feb, 2013', 'dd Mon, yyyy'"); + ok( w2utils.isDate('1 January, 2013', 'dd Month, yyyy') === true, "'1 January, 2013', 'dd Month, yyyy'"); + ok( w2utils.isDate('January 5, 2013', 'Month dd, yyyy') === true, "'January 5, 2013', 'Month dd, yyyy'"); - ok( w2utils.isDate(new Date()) === true, "current date"); + ok( w2utils.isDate(new Date()) === true, "current date"); - ok( w2utils.isDate() === false, "- no argument -" ); - ok( w2utils.isDate('') === false, "- blank -" ); - ok( w2utils.isDate(null) === false, "- null -" ); - ok( w2utils.isDate(undefined) === false, "- undefined -" ); - ok( w2utils.isDate({}) === false, "- object -" ); - ok( w2utils.isDate([]) === false, "- array -" ); - ok( w2utils.isDate(1300) === false, "- integer -" ); - ok( w2utils.isDate(500.5) === false, "- number -" ); + ok( w2utils.isDate() === false, "- no argument -" ); + ok( w2utils.isDate('') === false, "- blank -" ); + ok( w2utils.isDate(null) === false, "- null -" ); + ok( w2utils.isDate(undefined) === false, "- undefined -" ); + ok( w2utils.isDate({}) === false, "- object -" ); + ok( w2utils.isDate([]) === false, "- array -" ); + ok( w2utils.isDate(1300) === false, "- integer -" ); + ok( w2utils.isDate(500.5) === false, "- number -" ); }); test( "w2utils.isTime()", function() { - var values = { - 1 : false, - 0 : false, - '2' : false, - '-1' : false, - '+1' : false, - '1.' : false, - '1.0' : false, - '1:0' : false, - ':01' : false, - ' :01' : false, - '1:00' : true, - '01:00' : true, - '001:000' : false, - '001:00' : false, - '01:000' : false, - '1 : 0' : false, - '1PM' : true, - '1AM' : true, - '0AM' : false, - '12AM' : true, - '0PM' : false, - '12PM' : true, - '0:00AM' : true, - '4:00' : true, - '4:000' : false, - '-4:00' : false, - '1:00AM' : true, - '13:00AM' : false, - '12:00AM' : true, - '12:01AM' : true, - '00:00AM' : true, - '13:00PM' : false, - '12:00PM' : true, - '12:01PM' : true, - '00:00PM' : true, - '13:00 PM' : false, - '12:00 PM' : true, - '00:00 PM' : true, - ' 6:30 ' : true, - ' 6 : 30 ' : false, - ' 6 : 3 0 ' : false, - '13:00' : true, - '23:00' : true, - '24:00' : true, - '24:01' : false, - '25:00' : false, - '12:00' : true, - '12:01' : true, - '12:59' : true, - '11:60' : false, - '11:-1' : false, - '11:0' : false, - '11:0AM' : false, - '11:0 AM' : false, - '00:00' : true - }; - ok( w2utils.isTime() === false, "- no argument -" ); - ok( w2utils.isTime('') === false, "- blank -" ); - ok( w2utils.isTime(null) === false, "- null -" ); - ok( w2utils.isTime(undefined) === false, "- undefined -" ); - ok( w2utils.isTime({}) === false, "- object -" ); - ok( w2utils.isTime([]) === false, "- array -" ); - for (var v in values) { - ok( w2utils.isTime(v) === values[v], 'Test: ' + v); - } + var values = { + 1 : false, + 0 : false, + '2' : false, + '-1' : false, + '+1' : false, + '1.' : false, + '1.0' : false, + '1:0' : false, + ':01' : false, + ' :01' : false, + '1:00' : true, + '01:00' : true, + '001:000' : false, + '001:00' : false, + '01:000' : false, + '1 : 0' : false, + '1PM' : true, + '1AM' : true, + '0AM' : false, + '12AM' : true, + '0PM' : false, + '12PM' : true, + '0:00AM' : true, + '4:00' : true, + '4:000' : false, + '-4:00' : false, + '1:00AM' : true, + '13:00AM' : false, + '12:00AM' : true, + '12:01AM' : true, + '00:00AM' : true, + '13:00PM' : false, + '12:00PM' : true, + '12:01PM' : true, + '00:00PM' : true, + '13:00 PM' : false, + '12:00 PM' : true, + '00:00 PM' : true, + ' 6:30 ' : true, + ' 6 : 30 ' : false, + ' 6 : 3 0 ' : false, + '13:00' : true, + '23:00' : true, + '24:00' : true, + '24:01' : false, + '25:00' : false, + '12:00' : true, + '12:01' : true, + '12:59' : true, + '11:60' : false, + '11:-1' : false, + '11:0' : false, + '11:0AM' : false, + '11:0 AM' : false, + '00:00' : true + }; + ok( w2utils.isTime() === false, "- no argument -" ); + ok( w2utils.isTime('') === false, "- blank -" ); + ok( w2utils.isTime(null) === false, "- null -" ); + ok( w2utils.isTime(undefined) === false, "- undefined -" ); + ok( w2utils.isTime({}) === false, "- object -" ); + ok( w2utils.isTime([]) === false, "- array -" ); + for (var v in values) { + ok( w2utils.isTime(v) === values[v], 'Test: ' + v); + } }); test( "w2utils.base64encode(), w2utils.base64decode()", function() { - ok( - w2utils.base64decode(w2utils.base64encode('Some text')) === 'Some text', - "Simple text" - ); - ok( - w2utils.base64decode(w2utils.base64encode('~!@#$%^&*()_+|}{":?><`;,./\\')) === '~!@#$%^&*()_+|}{":?><`;,./\\', - "Text with special characters" - ); + ok( + w2utils.base64decode(w2utils.base64encode('Some text')) === 'Some text', + "Simple text" + ); + ok( + w2utils.base64decode(w2utils.base64encode('~!@#$%^&*()_+|}{":?><`;,./\\')) === '~!@#$%^&*()_+|}{":?><`;,./\\', + "Text with special characters" + ); }); \ No newline at end of file diff --git a/test/sidebar-old.html b/test/sidebar-old.html index 0c88ebbcf..695387ad7 100644 --- a/test/sidebar-old.html +++ b/test/sidebar-old.html @@ -5,59 +5,59 @@ - + \ No newline at end of file diff --git a/test/sidebar.html b/test/sidebar.html index ae1fd7147..e89db6225 100644 --- a/test/sidebar.html +++ b/test/sidebar.html @@ -7,82 +7,82 @@ - + \ No newline at end of file diff --git a/test/tabs-edit-grid.html b/test/tabs-edit-grid.html index aa76924b5..2abb56df6 100644 --- a/test/tabs-edit-grid.html +++ b/test/tabs-edit-grid.html @@ -5,105 +5,105 @@ -
          -
          - -
          -
          -
          First Name:
          -
          - -
          -
          Last Name:
          -
          - -
          -
          -
          - - -
          -
          -
          +
          +
          + +
          +
          +
          First Name:
          +
          + +
          +
          Last Name:
          +
          + +
          +
          +
          + + +
          +
          +
          \ No newline at end of file diff --git a/test/tabs-old.html b/test/tabs-old.html index 6e1d06e6b..5c89a585c 100644 --- a/test/tabs-old.html +++ b/test/tabs-old.html @@ -4,29 +4,29 @@ -
          - +
          + -
          -
          - +
          +
          + \ No newline at end of file diff --git a/test/toolbar-old.html b/test/toolbar-old.html index 268e6f634..02f42e093 100644 --- a/test/toolbar-old.html +++ b/test/toolbar-old.html @@ -4,33 +4,33 @@ -
          +
          -
          +
          \ No newline at end of file diff --git a/w2ui.jquery.json b/w2ui.jquery.json index 921502358..fcdb18bfe 100644 --- a/w2ui.jquery.json +++ b/w2ui.jquery.json @@ -24,15 +24,15 @@ "overlay" ], "author": { - "name" : "Vitali Malinouski", - "url" : "http://w2ui.com", - "email" : "vitmalina@gmail.com" + "name" : "Vitali Malinouski", + "url" : "http://w2ui.com", + "email" : "vitmalina@gmail.com" }, "maintainers": [ { - "name" : "Vitali Malinouski", - "url" : "http://w2ui.com", - "email" : "vitmalina@gmail.com" + "name" : "Vitali Malinouski", + "url" : "http://w2ui.com", + "email" : "vitmalina@gmail.com" } ], "licenses": [ @@ -41,11 +41,11 @@ "url": "https://github.com/vitmalina/w2ui/blob/master/license.txt" } ], - "bugs" : "https://github.com/vitmalina/w2ui/issues", - "homepage" : "http://w2ui.com/web", - "docs" : "http://w2ui.com/web/docs", - "download" : "http://w2ui.com/web/downloads/w2ui-1.4.zip", - "dependencies": { + "bugs" : "https://github.com/vitmalina/w2ui/issues", + "homepage" : "http://w2ui.com/web", + "docs" : "http://w2ui.com/web/docs", + "download" : "http://w2ui.com/web/downloads/w2ui-1.4.zip", + "dependencies" : { "jquery": ">=1.9" } } \ No newline at end of file