From d503c41cce27624a59e9b6d9866fb8823b8d426f Mon Sep 17 00:00:00 2001 From: Konstantin Leonov Date: Wed, 24 Sep 2014 12:04:20 +0300 Subject: [PATCH] Some changes for 2.4.89 The quantity of SQL of requests for each ad was reduced. Indices for plugin's database tables were added. The bug of data loading into the grid is fixed. --- .idea/simple-ads-manager.iml | 14 +- .idea/webResources.xml | 21 +- ad.class.php | 203 +- admin.class.php | 58 +- css/sam-admin-edit.css | 2 +- css/w2ui.css | 2753 ++++ css/w2ui.min.css | 3 +- js/sam-admin-edit-item.js | 9 +- js/sam-admin-edit-item.min.js | 2 +- js/sam-layout.js | 4 +- js/sam-layout.min.js | 2 +- js/w2ui.js | 24051 ++++++++++++++++++-------------- js/w2ui.min.js | 2 +- readme.txt | 9 +- sam-ajax-admin.php | 24 + sam-ajax-loader.php | 4 +- sam-ajax.php | 1 + sam.class.php | 14 +- simple-ads-manager.php | 2 +- updater.class.php | 100 +- 20 files changed, 16459 insertions(+), 10819 deletions(-) create mode 100644 css/w2ui.css diff --git a/.idea/simple-ads-manager.iml b/.idea/simple-ads-manager.iml index d7dc8c4..aaf65e3 100644 --- a/.idea/simple-ads-manager.iml +++ b/.idea/simple-ads-manager.iml @@ -1,13 +1,19 @@ - - - - + + + + + + + + + + diff --git a/.idea/webResources.xml b/.idea/webResources.xml index a9bf725..f6e673a 100644 --- a/.idea/webResources.xml +++ b/.idea/webResources.xml @@ -1,22 +1,3 @@ - - - - - - - - - - - - - - - - - - - - + diff --git a/ad.class.php b/ad.class.php index a891cfe..3dbceee 100644 --- a/ad.class.php +++ b/ad.class.php @@ -147,6 +147,7 @@ class SamAdPlace { public $cid = null; private $clauses; private $force; + public $sql = ''; public function __construct($args = null, $useCodes = false, $crawler = false, $clauses = null, $ajax = false) { global $SAM_Query; @@ -159,7 +160,7 @@ public function __construct($args = null, $useCodes = false, $crawler = false, $ else $this->clauses = $clauses; $this->force = $ajax; - $this->ad = $this->buildAd($this->args, $this->useCodes); + $this->ad = $this->buildAd2($this->args, $this->useCodes); } private function getSettings() { @@ -417,7 +418,7 @@ private function buildAd( $args = null, $useCodes = false ) { $output = ob_get_contents(); ob_end_clean(); } - else $output = self::prepareCodes($ad['ad_code'], $rId); + else self::prepareCodes($ad['ad_code'], $rId); } //if(!$this->crawler && !is_admin()) //$wpdb->query("UPDATE $aTable SET $aTable.ad_hits = $aTable.ad_hits+1, $aTable.ad_weight_hits = $aTable.ad_weight_hits+1 WHERE $aTable.id = {$ad['id']}"); @@ -433,6 +434,204 @@ private function buildAd( $args = null, $useCodes = false ) { elseif($useCodes) $output = $place['code_before'].$output.$place['code_after']; return $output; } + + private function buildAd2( $args = null, $useCodes = false ) { + if(is_null($args)) return ''; + if(empty($args['id']) && empty($args['name'])) return ''; + if( is_null($this->clauses) ) return ''; + + $settings = self::getSettings(); + $data = intval($useCodes); + $rId = rand(1111, 9999); + if($settings['adCycle'] == 0) $cycle = 1000; + else $cycle = $settings['adCycle']; + $el = isset($settings['errorlogFS']); + + global $wpdb; + $pTable = $wpdb->prefix . "sam_places"; + $aTable = $wpdb->prefix . "sam_ads"; + $eTable = $wpdb->prefix . "sam_errors"; + + $whereClause = $this->clauses['WC']; + $whereClauseT = $this->clauses['WCT']; + $whereClauseW = $this->clauses['WCW']; + $whereClause2W = $this->clauses['WC2W']; + + if(!empty($args['id'])) $pId = "sp.id = {$args['id']}"; + else $pId = "sp.name = '{$args['name']}'"; + + $output = ""; + + $aSql = " +SELECT + @pid := sp.id AS pid, + 0 AS aid, + sp.name, + sp.patch_source AS code_mode, + @code_before := sp.code_before AS code_before, + @code_after := sp.code_after AS code_after, + @ad_size := IF(sp.place_size = \"custom\", CONCAT(CAST(sp.place_custom_width AS CHAR), \"x\", CAST(sp.place_custom_height AS CHAR)), sp.place_size) AS ad_size, + sp.patch_code AS ad_code, + sp.patch_img AS ad_img, + \"\" AS ad_alt, + 0 AS ad_no, + sp.patch_link AS ad_target, + 0 AS ad_swf, + \"\" AS ad_swf_flashvars, + \"\" AS ad_swf_params, + \"\" AS ad_swf_attributes, + sp.patch_adserver AS ad_adserver, + sp.patch_dfp AS ad_dfp, + 0 AS count_clicks, + 0 AS code_type, + IF((sp.patch_source = 1 AND sp.patch_adserver) OR sp.patch_source = 2, -1, 1) AS ad_cycle, + @aca := IFNULL((SELECT AVG(wsa.ad_weight_hits*10/(wsa.ad_weight*$cycle)) FROM $aTable wsa WHERE wsa.pid = @pid AND wsa.trash IS NOT TRUE), 0) AS aca +FROM $pTable sp +WHERE $pId AND sp.trash IS FALSE +UNION +SELECT + sa.pid, + sa.id AS aid, + sa.name, + sa.code_mode, + @code_before AS code_before, + @code_after AS code_after, + @ad_size AS ad_size, + sa.ad_code, + sa.ad_img, + sa.ad_alt, + sa.ad_no, + sa.ad_target, + sa.ad_swf, + sa.ad_swf_flashvars, + sa.ad_swf_params, + sa.ad_swf_attributes, + 0 AS ad_adserver, + 0 AS ad_dfp, + sa.count_clicks, + sa.code_type, + IF(sa.ad_weight, (sa.ad_weight_hits*10/(sa.ad_weight*$cycle)), 0) AS ad_cycle, + @aca AS aca +FROM $aTable sa +WHERE sa.pid = @pid AND sa.trash IS FALSE AND $whereClause $whereClauseT $whereClauseW +ORDER BY ad_cycle +LIMIT 1;"; + + $ad = $wpdb->get_row($aSql, ARRAY_A); + + if($ad === false) { + if($el) self::errorWrite($eTable, $aTable, $aSql, $ad, $wpdb->last_error); + return ''; + } + + if((integer)$ad['aca'] == 1) { + $wpdb->update($aTable, array('ad_weight_hits' => 0), array('pid' => $ad['pid']), array("%d"), array("%d")); + $ad = $wpdb->get_row($aSql, ARRAY_A); + } + + $this->pid = $ad['pid']; + $this->id = $ad['aid']; + $this->cid = "c{$rId}_{$this->id}_{$this->pid}"; + //$this->sql = $aSql; + + // DFP + if($ad['code_mode'] == 2) { + if(($settings['useDFP'] == 1) && !empty($settings['dfpPub'])) { + $output = ""."\n"; + $output .= ""."\n"; + if($useCodes) + $output = (is_array($useCodes)) ? $useCodes['before'].$output.$useCodes['after'] : $ad['code_before'].$output.$ad['code_after']; + + $output = "
{$output}
"; + } + else $output = ''; + + return $output; + } + + // Ad Server (Blocking output of contained ads) + if(($ad['code_mode'] == 1) && (abs($ad['ad_adserver']) == 1)) { + $output = self::prepareCodes($ad['ad_code'], $rId); + if($useCodes) + $output = (is_array($useCodes)) ? $useCodes['before'].$output.$useCodes['after'] : $ad['code_before'].$output.$ad['code_after']; + $output = "
{$output}
"; + + return $output; + } + + // JS Loading + if(isset($settings['adShow']) && ($settings['adShow'] == 'js') && !$this->force) + return "
"; + + // Image and Code Modes + if($ad['code_mode'] == 0) { + if((int)$ad['ad_swf']) { + $id = "ad-".$ad['aid'].'-'.$rId; + $file = $ad['ad_img']; + $sizes = self::getSize($ad['ad_size'], null, null); + $width = $sizes['width']; + $height = $sizes['height']; + $flashvars = (!empty($ad['ad_swf_flashvars'])) ? $ad['ad_swf_flashvars'] : '{}'; + $params = (!empty($ad['ad_swf_params'])) ? $ad['ad_swf_params'] : '{}'; + $attributes = (!empty($ad['ad_swf_attributes'])) ? $ad['ad_swf_attributes'] : '{}'; + $text = 'Flash ad ID:'.$ad['aid']; //__('Flash ad').' ID:'.$ad['aid']; + $output = " + +
$text
+ "; + } + else { + $outId = ((int) $ad['count_clicks'] == 1) ? " id='a".rand(10, 99)."_".$ad['aid']."' class='sam_ad'" : ''; + $aStart =''; + $aEnd =''; + $iTag = ''; + if(!empty($settings['adDisplay'])) $target = '_'.$settings['adDisplay']; + else $target = '_blank'; + if(!empty($ad['ad_target'])) { + //$aStart = ((in_array((integer)$ad['ad_no'], array(2,3))) ? '' : '').""; + //$aEnd = "".(in_array((integer)$ad['ad_no'], array(2,3))) ? '' : ''; + $aStart = ""; + $aEnd = ""; + } + if(!empty($ad['ad_img'])) $iTag = "{$ad["; + $output = $aStart.$iTag.$aEnd; + } + } + elseif($ad['code_mode'] == 1) { + if($ad['code_type'] == 1) { + ob_start(); + eval('?>'.$ad['ad_code'].'sql = $output; + + $output = "
{$output}
"; + + if(is_array($useCodes)) $output = $useCodes['before'].$output.$useCodes['after']; + elseif($useCodes) $output = $ad['code_before'].$output.$ad['code_after']; + + // Updating Display Cycle + if(!$this->crawler && !is_admin()) { + $sSql = "UPDATE $aTable sa SET sa.ad_weight_hits = sa.ad_weight_hits + 1 WHERE sa.id = %d;"; + $wpdb->query($wpdb->prepare($sSql, $ad['aid'])); + } + + return $output; + } } } diff --git a/admin.class.php b/admin.class.php index 03c85a0..4534b3a 100644 --- a/admin.class.php +++ b/admin.class.php @@ -16,7 +16,7 @@ class SimpleAdsManagerAdmin extends SimpleAdsManager { public function __construct() { parent::__construct(); - global $wp_version, $sam_tables_defs; + global $wp_version, $sam_tables_defs, $wpdb; if ( function_exists( 'load_plugin_textdomain' ) ) load_plugin_textdomain( SAM_DOMAIN, false, basename( SAM_PATH ) . '/langs/' ); @@ -24,7 +24,7 @@ public function __construct() { if(!is_dir(SAM_AD_IMG)) mkdir(SAM_AD_IMG); $this->settingsTabs = array(); - $sam_tables_defs = self::getTablesDefs(); + $sam_tables_defs = self::getTablesDefs($wpdb->prefix); register_activation_hook(SAM_MAIN_FILE, array(&$this, 'onActivate')); register_deactivation_hook(SAM_MAIN_FILE, array(&$this, 'onDeactivate')); @@ -247,7 +247,7 @@ private function updateDB() { $this->getVersions(true); } - public function getTablesDefs() { + public function getTablesDefs( $prefix = 'wp_' ) { $pTableDef = array( 'id' => array('Type' => "int(11)", 'Null' => 'NO', 'Key' => 'PRI', 'Default' => '', 'Extra' => 'auto_increment'), 'name' => array('Type' => "varchar(255)", 'Null' => 'NO', 'Key' => '', 'Default' => '', 'Extra' => ''), @@ -389,12 +389,50 @@ public function getTablesDefs() { 'event_type' => array('Type' => 'tinyint(1)', 'Null' => 'YES', 'Key' => '', 'Default' => '', 'Extra' => '') ); + $pIndexDef = array( + 'UK_'.$prefix.'places' => array( + 'id' => array('Non_unique' => 0, 'Seq_in_index' => 1, 'Column_name' => 'id') + ) + ); + + $aIndexDef = array( + 'UK_'.$prefix.'ads' => array( + 'pid' => array('Non_unique' => 0, 'Seq_in_index' => 1, 'Column_name' => 'pid'), + 'id' => array('Non_unique' => 0, 'Seq_in_index' => 2, 'Column_name' => 'id') + ) + ); + + $zIndexDef = array( + 'UK_'.$prefix.'zones' => array( + 'id' => array('Non_unique' => 0, 'Seq_in_index' => 1, 'Column_name' => 'id') + ) + ); + + $bIndexDef = array( + 'UK_'.$prefix.'blocks' => array( + 'id' => array('Non_unique' => 0, 'Seq_in_index' => 1, 'Column_name' => 'id') + ) + ); + + $sIndexDef = array( + 'IDX_'.$prefix.'stats' => array( + 'id' => array('Non_unique' => 1, 'Seq_in_index' => 1, 'Column_name' => 'id'), + 'pid' => array('Non_unique' => 1, 'Seq_in_index' => 2, 'Column_name' => 'pid'), + 'event_time' => array('Non_unique' => 1, 'Seq_in_index' => 3, 'Column_name' => 'event_time') + ) + ); + return array( 'places' => $pTableDef, 'ads' => $aTableDef, 'zones' => $zTableDef, 'blocks' => $bTableDef, - 'stats' => $sTableDef + 'stats' => $sTableDef, + 'idxPlaces' => $pIndexDef, + 'idxAds' => $aIndexDef, + 'idxZones' => $zIndexDef, + 'idxBlocks' => $bIndexDef, + 'idxStats' => $sIndexDef ); } @@ -803,7 +841,7 @@ public function loadScripts($hook) { wp_enqueue_style('ComboGrid', SAM_URL.'css/jquery.ui.combogrid.css', false, '1.6.3'); wp_enqueue_style('wp-pointer'); wp_enqueue_style('colorButtons', SAM_URL.'css/color-buttons.css', false, SAM_VERSION); - wp_enqueue_style('W2UI', SAM_URL . 'css/w2ui.min.css', false, '1.3'); + wp_enqueue_style('W2UI', SAM_URL . 'css/w2ui.min.css', false, '1.4.1'); wp_enqueue_style('jqPlot', SAM_URL . 'css/jquery.jqplot.min.css', false, '1.0.2'); $options = parent::getSettings(); @@ -820,7 +858,7 @@ public function loadScripts($hook) { if($options['useSWF']) wp_enqueue_script('swfobject'); wp_enqueue_script('jquery'); wp_enqueue_media(array('post' => null)); - wp_enqueue_script('W2UI', SAM_URL . 'js/w2ui.min.js', array('jquery'), '1.3'); + wp_enqueue_script('W2UI', SAM_URL . 'js/w2ui.min.js', array('jquery'), '1.4.1'); wp_enqueue_script('jquery-ui-core'); wp_enqueue_script('jquery-effects-core'); //wp_enqueue_script('jquery-ui-mouse'); @@ -846,7 +884,7 @@ public function loadScripts($hook) { wp_enqueue_script('pointLabels', SAM_URL . 'js/jqplot.pointLabels.min.js', array('jquery', 'jqPlot'), '1.0.2'); wp_enqueue_script('wp-pointer'); - wp_enqueue_script('adminEditScript', SAM_URL.'js/sam-admin-edit-item.min.js', array('jquery', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'), SAM_VERSION); + wp_enqueue_script('adminEditScript', SAM_URL.'js/sam-admin-edit-item.js', array('jquery', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'), SAM_VERSION); wp_localize_script('adminEditScript', 'samEditorOptions', array( 'places' => array('enabled' => $pointers['places'], 'title' => __('Name of Ads Place', SAM_DOMAIN), 'content' => __('This is not required parameter. But it is strongly recommended to define it if you plan to use Ads Blocks, plugin\'s widgets or autoinserting of ads.', SAM_DOMAIN)), 'ads' => array('enabled' => $pointers['ads'], 'title' => __('Name of Ad', SAM_DOMAIN), 'content' => __('This is not required parameter. But it is strongly recommended to define it if you plan to use Ads Blocks or plugin\'s widgets.', SAM_DOMAIN)), @@ -1479,8 +1517,10 @@ function affiliateLink(str){ str = unescape(str); var r = ''; for(var i = 0; i <
- - doSettingsSections('sam-settings', $this->settingsTabs); ?> + doSettingsSections('sam-settings', $this->settingsTabs); + ?>

'; - } - html += ''+ - resizer + - '
'+ - (col.caption == '' ? ' ' : col.caption) + - '
'+ - ''; - } - } - html += '
 
'; - html += ''; - return html; - } - }, + 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 != null) { + 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; + + // copy & paste + + case 17: // ctrl key + case 91: // cmd key + if (empty) break; + var text = obj.copy(); + $('body').append(''); + $('#_tmp_copy_data').focus().select(); + // remove _tmp_copy_data textarea + $(document).on('keyup', tmp_key_down); + function tmp_key_down() { + $('#_tmp_copy_data').remove(); + $(document).off('keyup', tmp_key_down); + } + break; + + case 88: // x - cut + if (empty) break; + if (event.ctrlKey || event.metaKey) { + setTimeout(function () { obj["delete"](true); }, 100); + } + 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) { + var buffered = this.records.length; + if (this.searchData.length != 0 && !this.url) buffered = this.last.searchIds.length; + 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 (buffered == 0) return; + // if all records in view + var len = this.last.searchIds.length; + if (records.height() > this.recordHeight * (len > 0 ? len : buffered)) 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 (obj.last.userSelect == 'text') return; + if (typeof event == 'undefined') event = { offsetX: 0, offsetY: 0, target: $('#grid_'+ obj.name +'_rec_'+ recid)[0] }; + 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 + // cancel event + if (event.preventDefault) event.preventDefault(); + }, + + 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_'+ recid +'_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 + // copy headers + for (var c in this.columns) { + var col = this.columns[c]; + if (col.hidden === true) continue; + text += '"' + w2utils.stripTags(col.caption ? col.caption : col.field) + '"\t'; + } + text = text.substr(0, text.length-1); // remove last \t + text += '\n'; + // copy selected text + 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(); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, + + refreshCell: function (recid, field) { + var index = this.get(recid, true); + var isSummary = (this.records[index] && this.records[index].recid == recid ? false : true); + var col_ind = this.getColumn(field, true); + var rec = (isSummary ? this.summary[index] : 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, isSummary)); + 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'); + var isSummary = (this.records[ind] && this.records[ind].recid == recid ? false : true); + // 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, isSummary)); + if (isSummary) this.resize(); + } + }, + + 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; + } + //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; + } + + // -- 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.last.state) this.last.state = this.stateSave(true); // initial default state + this.stateRestore(); + 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.which != 1) return; // if not left mouse button + // restore css user-select + if (obj.last.userSelect == 'text') { + delete obj.last.userSelect; + $(obj.box).find('.w2ui-grid-body') + .css('user-select', 'none') + .css('-webkit-user-select', 'none') + .css('-moz-user-select', 'none') + .css('-ms-user-select', 'none'); + $(this.box).on('selectstart', function () { return false; }); + } + // regular record select + if ($(event.target).parents().hasClass('w2ui-head') || $(event.target).hasClass('w2ui-head')) return; + if (obj.last.move && obj.last.move.type == 'expand') return; + // if altKey - alow text selection + if (event.altKey) { + $(obj.box).off('selectstart'); + $(obj.box).find('.w2ui-grid-body') + .css('user-select', 'text') + .css('-webkit-user-select', 'text') + .css('-moz-user-select', 'text') + .css('-ms-user-select', 'text'); + obj.selectNone(); + obj.last.move = { type: 'text-select' }; + obj.last.userSelect = 'text'; + } else { + 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') { + 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 (col.hideable === false) continue; + 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 && obj.show.skipRecords) { + col_html += + ''; + } + col_html += ''+ + ''; + col_html += "
'+ + ' '+ + ''+ + ' '+ + '
'+ + ' '+ + ''+ + ' '+ + '
'+ + '
'+ w2utils.lang('Skip') + + ' '+ w2utils.lang('Records')+ + '
'+ + '
'+ + '
'+ w2utils.lang('Save Grid State') + '
'+ + '
'+ + '
'+ w2utils.lang('Restore Default State') + '
'+ + '
"; + 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 = Math.max(_dragData.numberPreColumnsPresent,targetIntersection( cursorX, offsets, lastWidth )); + + markIntersection( _dragData.targetInt ); + trackGhost( cursorX, cursorY ); + } + + function dragColEnd ( event ) { + _dragData.pressed = false; + + var eventData, + target, + selected, + columnConfig, + 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; + targetColumn = $( _dragData.columns[ Math.min(_dragData.lastInt, _dragData.columns.length - 1) ] ); + target = (_dragData.lastInt < _dragData.columns.length) ? parseInt(targetColumn.attr('col')) : columnConfig.length; + + 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 + $( _dragData.columns[ _dragData.numberPreColumnsPresent ] ).prepend( _dragData.marker.addClass( 'left' ).removeClass( 'right' ) ).css({ position: 'relative' }); + $( _dragData.columns[ _dragData.numberPreColumnsPresent ] ).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'); + } + } + } - 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; - }, + 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; + } + } - 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; - }, + function trackGhost( cursorX, cursorY ){ + $( _dragData.ghost ).css({ + left: cursorX - 10, + top: cursorY - 10 + }); + } - 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.floor(records[0].scrollTop / this.recordHeight + 1); - var t2 = Math.floor(records[0].scrollTop / this.recordHeight + 1) + Math.round(records.height() / this.recordHeight); - 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 (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 () { - $(this).find('td').html('
'); - obj.last.pull_more = true; - obj.last.xhr_offset += obj.limit; - obj.request('get-records'); - }); - } - if (more.find('td').text().indexOf('Load') == -1) { - more.find('td').html('
Load '+ obj.limit + ' 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.markSearchResults === 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); - } - }, + //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; + } + } + }, - getRecordHTML: function (ind, lineNum, summary) { - var rec_html = ''; - // 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 (record.selected && this.selectType == 'row') 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 = record.changed && record.changes[col.field]; - var rec_cell = this.getCellHTML(ind, col_ind, summary); - var addStyle = ''; - if (typeof col.render == 'string') { - var tmp = col.render.toLowerCase().split(':'); - if ($.inArray(tmp[0], ['number', 'int', 'float', 'money', 'percent']) != -1) addStyle = 'text-align: right'; - if ($.inArray(tmp[0], ['date']) != -1) addStyle = 'text-align: right'; - } - var isCellSelected = false; - if (record.selected && $.inArray(col_ind, record.selectedColumns) != -1) isCellSelected = true; - rec_html += ''+ - rec_cell + - ''; - col_ind++; - if (typeof this.columns[col_ind] == 'undefined') break; - } - rec_html += ''; - rec_html += ''; - // if row is expanded (buggy) - // if (record.expanded === true && $('#grid_'+ this.name +'_rec_'+ record.recid +'_expanded_row').length == 0) { - // var tmp = 1 + (this.show.selectColumn ? 1 : 0); - // rec_html += - // ''+ - // (this.show.lineNumbers ? '' : '') + - // '
'+ - // ' '+ - // '
'+ - // ' '+ - // ''; - // } - return rec_html; - }, + columnOnOff: function (el, event, field) { + // 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 { + 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; + } + if (hide) { + setTimeout(function () { + $().w2overlay('', { name: 'searches-'+ this.name }); + obj.toolbar.uncheck('column-on-off'); + }, 100); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + }, - 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.parseField(record, col.field); - var isChanged = record.changed && typeof record.changes[col.field] != 'undefined'; - if (isChanged) data = record.changes[col.field]; - // various renderers - if (data == null || typeof data == 'undefined') data = ''; - if (typeof col.render != 'undefined') { - if (typeof col.render == 'function') { - data = col.render.call(this, record, ind, col_ind); - if (data.length >= 4 && data.substr(0, 4) != ''; - } - 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 ($.inArray(tmp[0], ['number', 'int', 'float', 'money', 'percent']) != -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 (tmp[0] == 'money') { tmp[1] = 2; prefix = w2utils.settings.currencySymbol; } - if (tmp[0] == 'percent') { suffix = '%'; if (tmp[1] !== '0') tmp[1] = 1; } - if (tmp[0] == 'int') { tmp[1] = 0; } - // format - data = '
' + prefix + w2utils.formatNumber(Number(data).toFixed(tmp[1])) + 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 (!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; - }, + 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 })); - getFooterHTML: function () { - return '
'+ - ' '+ - ' '+ - ' '+ - '
'; - }, + // ============================================= + // ------ Toolbar Generic buttons - 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('edit'); else this.toolbar.disable('edit'); - if (sel.length >= 1) this.toolbar.enable('delete'); else this.toolbar.disable('delete'); - } - }, + 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'])); + } + 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]); - lock: function (msg, showSpinner) { - var box = $(this.box).find('> div:first-child'); - setTimeout(function () { w2utils.lock(box, msg, showSpinner); }, 10); - }, + // ============================================= + // ------ Toolbar onClick processing - unlock: function () { - var box = this.box; - setTimeout(function () { w2utils.unlock(box); }, 25); // needed timer so if server fast, it will not flash - }, + 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': + obj.initColumnOnOff(); + 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; + }, - 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; - } - } + 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' + }); + } - $.extend(w2grid.prototype, w2utils.event); - w2obj.grid = w2grid; -})(jQuery); + 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' + }); + }, -/************************************************************************ - * 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 - * - problem with layout.html (see in 1.3) - * - add panel title - * - ************************************************************************/ + 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); + } -(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.onRender = null; - this.onRefresh = null; - this.onResize = null; - this.onDestroy = null - - $.extend(true, this, w2obj.layout, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2layout = function(method) { - if (typeof method === 'object' || !method ) { - // check required parameters - if (!method || typeof method.name == 'undefined') { - console.log('ERROR: The parameter "name" is required but not supplied in $().w2layout().'); - return; - } - if (typeof w2ui[method.name] != 'undefined') { - console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ method.name +').'); - return; - } - if (!w2utils.isAlphaNumeric(method.name)) { - console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); - return; - } - var panels = method.panels; - var object = new w2layout(method); - $.extend(object, { handlers: [], panels: [] }); - // add defined panels panels - for (var p in panels) { - 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 p in { 'top':'', 'left':'', 'main':'', 'preview':'', 'right':'', 'bottom':'' }) { - if (object.get(p) != null) continue; - object.panels[p] = $.extend(true, {}, w2layout.prototype.panel, { type: p, hidden: true, 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' ); - } + var buffered = this.records.length; + if (this.searchData.length != 0 && !this.url) buffered = this.last.searchIds.length; + // 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 = 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 (col.gridMinWidth > 0) { + 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 || this.last.scrollLeft) && 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; - 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; - } + } + 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' || $(el).val() == 'not 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' && ['in', 'not in'].indexOf(sdata.operator) != -1) 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' && ['in', 'not in'].indexOf(sdata.operator) != -1) { + $('#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 (['in', 'not in'].indexOf(sdata.operator) != -1) { + $('#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) { + 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 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: { - type : null, // left, right, top, bottom - size : 100, // width or height depending on panel name - minSize : 20, - 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 - }, + function getGroups () { + var html = ''; + // add empty group at the end + if (obj.columnGroups[obj.columnGroups.length-1].caption != '') obj.columnGroups.push({ caption: '' }); - // alias for content - html: function (panel, data, transition) { - return this.content(panel, data, transition); - }, + 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; + } - content: function (panel, data, transition) { - var obj = this; - var p = this.get(panel); - if (panel == 'css') { - $('#layout_'+ obj.name +'_panel_css').html(''); - return true; - } - if (p == null) return false; - if ($('#layout_'+ this.name + '_panel2_'+ p.type).length > 0) return false; - $('#layout_'+ this.name + '_panel_'+ p.type).scrollTop(0); - if (data == null || typeof data == 'undefined') { - return p.content; - } else { - if (data instanceof jQuery) { - console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); - return false; - } - // remove foreign classes and styles - var tmp = $('#'+ 'layout_'+ this.name + '_panel_'+ panel + ' > .w2ui-panel-content'); - var panelTop = $(tmp).position().top; - tmp.attr('class', 'w2ui-panel-content'); - if (tmp.length > 0 && typeof p.style != 'undefined') tmp[0].style.cssText = p.style; - if (p.content == '') { - p.content = data; - if (!p.hidden) this.refresh(panel); - } else { - p.content = data; - if (!p.hidden) { - if (transition != null && transition != '' && typeof transition != 'undefined') { - // apply transition - var nm = 'layout_'+ this.name + '_panel_'+ p.type; - var div1 = $('#'+ nm + ' > .w2ui-panel-content'); - div1.after('
'); - var div2 = $('#'+ nm + ' > .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 - if (window.navigator.userAgent.indexOf('MSIE')) setTimeout(function () { obj.resize(); }, 100); - }); + 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 () { + var buffered = this.records.length; + if (this.searchData.length != 0 && !this.url) buffered = this.last.searchIds.length; + // larget number works better with chrome, smaller with FF. + if (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 > buffered) limit = 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'); + var buffered = this.records.length; + if (this.searchData.length != 0 && !this.url) buffered = this.last.searchIds.length; + if (buffered == 0 || records.length == 0 || records.height() == 0) return; + if (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() < 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 > buffered) t1 = buffered; + if (t2 > buffered) t2 = 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(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 = (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 > buffered && this.last.pull_more !== true && 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 (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 (!p.hidden) this.refresh(panel); + if (ind >= this.summary.length) return ''; + record = this.summary[ind]; } - } - } - } - // IE Hack - if (window.navigator.userAgent.indexOf('MSIE')) setTimeout(function () { obj.resize(); }, 100); - return true; - }, + 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 + '
'; + } + if (tmp[0] == 'toggle') { + data = '
' + prefix + (data ? 'Yes' : '') + 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 '
'+ + ' '+ + ' '+ + ' '+ + '
'; + }, - 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 - if (window.navigator.userAgent.indexOf('MSIE')) setTimeout(function () { obj.resize(); }, 100); - }); - return true; - } - return false; - }, + 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 + }, + + stateSave: function (returnOnly) { + if (!localStorage) return null; + var state = { + columns : [], + show : $.extend({}, this.show), + last : { + search : this.last.search, + multi : this.last.multi, + logic : this.last.logic, + caption : this.last.caption, + field : this.last.field, + scrollTop : this.last.scrollTop, + scrollLeft : this.last.scrollLeft + }, + sortData : [], + searchData : [] + }; + for (var i in this.columns) { + var col = this.columns[i]; + state.columns.push({ + field : col.field, + hidden : col.hidden, + size : col.size, + sizeCalculated : col.sizeCalculated, + sizeOriginal : col.sizeOriginal, + sizeType : col.sizeType + }); + } + for (var i in this.sortData) state.sortData.push($.extend({}, this.sortData[i])); + for (var i in this.searchData) state.searchData.push($.extend({}, this.searchData[i])); + // save into local storage + if (returnOnly !== true) { + // event before + var eventData = this.trigger({ phase: 'before', type: 'stateSave', target: this.name, state: state }); + if (eventData.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } + try { + var savedState = $.parseJSON(localStorage.w2ui || '{}'); + if (!savedState) savedState = {}; + if (!savedState.states) savedState.states = {}; + savedState.states[this.name] = state; + localStorage.w2ui = JSON.stringify(savedState); + } catch (e) { + delete localStorage.w2ui; + return null; + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + return state; + }, - 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': '.35s', - '-moz-transition' : '.35s', - '-ms-transition' : '.35s', - '-o-transition' : '.35s' - }); - 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; - }, + stateRestore: function (newState) { + var obj = this; + if (!newState) { + // read it from local storage + try { + if (!localStorage) return false; + var tmp = $.parseJSON(localStorage.w2ui || '{}'); + if (!tmp) tmp = {}; + if (!tmp.states) tmp.states = {}; + newState = tmp.states[this.name]; + } catch (e) { + delete localStorage.w2ui; + return null; + } + } + // event before + var eventData = this.trigger({ phase: 'before', type: 'stateRestore', target: this.name, state: newState }); + if (eventData.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } + // default behavior + if ($.isPlainObject(newState)) { + $.extend(this.show, newState.show); + $.extend(this.last, newState.last); + var sTop = this.last.scrollTop; + var sLeft = this.last.scrollLeft; + for (var c in newState.columns) { + var tmp = newState.columns[c]; + var col = this.getColumn(tmp.field); + if (col) $.extend(col, tmp); + } + this.sortData.splice(0, this.sortData.length); + for (var c in newState.sortData) this.sortData.push(newState.sortData[c]); + this.searchData.splice(0, this.searchData.length); + for (var c in newState.searchData) this.searchData.push(newState.searchData[c]); + // apply sort and search + setTimeout(function () { + // needs timeout as records need to be populated + if (obj.sortData.length > 0) obj.localSort(); + if (obj.searchData.length > 0) obj.localSearch(); + obj.last.scrollTop = sTop; + obj.last.scrollLeft = sLeft; + obj.refresh(); + }, 1); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return true; + }, + + stateReset: function () { + this.stateRestore(this.last.state); + // remove from local storage + if (localStorage) { + try { + var tmp = $.parseJSON(localStorage.w2ui || '{}'); + if (tmp.states && tmp.states[this.name]) { + delete tmp.states[this.name]; + } + localStorage.w2ui = JSON.stringify(tmp); + } catch (e) { + delete localStorage.w2ui; + return null; + } + } + }, + + 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.split(':')[0]) != -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 null; + 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 null; + 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; + } + } + }; - 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 false; - - 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.resizabled) $('#layout_'+ obj.name +'_resizer_'+panel).show(); - obj.trigger($.extend(eventData, { phase: 'after' })); - obj.resize(); - } else { - if (p.resizabled) $('#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; - }, + $.extend(w2grid.prototype, w2utils.event); + w2obj.grid = w2grid; +})(jQuery); - 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 false; - - 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; - }, +/************************************************************************ +* 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. +* - bug: when you assign content before previous transition completed. +* +************************************************************************/ - 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); - }, +(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; - set: function (panel, options) { - var obj = this.get(panel, true); - if (obj == null) return false; - $.extend(this.panels[obj], options); - this.refresh(panel); - this.resize(); // resize is needed when panel size is changed - return true; - }, + } 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; + } - get: function (panel, returnIndex) { - var obj = null; - for (var p in this.panels) { - if (this.panels[p].type == panel) { - if (returnIndex === true) return p; else return this.panels[p]; + 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; } - } - return null; - }, + }; + + // ==================================================== + // -- Implementation of core functionality + + w2layout.prototype = { + // default setting for a panel + panel: { + type : null, // left, right, top, bottom + title : '', + 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; + }, - el: function (panel) { - var el = $('#layout_'+ this.name +'_panel_'+ panel +' .w2ui-panel-content'); - if (el.length != 1) return null; - return el[0]; - }, + load: function (panel, url, transition, onLoad) { + var obj = this; + if (panel == 'css') { + $.get(url, function (data, status, xhr) { // should always be $.get as it is template + obj.content(panel, xhr.responseText); + if (onLoad) onLoad(); + }); + return true; + } + if (this.get(panel) !== null) { + $.get(url, function (data, status, xhr) { // should always be $.get as it is template + 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; + }, - 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(); - }, + 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; + }, - 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(); - }, + 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; + }, - toggleToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel); - }, + 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; + }, - 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(); - }, + 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('
.w2ui-panel-tabs').show(); - this.resize(); - }, + function resizeStart(type, evnt) { + if (!obj.box) return; + if (!evnt) evnt = window.event; + if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } + $(document).off('mousemove', obj.tmp.events.mouseMove).on('mousemove', obj.tmp.events.mouseMove); + $(document).off('mouseup', obj.tmp.events.mouseUp).on('mouseup', obj.tmp.events.mouseUp); + obj.tmp.resize = { + type : type, + x : evnt.screenX, + y : evnt.screenY, + diff_x : 0, + diff_y : 0, + value : 0 + }; + // lock all panels + for (var p1 in w2layout_panels) { + p1 = w2layout_panels[p1]; + obj.lock(p1, { opacity: 0 }); + } + if (type == 'left' || type == 'right') { + obj.tmp.resize.value = parseInt($('#layout_'+ obj.name +'_resizer_'+ type)[0].style.left); + } + if (type == 'top' || type == 'preview' || type == 'bottom') { + obj.tmp.resize.value = parseInt($('#layout_'+ obj.name +'_resizer_'+ type)[0].style.top); + } + } - toggleTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel); - }, + function resizeStop(evnt) { + if (!obj.box) return; + if (!evnt) evnt = window.event; + if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } + $(document).off('mousemove', obj.tmp.events.mouseMove); + $(document).off('mouseup', obj.tmp.events.mouseUp); + if (typeof obj.tmp.resize == 'undefined') return; + // unlock all panels + for (var p1 in w2layout_panels) { + obj.unlock(w2layout_panels[p1]); + } + // set new size + if (obj.tmp.diff_x !== 0 || obj.tmp.resize.diff_y !== 0) { // only recalculate if changed + var ptop = obj.get('top'); + var pbottom = obj.get('bottom'); + var panel = obj.get(obj.tmp.resize.type); + var height = parseInt($(obj.box).height()); + var width = parseInt($(obj.box).width()); + var str = String(panel.size); + var ns, nd; + switch (obj.tmp.resize.type) { + case 'top': + ns = parseInt(panel.sizeCalculated) + obj.tmp.resize.diff_y; + nd = 0; + break; + case 'bottom': + ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_y; + nd = 0; + break; + case 'preview': + ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_y; + nd = (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) + + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); + break; + case 'left': + ns = parseInt(panel.sizeCalculated) + obj.tmp.resize.diff_x; + nd = 0; + break; + case 'right': + ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_x; + nd = 0; + break; + } + // set size + if (str.substr(str.length-1) == '%') { + panel.size = Math.floor(ns * 100 / + (panel.type == 'left' || panel.type == 'right' ? width : height - nd) * 100) / 100 + '%'; + } else { + panel.size = ns; + } + obj.resize(); + } + $('#layout_'+ obj.name + '_resizer_'+ obj.tmp.resize.type).removeClass('active'); + delete obj.tmp.resize; + } - 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 false; - - 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 - var tmp = ['top', 'left', 'main', 'preview', 'right', 'bottom']; - for (var t in tmp) { - var pan = obj.get(tmp[t]); - var html = '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'; - $(obj.box).find(' > div').append(html); - // tabs are rendered in refresh() - } - $(obj.box).find(' > div') - .append('
drag - if (obj.tmp.resizing == 'left' && (obj.get('left').minSize - obj.tmp.resize.div_x > obj.get('left').width)) { - obj.tmp.resize.div_x = obj.get('left').minSize - obj.get('left').width; - } - if (obj.tmp.resize.type == 'left' && (obj.get('main').minSize + obj.tmp.resize.div_x > obj.get('main').width)) { - obj.tmp.resize.div_x = obj.get('main').width - obj.get('main').minSize; - } - // right panel -> drag - if (obj.tmp.resize.type == 'right' && (obj.get('right').minSize + obj.tmp.resize.div_x > obj.get('right').width)) { - obj.tmp.resize.div_x = obj.get('right').width - obj.get('right').minSize; - } - if (obj.tmp.resize.type == 'right' && (obj.get('main').minSize - obj.tmp.resize.div_x > obj.get('main').width)) { - obj.tmp.resize.div_x = obj.get('main').minSize - obj.get('main').width; - } - // top panel -> drag - if (obj.tmp.resize.type == 'top' && (obj.get('top').minSize - obj.tmp.resize.div_y > obj.get('top').height)) { - obj.tmp.resize.div_y = obj.get('top').minSize - obj.get('top').height; - } - if (obj.tmp.resize.type == 'top' && (obj.get('main').minSize + obj.tmp.resize.div_y > obj.get('main').height)) { - obj.tmp.resize.div_y = obj.get('main').height - obj.get('main').minSize; - } - // bottom panel -> drag - if (obj.tmp.resize.type == 'bottom' && (obj.get('bottom').minSize + obj.tmp.resize.div_y > obj.get('bottom').height)) { - obj.tmp.resize.div_y = obj.get('bottom').height - obj.get('bottom').minSize; - } - if (obj.tmp.resize.type == 'bottom' && (obj.get('main').minSize - obj.tmp.resize.div_y > obj.get('main').height)) { - obj.tmp.resize.div_y = obj.get('main').minSize - obj.get('main').height; - } - // preview panel -> drag - if (obj.tmp.resize.type == 'preview' && (obj.get('preview').minSize + obj.tmp.resize.div_y > obj.get('preview').height)) { - obj.tmp.resize.div_y = obj.get('preview').height - obj.get('preview').minSize; - } - if (obj.tmp.resize.type == 'preview' && (obj.get('main').minSize - obj.tmp.resize.div_y > obj.get('main').height)) { - obj.tmp.resize.div_y = obj.get('main').minSize - obj.get('main').height; - } - switch(obj.tmp.resize.type) { - case 'top': - case 'preview': - case 'bottom': - obj.tmp.resize.div_x = 0; - if (p.length > 0) p[0].style.top = (obj.tmp.resize.value + obj.tmp.resize.div_y) + 'px'; - break; - case 'left': - case 'right': - obj.tmp.resize.div_y = 0; - if (p.length > 0) p[0].style.left = (obj.tmp.resize.value + obj.tmp.resize.div_x) + 'px'; - break; - } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - } - }, + function resizeMove(evnt) { + if (!obj.box) return; + if (!evnt) evnt = window.event; + if (typeof obj.tmp.resize == 'undefined') return; + var panel = obj.get(obj.tmp.resize.type); + // event before + var tmp = obj.tmp.resize; + var eventData = obj.trigger({ phase: 'before', type: 'resizing', target: obj.name, object: panel, originalEvent: evnt, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); + if (eventData.isCancelled === true) return; + + var p = $('#layout_'+ obj.name + '_resizer_'+ tmp.type); + var resize_x = (evnt.screenX - tmp.x); + var resize_y = (evnt.screenY - tmp.y); + var mainPanel = obj.get('main'); + + if (!p.hasClass('active')) p.addClass('active'); + + 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 '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 (panel != null && typeof panel != 'undefined') { - var p = obj.get(panel); - if (p == null) return; - // apply properties to the panel - var el = $('#layout_'+ obj.name +'_panel_'+ panel).css({ display: p.hidden ? 'none' : 'block' }); - el = el.find('.w2ui-panel-content'); - if (el.length > 0) el.css('overflow', p.overflow)[0].style.cssText += ';' + p.style; - if (p.resizable === true) { - $('#layout_'+ this.name +'_resizer_'+ panel).show(); - } else { - $('#layout_'+ this.name +'_resizer_'+ panel).hide(); - } - // insert content - if (typeof p.content == 'object' && p.content.render) { - p.content.box = $('#layout_'+ obj.name + '_panel_'+ p.type +' > .w2ui-panel-content')[0]; - p.content.render(); // do not do .render(box); - } else { - $('#layout_'+ obj.name + '_panel_'+ p.type +' > .w2ui-panel-content').html(p.content); - } - // if there are tabs and/or toolbar - render it - var tmp = $(obj.box).find('#layout_'+ obj.name + '_panel_'+ p.type +' .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(); - } - var tmp = $(obj.box).find('#layout_'+ obj.name + '_panel_'+ p.type +' .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(); - } - } else { - if ($('#layout_' +obj.name +'_panel_main').length <= 0) { - obj.render(); - return; - } - obj.resize(); - // refresh all of them - for (var p in this.panels) { obj.refresh(this.panels[p].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 eventData = this.trigger({ phase: 'before', type: 'resize', target: this.name, panel: this.tmp.resizing }); - if (eventData.isCancelled === true) return false; - 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); - // calculate % - for (var p in { 'top':'', 'left':'', 'right':'', 'bottom':'', 'preview':'' }) { - var tmp = this.get(p); - var str = String(tmp.size); - if (tmp && 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); - } - if (tmp.sizeCalculated < parseInt(tmp.minSize)) tmp.sizeCalculated = parseInt(tmp.minSize); - } - // top if any - if (ptop != null && ptop.hidden != true) { - var l = 0; - var t = 0; - var w = width; - var 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' - }).bind('mousedown', function (event) { - w2ui[obj.name].tmp.events.resizeStart('top', event); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_top').hide(); - } - // left if any - if (pleft != null && pleft.hidden != true) { - var l = 0; - var t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - var w = pleft.sizeCalculated; - var h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0); - var e = $('#layout_'+ this.name +'_panel_left'); - if (window.navigator.userAgent.indexOf('MSIE') > 0 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - $('#layout_'+ this.name +'_panel_left').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' - }).bind('mousedown', function (event) { - w2ui[obj.name].tmp.events.resizeStart('left', event); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_left').hide(); - $('#layout_'+ this.name +'_resizer_left').hide(); - } - // right if any - if (pright != null && pright.hidden != true) { - var l = width - pright.sizeCalculated; - var t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - var w = pright.sizeCalculated; - var 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' - }).bind('mousedown', function (event) { - w2ui[obj.name].tmp.events.resizeStart('right', event); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_right').hide(); - } - // bottom if any - if (pbottom != null && pbottom.hidden != true) { - var l = 0; - var t = height - pbottom.sizeCalculated; - var w = width; - var 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' - }).bind('mousedown', function (event) { - w2ui[obj.name].tmp.events.resizeStart('bottom', event); - return false; + 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' }); - } - } else { - $('#layout_'+ this.name +'_panel_bottom').hide(); - } - // main - always there - var l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - var t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - var w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding: 0); - var h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - - (sprev ? pprev.sizeCalculated + this.padding : 0); - var e = $('#layout_'+ this.name +'_panel_main'); - if (window.navigator.userAgent.indexOf('MSIE') > 0 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - $('#layout_'+ this.name +'_panel_main').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) { - var l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - var t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated; - var w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding : 0); - var h = pprev.sizeCalculated; - var e = $('#layout_'+ this.name +'_panel_preview'); - if (window.navigator.userAgent.indexOf('MSIE') > 0 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - $('#layout_'+ this.name +'_panel_preview').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' - }).bind('mousedown', function (event) { - w2ui[obj.name].tmp.events.resizeStart('preview', event); - return false; + 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' }); - } - } else { - $('#layout_'+ this.name +'_panel_preview').hide(); - } - - // display tabs and toolbar if needed - for (var p in { 'top':'', 'left':'', 'main':'', 'preview':'', 'right':'', 'bottom':'' }) { - var pan = this.get(p); - var tmp = '#layout_'+ this.name +'_panel_'+ p +' > .w2ui-panel-'; - var height = 0; - if (pan.show.tabs) { - if (pan.tabs != null && w2ui[this.name +'_'+ p +'_tabs']) w2ui[this.name +'_'+ p +'_tabs'].resize(); - height += w2utils.getSize($(tmp + 'tabs').css({ display: 'block' }), 'height'); - } - if (pan.show.toolbar) { - if (pan.toolbar != null && w2ui[this.name +'_'+ p +'_toolbar']) w2ui[this.name +'_'+ p +'_toolbar'].resize(); - height += w2utils.getSize($(tmp + 'toolbar').css({ top: height + 'px', display: 'block' }), 'height'); - } - $(tmp + 'content').css({ display: 'block' }).css({ top: height + 'px' }); - } - // send resize to all objects - var obj = this; - 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; - }, + 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(); + } - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return false; - 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); - if (this.tmp.events && this.tmp.events.mousemove) $(document).off('mousemove', this.tmp.events.mousemove); - if (this.tmp.events && this.tmp.events.mouseup) $(document).off('mouseup', this.tmp.events.mouseup); - - return true; - }, + // 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; + }, - lock: function (panel, msg, showSpinner) { - if ($.inArray(String(panel), ['left', 'right', 'top', 'bottom', 'preview', 'main']) == -1) { - console.log('ERROR: First parameter needs to be the a valid panel name.'); - return; - } - var nm = '#layout_'+ this.name + '_panel_' + panel; - w2utils.lock(nm, msg, showSpinner); - }, + 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; + }, - unlock: function (panel) { - if ($.inArray(String(panel), ['left', 'right', 'top', 'bottom', 'preview', 'main']) == -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); - } - } + 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; + $.extend(w2layout.prototype, w2utils.event); + w2obj.layout = w2layout; })(jQuery); /************************************************************************ - * Library: Web 2.0 UI for jQuery (using prototypical inheritance) - * - Following objects defined - * - w2popup - popup widget - * - $().w2popup - jQuery wrapper - * - Dependencies: jQuery, w2utils - * - * == NICE TO HAVE == - * - when maximized, align the slide down message - * - bug: after transfer to another content, message does not work - * - transition should include title, body and buttons, not just body - * - add lock method() to lock popup content - * - ************************************************************************/ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - w2popup - popup widget +* - $().w2popup - jQuery wrapper +* - Dependencies: jQuery, w2utils +* +* == NICE TO HAVE == +* - transition should include title, body and buttons, not just body +* +************************************************************************/ 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 = { url: options }; - if (method == 'open' && typeof options.url != 'undefined') method = 'load'; - if (typeof options == 'undefined') 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 - }, - handlers : [], - onOpen : null, - onClose : null, - onMax : null, - onMin : null, - onKeydown : null, - - open: function (options) { - var obj = this; - // get old options and merge them - var old_options = $('#w2ui-popup').data('options'); - var options = $.extend({}, this.defaults, { body : '' }, old_options, options); - // if new - reset event handlers - if ($('#w2ui-popup').length == 0) { - w2popup.handlers = []; - w2popup.onMax = null; - w2popup.onMin = 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.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; - // 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 - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 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 - if (typeof old_options == 'undefined' || old_options['width'] != options['width'] || old_options['height'] != options['height']) { - $('#w2ui-panel').remove(); - w2popup.resize(options.width, options.height); - } - // 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 () { - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 1); - } - // save new options - options._last_w2ui_name = w2utils.keyboard.active(); - w2utils.keyboard.active(null); - $('#w2ui-popup').data('options', options); - // keyboard events - if (options.keyboard) $(document).on('keydown', this.keydown); - - // initialize move - var tmp = { resizing: false }; - $('#w2ui-popup .w2ui-msg-title') - .on('mousedown', function (event) { mvStart(event); }) - .on('mousemove', function (event) { mvMove(event); }) - .on('mouseup', function (event) { mvStop(event); }); - $('#w2ui-popup .w2ui-msg-body') - .on('mousemove', function (event) { mvMove(event); }) - .on('mouseup', function (event) { mvStop(event); }); - $('#w2ui-lock') - .on('mousemove', function (event) { mvMove(event); }) - .on('mouseup', function (event) { mvStop(event); }); - - // handlers - function mvStart(event) { - if (!event) event = window.event; - if (!window.addEventListener) { window.document.attachEvent('onselectstart', function() { return false; } ); } - tmp.resizing = true; - tmp.tmp_x = event.screenX; - tmp.tmp_y = event.screenY; - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - if (event.preventDefault) event.preventDefault(); else return false; - } - - function mvMove(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - tmp.tmp_div_x = (evnt.screenX - tmp.tmp_x); - tmp.tmp_div_y = (evnt.screenY - tmp.tmp_y); - $('#w2ui-popup').css({ - '-webkit-transition': 'none', - '-webkit-transform': 'translate3d('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px, 0px)', - '-moz-transition': 'none', - '-moz-transform': 'translate('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px)', - '-ms-transition': 'none', - '-ms-transform': 'translate('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px)', - '-o-transition': 'none', - '-o-transform': 'translate('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px)' - }); - $('#w2ui-panel').css({ - '-webkit-transition': 'none', - '-webkit-transform': 'translate3d('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px, 0px)', - '-moz-transition': 'none', - '-moz-transform': 'translate('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px)', - '-ms-transition': 'none', - '-ms-transform': 'translate('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px', - '-o-transition': 'none', - '-o-transform': 'translate('+ tmp.tmp_div_x +'px, '+ tmp.tmp_div_y +'px)' - }); - } - - function mvStop(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - tmp.tmp_div_x = (evnt.screenX - tmp.tmp_x); - tmp.tmp_div_y = (evnt.screenY - tmp.tmp_y); - $('#w2ui-popup').css({ - '-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)', - 'left': (parseInt($('#w2ui-popup').css('left')) + parseInt(tmp.tmp_div_x)) + 'px', - 'top': (parseInt($('#w2ui-popup').css('top')) + parseInt(tmp.tmp_div_y)) + 'px' - }); - $('#w2ui-panel').css({ - '-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)', - 'left': (parseInt($('#w2ui-panel').css('left')) + parseInt(tmp.tmp_div_x)) + 'px', - 'top': (parseInt($('#w2ui-panel').css('top')) + parseInt(tmp.tmp_div_y)) + 'px' - }); - tmp.resizing = false; - } - 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, object: w2popup, 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); - // trigger event - var eventData = this.trigger({ phase: 'before', type: 'close', target: 'popup', options: options }); - if (eventData.isCancelled === true) return; - // default behavior - $('#w2ui-popup, #w2ui-panel').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(); - setTimeout(function () { - $('#w2ui-popup').remove(); - $('#w2ui-panel').remove(); - // 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 options = $('#w2ui-popup').data('options'); - if (options.maximized === true) w2popup.min(); else w2popup.max(); - }, - - 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 - options.maximized = true; - options.prevSize = $('#w2ui-popup').css('width')+':'+$('#w2ui-popup').css('height'); - $('#w2ui-popup').data('options', options); - // do resize - w2popup.resize(10000, 10000, function () { - 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 - options.maximized = false; - options.prevSize = null; - $('#w2ui-popup').data('options', options); - // do resize - w2popup.resize(size[0], size[1], function () { - 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); - }, + // ==================================================== + // -- 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, old_options, { title: '', body : '', buttons: '' }, 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(((parseInt(height) - parseInt(options.height)) / 2) * 0.6); + var left = parseInt((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 btn = ''; + if (options.showClose) { + btn += '
Close
'; + } + if (options.showMax) { + btn += '
Max
'; + } + var msg='
'+ + '
' + btn + options.title + '
'+ + '
'+ + '
' + options.body + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
' + options.buttons + '
'+ + '
'; + $('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; + if (options.buttons != '') { + $('#w2ui-popup .w2ui-msg-buttons').show().html(options.buttons); + $('#w2ui-popup .w2ui-msg-body').removeClass('w2ui-msg-no-buttons'); + $('#w2ui-popup .w2ui-box1, #w2ui-popup .w2ui-box2').css('bottom', ''); + } else { + $('#w2ui-popup .w2ui-msg-buttons').hide().html(''); + $('#w2ui-popup .w2ui-msg-body').addClass('w2ui-msg-no-buttons'); + $('#w2ui-popup .w2ui-box1, #w2ui-popup .w2ui-box2').css('bottom', '0px'); + } + if (options.title != '') { + $('#w2ui-popup .w2ui-msg-title').show().html( + (options.showClose ? '
Close
' : '') + + (options.showMax ? '
Max
' : '') + + options.title); + $('#w2ui-popup .w2ui-msg-body').removeClass('w2ui-msg-no-title'); + $('#w2ui-popup .w2ui-box1, #w2ui-popup .w2ui-box2').css('top', ''); + } else { + $('#w2ui-popup .w2ui-msg-title').hide().html(''); + $('#w2ui-popup .w2ui-msg-body').addClass('w2ui-msg-no-title'); + $('#w2ui-popup .w2ui-box1, #w2ui-popup .w2ui-box2').css('top', '0px'); + } + // 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); - load: function (options) { - 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-ppopup').append('
'); - } - $('#w2ui-popup #div-style').html(style); - } - $('#w2ui-tmp').remove(); - } - }, + // 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; + } - 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 head = $('#w2ui-popup .w2ui-msg-title'); - if ($('#w2ui-popup .w2ui-popup-message').length == 0) { - var pwidth = parseInt($('#w2ui-popup').width()); - $('#w2ui-popup .w2ui-box1') - .before(''); - $('#w2ui-popup .w2ui-popup-message').data('options', options); - } else { - if (typeof options.width == 'undefined') options.width = w2utils.getSize($('#w2ui-popup .w2ui-popup-message'), 'width'); - if (typeof options.height == 'undefined') options.height = w2utils.getSize($('#w2ui-popup .w2ui-popup-message'), 'height'); - } - var display = $('#w2ui-popup .w2ui-popup-message').css('display'); - $('#w2ui-popup .w2ui-popup-message').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-popup-message').show().html(options.html); - setTimeout(function() { - $('#w2ui-popup .w2ui-popup-message').css({ - '-webkit-transition': '0s', '-moz-transition': '0s', '-ms-transition': '0s', '-o-transition': '0s', - 'z-Index': 1500 - }); // has to be on top of lock - w2popup.lock(); - if (typeof options.onOpen == 'function') options.onOpen(); - }, 300); - } else { - $('#w2ui-popup .w2ui-popup-message').css('z-Index', 250); - var options = $('#w2ui-popup .w2ui-popup-message').data('options'); - $('#w2ui-popup .w2ui-popup-message').remove(); - w2popup.unlock(); - if (typeof options.onClose == 'function') options.onClose(); - } - // timer needs to animation - setTimeout(function () { - $('#w2ui-popup .w2ui-popup-message').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); - }, + 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)' + }); + } - lock: function (msg, showSpinner) { - w2utils.lock($('#w2ui-popup'), msg, showSpinner); - }, + 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'})); + }, - unlock: function () { - w2utils.unlock($('#w2ui-popup')); - }, + 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'})); + }, (options.speed * 1000) + 50); + }, - // --- 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 + 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'})); }); - }, 100); - if (window.getSelection) window.getSelection().removeAllRanges(); - }); - } else { - $('#w2ui-lock').on('mouseup', function () { w2popup.close(); }); - } - return true; - }, + }, - unlockScreen: function () { - if ($('#w2ui-lock').length == 0) return false; - var options = $.extend({}, $('#w2ui-popup').data('options'), 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; - }, + 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) { // should always be $.get as it is template + 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; + }, - 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); - } + 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 + }); + setTimeout(function () { + options.width = width; + options.height = height; + if (typeof callBack == 'function') callBack(); + }, (options.speed * 1000) + 50); // give extra 50 ms + } } - } - // merge in event handling - $.extend(w2popup, w2utils.event); + // merge in event handling + $.extend(w2popup, w2utils.event); })(jQuery); @@ -6940,4212 +8480,5213 @@ var w2popup = {}; // --- Common dialogs var w2alert = function (msg, title, callBack) { - if (typeof title == 'undefined') title = w2utils.lang('Notification'); - if (jQuery('#w2ui-popup').length > 0) { - 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 (msg, title, callBack) { - if (typeof callBack == 'undefined' || typeof title == 'function') { - callBack = title; - title = w2utils.lang('Confirmation'); - } - if (typeof title == 'undefined') { - title = w2utils.lang('Confirmation'); - } - if (jQuery('#w2ui-popup').length > 0) { - w2popup.message({ - width : 400, - height : 150, - html : '
'+ - '
'+ msg +'
'+ - '
'+ - '
'+ - ' '+ - ' '+ - '
', - onOpen: function () { - jQuery('#w2ui-popup .w2ui-popup-message .w2ui-popup-button').on('click', function (event) { - w2popup.message(); - if (typeof callBack == 'function') callBack(event.target.id); + if (title == null) title = w2utils.lang('Notification'); + if (jQuery('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + w2popup.message({ + width : 400, + height : 170, + html : '
' + + '
' + msg + '
' + + '
' + + '
' + + ' ' + + '
', + onClose : function () { + if (typeof callBack == 'function') callBack(); + } }); - }, - 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.open({ - width : 450, - height : 200, - title : title, - modal : true, - showClose : false, - body : '
' + msg +'
', - buttons : ''+ - '', - onOpen: function (event) { - event.onComplete = function () { - jQuery('#w2ui-popup .w2ui-popup-button').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 - * - Dependencies: jQuery, w2utils - * - * == NICE TO HAVE == - * - tabs might not work in chromium apps, need bind() - * - on overflow display << >> - * - 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(true, this, w2obj.tabs, options); - } - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2tabs = function(method) { - if (typeof method === 'object' || !method ) { - // check required parameters - if (!method || typeof method.name == 'undefined') { - console.log('ERROR: The parameter "name" is required but not supplied in $().w2tabs().'); - return; - } - if (typeof w2ui[method.name] != 'undefined') { - console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ method.name +').'); - return; - } - if (!w2utils.isAlphaNumeric(method.name)) { - console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); - return; - } - // extend tabs - var tabs = method.tabs; - var object = new w2tabs(method); - $.extend(object, { tabs: [], handlers: [] }); - for (var i in tabs) { 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' ); + w2popup.open({ + width : 450, + height : 220, + showMax : false, + showClose : false, + title : title, + body : '
' + msg + '
', + buttons : '', + onClose : function () { + if (typeof callBack == 'function') callBack(); + } + }); } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2tabs.prototype = { - tab : { - id : null, // commnad 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 r in tab) { - // checks - if (String(tab[r].id) == 'undefined') { - console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); - return; - } - var unique = true; - for (var i in this.tabs) { if (this.tabs[i].id == tab[r].id) { unique = false; break; } } - if (!unique) { - console.log('ERROR: The parameter "id='+ tab[r].id +'" is not unique within the current tabs. (obj: '+ this.name +')'); - return; - } - if (!w2utils.isAlphaNumeric(tab[r].id)) { - console.log('ERROR: The parameter "id='+ tab[r].id +'" must be alpha-numeric + "-_". (obj: '+ this.name +')'); - return; - } - // add tab - var tab = $.extend({}, tab, tab[r]); - if (id == null || typeof id == 'undefined') { - this.tabs.push(tab); +var w2confirm = function (msg, title, callBack) { + var options = {}; + var defaults = { + msg : '', + title : w2utils.lang('Confirmation'), + width : (jQuery('#w2ui-popup').length > 0 ? 400 : 450), + height : (jQuery('#w2ui-popup').length > 0 ? 170 : 220), + yes_text : 'Yes', + yes_class : '', + yes_style : '', + yes_callBack: null, + no_text : 'No', + no_class : '', + no_style : '', + no_callBack : null, + callBack : null + }; + if (arguments.length == 1 && typeof msg == 'object') { + jQuery.extend(options, defaults, msg); + } else { + if (typeof title == 'function') { + jQuery.extend(options, defaults, { + msg : msg, + callBack: title + }) } else { - var middle = this.get(id, true); - this.tabs = this.tabs.slice(0, middle).concat([tab], this.tabs.slice(middle)); + jQuery.extend(options, defaults, { + msg : msg, + title : title, + callBack: callBack + }) } - this.refresh(tab[r].id); - } - }, - - remove: function (id) { - 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; - }, + } + if (jQuery('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + if (options.width > w2popup.get().width) options.width = w2popup.get().width; + if (options.height > (w2popup.get().height - 50)) options.height = w2popup.get().height - 50; + w2popup.message({ + width : options.width, + height : options.height, + html : '
' + + '
' + options.msg + '
' + + '
' + + '
' + + ' ' + + ' ' + + '
', + onOpen: function () { + jQuery('#w2ui-popup .w2ui-popup-message .btn').on('click', function (event) { + w2popup.message(); + if (typeof options.callBack == 'function') options.callBack(event.target.id); + if (event.target.id == 'Yes' && typeof options.yes_callBack == 'function') options.yes_callBack(); + if (event.target.id == 'No' && typeof options.no_callBack == 'function') options.no_callBack(); + }); + }, + onKeydown: function (event) { + switch (event.originalEvent.keyCode) { + case 13: // enter + if (typeof options.callBack == 'function') options.callBack('Yes'); + if (typeof options.yes_callBack == 'function') options.yes_callBack(); + w2popup.message(); + break + case 27: // esc + if (typeof options.callBack == 'function') options.callBack('No'); + if (typeof options.no_callBack == 'function') options.no_callBack(); + w2popup.message(); + break + } + } + }); - select: function (id) { - if (this.get(id) == null || this.active == id) return false; - this.active = id; - this.refresh(); - return true; - }, + } else { - 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; - }, + if (!w2utils.isInt(options.height)) options.height = options.height + 50; + w2popup.open({ + width : options.width, + height : options.height, + title : options.title, + modal : true, + showClose : false, + body : '
' + options.msg + '
', + buttons : ''+ + '', + onOpen: function (event) { + event.onComplete = function () { + jQuery('#w2ui-popup .w2ui-popup-btn').on('click', function (event) { + w2popup.close(); + if (typeof options.callBack == 'function') options.callBack(event.target.id); + if (event.target.id == 'Yes' && typeof options.yes_callBack == 'function') options.yes_callBack(); + if (event.target.id == 'No' && typeof options.no_callBack == 'function') options.no_callBack(); + }); + } + }, + onKeydown: function (event) { + switch (event.originalEvent.keyCode) { + case 13: // enter + if (typeof options.callBack == 'function') options.callBack('Yes'); + if (typeof options.yes_callBack == 'function') options.yes_callBack(); + w2popup.close(); + break + case 27: // esc + if (typeof options.callBack == 'function') options.callBack('No'); + if (typeof options.no_callBack == 'function') options.no_callBack(); + w2popup.close(); + break + } + } + }); + } - get: function (id, returnIndex) { - if (arguments.length == 0) { - var all = []; - for (var i = 0; i < this.tabs.length; i++) if (this.tabs[i].id != null) all.push(this.tabs[i].id); - return all; - } - for (var i in this.tabs) { - if (this.tabs[i].id == id) { - if (returnIndex === true) return i; else return this.tabs[i]; + return { + yes: function (fun) { + options.yes_callBack = fun; + return this; + }, + no: function (fun) { + options.no_callBack = fun; + return this; } - } - return null; - }, - - show: function () { - var shown = 0; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.hidden === false) continue; - tab.hidden = false; - this.refresh(tab.id); - shown++; - } - return shown; - }, - - hide: function () { - var hidden = 0; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.hidden === true) continue; - tab.hidden = true; - this.refresh(tab.id); - hidden++; - } - return hidden; - }, - - enable: function (id) { - var enabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.disabled === false) continue; - tab.disabled = false; - this.refresh(tab.id); - enabled++; - } - return enabled; - }, - - disable: function (id) { - var disabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.disabled === true) continue; - tab.disabled = true; - this.refresh(tab.id); - disabled++; - } - return disabled; - }, + }; +}; +/************************************************************************ +* 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 << >> +* +************************************************************************/ - refresh: function (id) { - var time = (new Date()).getTime(); - if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (String(id) == 'undefined') { - // refresh all - for (var i in this.tabs) this.refresh(this.tabs[i].id); - } - // 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 false; - // create or refresh only one item - var tab = this.get(id); - if (tab == null) return; - 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);'; } - 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); +(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.routeData = {}; // data for dynamic routes + 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 { - $(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)' }); } - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, + 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 : '', + route : null, + 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; + }, - 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 false; - // default action - if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (String(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; - // 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; - }, + select: function (id) { + if (this.active == id || this.get(id) === null) return false; + this.active = id; + this.refresh(); + return true; + }, - resize: function () { - 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 false; - // empty function - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, + 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; + }, - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return false; - // 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' })); - }, + 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; + }, - // =================================================== - // -- 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, object: this.get(id), originalEvent: event }); - if (eventData.isCancelled === true) return false; - // 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); - }, + 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; + }, - 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 false; - // 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(); - }, + 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; - animateInsert: function(id, tab) { - if (this.get(id) == null) return; - if (!$.isPlainObject(tab)) return; - // check for unique - var unique = true; - for (var i in this.tabs) { if (this.tabs[i].id == tab.id) { unique = false; break; } } - if (!unique) { - console.log('ERROR: The parameter "id='+ tab.id +'" is not unique within the current tabs. (obj: '+ 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 - 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);'; } - 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); - } - } + // intentionaly blank - $.extend(w2tabs.prototype, w2utils.event); - w2obj.tabs = w2tabs; -})(jQuery); + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, -/************************************************************************ - * 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 << >> - * - ************************************************************************/ + 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' })); + }, -(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 required parameters - if (!method || typeof method.name == 'undefined') { - console.log('ERROR: The parameter "name" is required but not supplied in $().w2toolbar().'); - return; - } - if (typeof w2ui[method.name] != 'undefined') { - console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ method.name +').'); - return; - } - if (!w2utils.isAlphaNumeric(method.name)) { - console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); - return; - } - var items = method.items; - // extend items - var object = new w2toolbar(method); - $.extend(object, { items: [], handlers: [] }); - - for (var i in items) { 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, // commnad 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 - }, + // =================================================== + // -- Internal Event Handlers - add: function (items) { - this.insert(null, items); - }, + 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; + // route processing + if (tab.route) { + var route = String('/'+ tab.route).replace(/\/{2,}/g, '/'); + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue; + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + this.refresh(id); + }, - insert: function (id, items) { - if (!$.isArray(items)) items = [items]; - for (var o in items) { - // 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; - } - var unique = true; - for (var i = 0; i < this.items.length; i++) { if (this.items[i].id == items[o].id) { unique = false; return; } } - if (!unique) { - console.log('ERROR: The parameter "id" is not unique within the current toolbar.'); - return; - } - if (!w2utils.isAlphaNumeric(items[o].id)) { - console.log('ERROR: The parameter "id" must be alpha-numeric + "-_".'); - return; - } - // add item - var it = $.extend({}, w2toolbar.prototype.item, items[o]); - if (id == null || typeof id == 'undefined') { - this.items.push(it); - } else { - var middle = this.get(id, true); - this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle)); + 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); } - this.refresh(it.id); - } - }, + }; - remove: function (id) { - 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; - }, + $.extend(w2tabs.prototype, w2utils.event); + w2obj.tabs = w2tabs; +})(jQuery); - get: function (id, returnIndex) { - if (arguments.length == 0) { - var all = []; - for (var i = 0; i < this.items.length; i++) if (this.items[i].id != null) all.push(this.items[i].id); - return all; - } - for (var i = 0; i < this.items.length; i++) { - if (this.items[i].id == id) { - if (returnIndex === true) return i; else return this.items[i]; - } - } - return null; - }, - show: function (id) { - var items = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.hidden = false; - this.refresh(it.id); - } - return items; - }, +/************************************************************************ +* 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 +* +************************************************************************/ - hide: function (id) { - var items = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.hidden = true; - this.refresh(it.id); - } - return items; - }, +(function ($) { + var w2toolbar = function (options) { + this.box = null; // DOM Element that holds the element + this.name = null; // unique name for w2ui + this.routeData = {}; // data for dynamic routes + 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 : '', + route : null, // if not null, it is route to go + html : '', + img : null, + icon : null, + count : 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 + overlay : {}, + 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; + }, - enable: function (id) { - var items = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.disabled = false; - this.refresh(it.id); - } - return items; - }, + 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; + }, - disable: function (id) { - var items = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.disabled = true; - this.refresh(it.id); - } - 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; + }, - check: function (id) { - var items = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.checked = true; - this.refresh(it.id); - } - return items; - }, + 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; + }, - uncheck: function (id) { - var items = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.checked = false; - this.refresh(it.id); - } - return items; - }, + 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; - render: function (box) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return false; - - if (typeof box != 'undefined' && 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 (typeof it.id == 'undefined' || 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' })); - }, + // intentionaly blank - 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), item: this.get(id) }); - if (eventData.isCancelled === true) return false; - - if (typeof id == 'undefined') { - // refresh all - for (var i = 0; i < this.items.length; i++) { - var it = this.items[i]; - if (typeof it.id == 'undefined' || it.id == null) it.id = "item_" + i; - this.refresh(it.id); - } - } - // create or refresh only one item - var it = this.get(id); - if (it == null) return; - - 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; - }, + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + return (new Date()).getTime() - time; + }, - 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 false; + 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.count != null ? '' : '') + + (((item.type === 'drop' || item.type === 'menu') && item.arrow !== false) ? + '' : '') + + '
'+ item.text +''+ item.count +'
'+ + '
'; + break; - // empty function + case 'break': + html += ''+ + ' '+ + '
 
'; + break; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - return (new Date()).getTime() - time; - }, + case 'html': + html += ''+ + ' '+ + '
' + item.html + '
'; + break; + } - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return false; - // 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' })); - }, + 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; + }, - // ======================================== - // --- 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 != '' && typeof newHTML != 'undefined') 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; + + // route processing + var it = event.subItem; + if (it.route) { + var route = String('/'+ it.route).replace(/\/{2,}/g, '/'); + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + if (obj.routeData[info.keys[k].name] == null) continue; + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } - menuClick: function (id, menu_index, event) { - if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - 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: this.get(id), - subItem: (typeof menu_index != 'undefined' && this.get(id) ? this.get(id).items[menu_index] : null), originalEvent: event }); - if (eventData.isCancelled === true) return false; - - // normal processing - - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - }, + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } + }, - click: function (id, event) { - if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - 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: this.get(id), originalEvent: event }); - if (eventData.isCancelled === true) return false; - - $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button').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; - $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button').addClass('checked'); - } + 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 = {}; - if (it.type == 'drop') { - el.w2overlay(it.html, $.extend({ left: (el.width() - 50) / 2, top: 3 }, it.overlay)); - } - if (it.type == 'menu') { - el.w2menu(it.items, $.extend({ left: (el.width() - 50) / 2, top: 3 }, it.overlay, { - select: function (item, event, index) { obj.menuClick(it.id, index, event); } - })); - } - // window.click to hide it - $(document).on('click', hideDrop); - function hideDrop() { - it.checked = false; - if (it.checked) { - $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button').addClass('checked'); - } else { - $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button').removeClass('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); + } } - obj.refresh(it.id); - $(document).off('click', hideDrop); - } - }, 1); - } - } - if (it.type == 'check' || it.type == 'drop' || it.type == 'menu') { - it.checked = !it.checked; - if (it.checked) { - $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button').addClass('checked'); - } else { - $('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button').removeClass('checked'); - } + if (it.type === 'check' || it.type === 'drop' || it.type === 'menu') { + it.checked = !it.checked; + if (it.checked) { + btn.addClass('checked'); + } else { + btn.removeClass('checked'); + } + } + // route processing + if (it.route) { + var route = String('/'+ it.route).replace(/\/{2,}/g, '/'); + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } + // event after + this.trigger($.extend(eventData, { phase: 'after' })); + } } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - } - } - } + }; - $.extend(w2toolbar.prototype, w2utils.event); - w2obj.toolbar = w2toolbar; + $.extend(w2toolbar.prototype, w2utils.event); + w2obj.toolbar = w2toolbar; })(jQuery); + /************************************************************************ - * 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) - * - ************************************************************************/ +* 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 +* +************************************************************************/ (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 required parameters - if (!method || typeof method.name == 'undefined') { - console.log('ERROR: The parameter "name" is required but not supplied in $().w2sidebar().'); - return; - } - if (typeof w2ui[method.name] != 'undefined') { - console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+ method.name +').'); - return; - } - if (!w2utils.isAlphaNumeric(method.name)) { - console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '); - 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 : '', - img : null, - icon : null, - nodes : [], - style : '', - selected : false, - expanded : false, - hidden : false, - disabled : false, - group : false, // if true, it will build as a group - 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) { - if (arguments.length == 2) { - // need to be in reverse order - nodes = arguments[1]; - before = arguments[0]; - var ind = this.get(before); - if (ind == null) { - var txt = (nodes[o].caption != 'undefined' ? nodes[o].caption : nodes[o].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) { - if (typeof nodes[o].id == 'undefined') { - var txt = (nodes[o].caption != 'undefined' ? nodes[o].caption : nodes[o].text); - console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.'); - continue; - } - if (this.get(this, nodes[o].id) != null) { - var txt = (nodes[o].caption != 'undefined' ? nodes[o].caption : nodes[o].text); - console.log('ERROR: Cannot insert node with id='+ nodes[o].id +' (text: '+ txt + ') because another node with the same id already exists.'); - continue; - } - var tmp = $.extend({}, w2sidebar.prototype.node, nodes[o]); - tmp.sidebar= this; - tmp.parent = parent; - var nd = tmp.nodes; - tmp.nodes = []; // very important to re-init empty nodes array - if (before == null) { // append to the end - parent.nodes.push(tmp); + var w2sidebar = function (options) { + this.name = null; + this.box = null; + this.sidebar = null; + this.parent = null; + this.nodes = []; // Sidebar child nodes + this.menu = []; + this.routeData = {}; // data for dynamic routes + 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 { - var ind = this.get(parent, before, true); - if (ind == null) { - var txt = (nodes[o].caption != 'undefined' ? nodes[o].caption : nodes[o].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 (typeof nd != 'undefined' && nd.length > 0) { this.insert(tmp, null, nd); } - } - this.refresh(parent.id); - return tmp; - }, - - remove: function () { // multiple arguments - var deleted = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp == null) continue; - var ind = this.get(tmp.parent, arguments[a], true); - if (ind == null) continue; - tmp.parent.nodes.splice(ind, 1); - deleted++; - } - if (deleted > 0 && arguments.length == 1) this.refresh(tmp.parent.id); else this.refresh(); - return deleted; - }, + 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 + route : null, + 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; + } + }, - 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 - this._tmp = null; - 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 (typeof nodes != 'undefined') { - this.add(parent.nodes[i], nodes); - } - this.refresh(id); - return true; - } else { - this._tmp = this.set(parent.nodes[i], id, node); - if (this._tmp) return true; - } - } - return false; - }, + 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); + }, - get: function (parent, id, returnIndex) { // can be just called get(id) or get(id, true) - 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 - this._tmp = null; - 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 { - this._tmp = this.get(parent.nodes[i], id, returnIndex); - if (this._tmp || this._tmp === 0) return this._tmp; - } - } - return this._tmp; - }, + 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; + }, - 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; - }, + 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; + }, - show: function () { - 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; - }, + 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; + // route processing + if (nd.route) { + var route = String('/'+ nd.route).replace(/\/{2,}/g, '/'); + var info = w2utils.parseRoute(route); + if (info.keys.length > 0) { + for (var k = 0; k < info.keys.length; k++) { + if (obj.routeData[info.keys[k].name] == null) continue; + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), obj.routeData[info.keys[k].name]); + } + } + setTimeout(function () { window.location.hash = route; }, 1); + } + // event after + obj.trigger($.extend(eventData, { phase: 'after' })); + }, 1); + }, - 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; - }, + 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' })); - 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; - }, + function selectNode (node, event) { + if (node !== null && !node.hidden && !node.disabled && !node.group) { + obj.click(node.id, event); + setTimeout(function () { obj.scrollIntoView(); }, 50); + } + } - select: function (id) { - if (this.selected == id) return false; - this.unselect(this.selected); - var new_node = this.get(id); - if (!new_node) return false; - $(this.box).find('#node_'+ w2utils.escapeId(id)) - .addClass('w2ui-selected') - .find('.w2ui-icon').addClass('w2ui-icon-selected'); - new_node.selected = true; - this.selected = id; - }, + function neighbor (node, neighborFunc) { + node = neighborFunc(node); + while (node !== null && (node.hidden || node.disabled)) { + if (node.group) break; else node = neighborFunc(node); + } + return node; + } - 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; - }, + 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; + } - toggle: function(id) { - var nd = this.get(id); - if (nd == null) return; - if (nd.plus) { - this.set(id, { plus: false }); - this.expand(id); - this.refresh(id); - return; - } - if (nd.nodes.length == 0) return; - if (this.get(id).expanded) this.collapse(id); else this.expand(id); - }, + 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; + } - collapse: function (id) { - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'collapse', target: id, object: nd }); - if (eventData.isCancelled === true) return false; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideUp('fast'); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
+
'); - nd.expanded = false; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.resize(); - }, + 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'); + } + }, - collapseAll: function (parent) { - if (typeof parent == 'undefined') parent = this; - 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].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); - }, + 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' })); + }, - expand: function (id) { - var nd = this.get(id); - // event before - var eventData = this.trigger({ phase: 'before', type: 'expand', target: id, object: nd }); - if (eventData.isCancelled === true) return false; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideDown('fast'); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
-
'); - nd.expanded = true; - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.resize(); - }, + 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 + }, - expandAll: function (parent) { - if (typeof parent == 'undefined') parent = this; - 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].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); - }, + 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' })); + }, - expandParents: function (id) { - var node = this.get(id); - if (node == null) return; - if (node.parent) { - node.parent.expanded = true; - this.expandParents(node.parent.id); - } - this.refresh(id); - }, + 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; + }, - click: function (id, event) { - var obj = this; - var nd = this.get(id); - if (nd == null) return; - var old = this.selected; - if (nd.disabled || nd.group) return; // should click event if already selected - // move selected first - $(obj.box).find('#node_'+ w2utils.escapeId(old)).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - $(obj.box).find('#node_'+ w2utils.escapeId(id)).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, object: nd }); - if (eventData.isCancelled === true) { - // restore selection - $(obj.box).find('#node_'+ w2utils.escapeId(id)).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - $(obj.box).find('#node_'+ w2utils.escapeId(old)).addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); - return false; - } - // default action - if (old != null) obj.get(old).selected = false; - obj.get(id).selected = true; - obj.selected = id; - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 1); - }, + 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; + } + }, - 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 false; - // 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) { - obj.collapse(obj.selected); - } else { - // collapse parent - if (nd.parent && !nd.parent.disabled && !nd.parent.group) { - obj.collapse(nd.parent.id); - obj.click(nd.parent.id); - setTimeout(function () { obj.scrollIntoView(); }, 50); - } - } - } - if (event.keyCode == 39) { // right - if (nd.nodes.length > 0) obj.expand(obj.selected); - } - if (event.keyCode == 38) { // up - var tmp = prev(nd); - if (tmp != null) { obj.click(tmp.id, event); setTimeout(function () { obj.scrollIntoView(); }, 50); } - } - if (event.keyCode == 40) { // down - var tmp = next(nd); - if (tmp != null) { obj.click(tmp.id, event); setTimeout(function () { obj.scrollIntoView(); }, 50); } - } - // 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' })); - return; - - 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.disabled && !t.group) nextNode = t; else nextNode = next(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.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 = null; - var noSubs = false; - if (ind > 0) { - prevNode = parent.nodes[ind - 1]; - // jump inside parents last node - if (prevNode.expanded && prevNode.nodes.length > 0) { - var t = prevNode.nodes[prevNode.nodes.length - 1]; - if (!t.disabled && !t.group) prevNode = t; else prevNode = prev(t); - } - } else { - prevNode = parent; // jump to the parent - noSubs = true; - } - if (prevNode != null && (prevNode.disabled || prevNode.group)) prevNode = prev(prevNode); - return prevNode; - } - }, + 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; + }, - 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 }); - } - if (offset <= 0) { - body.animate({ 'scrollTop': body.scrollTop() - body.height() / 1.3 }); - } - }, + 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' })); + }, - 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 false; - // default action - if (nd.nodes.length > 0) this.toggle(id); - // 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); + }, - 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 false; - // 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, - select: function (item, event, index) { obj.menuClick(id, index, event); } - } - ); + unlock: function () { + w2utils.unlock(this.box); } - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, 1); - }, + }; - 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 false; - // default action - // -- empty - // event after - obj.trigger($.extend(eventData, { phase: 'after' })); - }, + $.extend(w2sidebar.prototype, w2utils.event); + w2obj.sidebar = w2sidebar; +})(jQuery); - render: function (box) { - // event before - var eventData = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (eventData.isCancelled === true) return false; - // 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(); - }, +/************************************************************************ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - 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) +* - form to support custom types +* - bug: if input is hidden and then enum is applied, then when it becomes visible, it will be 110px +* +************************************************************************/ - 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 false; - // 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; - if (typeof id == 'undefined') { - var node = this; - var nm = '.w2ui-sidebar-div'; - } else { - var node = this.get(id); - if (node == null) return; - var nm = '#node_'+ w2utils.escapeId(node.id) + '_sub'; - } - if (node != this) { - var tmp = '#node_'+ w2utils.escapeId(node.id); - var 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++) { - var nodeHTML = getNodeHTML(node.nodes[i]); - $(this.box).find(nm).append(nodeHTML); - if (node.nodes[i].nodes.length != 0) { this.refresh(node.nodes[i].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.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')) +''+ - ' '+ nd.text +''+ - '
'+ - '
'; +(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 (nd.selected && !nd.disabled) obj.selected = nd.id; - var tmp = ''; - if (img) tmp = '
'; - if (icon) tmp = '
'; - html = - '
'+ - ''+ - ''+ - ''+ - '
'+ - '
' + (nd.nodes.length > 0 ? (nd.expanded ? '-' : '+') : (nd.plus ? '+' : '')) + '
' + - '
'+ - tmp + - (nd.count !== '' ? '
'+ nd.count +'
' : '') + - '
'+ nd.text +'
'+ - '
'+ - '
'+ - '
'; + // if without arguments - return the object + if (arguments.length == 0) { + var obj = $(this).data('w2field'); + return obj; + } + 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; + }); } - 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 false; - // 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; - }, + // ==================================================== + // -- Implementation of core functionality - destroy: function () { - // event before - var eventData = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (eventData.isCancelled === true) return false; - // 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' })); - }, + /* 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; + } - lock: function (msg, showSpinner) { - var box = $(this.box).find('> div:first-child'); - w2utils.lock(box, msg, showSpinner); - }, + 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, + decimalSymbol : w2utils.settings.decimalSymbol, + 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(); + if ($(this.el).attr('placeholder') && options.placeholder == '') options.placeholder = $(this.el).attr('placeholder'); + $(this.el).attr('placeholder', options.placeholder); + break; - unlock: function () { - w2utils.unlock(this.box); - } - } + 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); + if ($(this.el).attr('placeholder') && options.placeholder == '') options.placeholder = $(this.el).attr('placeholder'); + $(this.el).attr('placeholder', options.placeholder); + break; - $.extend(w2sidebar.prototype, w2utils.event); - w2obj.sidebar = w2sidebar; -})(jQuery); + 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 + if ($(this.el).attr('placeholder') && options.placeholder == '') options.placeholder = $(this.el).attr('placeholder'); + $(this.el).attr('placeholder', options.placeholder ? options.placeholder : options.format); + break; -/************************************************************************ - * Library: Web 2.0 UI for jQuery (using prototypical inheritance) - * - Following objects defined - * - w2field - various field controls - * - $().w2field - jQuery wrapper - * - Dependencies: jQuery, w2utils - * - * == NICE TO HAVE == - * - select - for select, list - for drop down (needs this in grid) - * - enum add events: onLoad, onRequest, onCompare, onSelect, onDelete, onClick for already selected elements - * - upload (regular files) - * - enum - refresh happens on each key press even if not needed (for speed) - * - BUG with prefix/postfix and arrows (test in different contexts) - * - multiple date selection - * - rewrire everythin in objects (w2ftext, w2fenum, w2fdate) - * - render calendar to the div - * - ************************************************************************/ + 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 + if ($(this.el).attr('placeholder') && options.placeholder == '') options.placeholder = $(this.el).attr('placeholder'); + $(this.el).attr('placeholder', options.placeholder ? options.placeholder : (options.format == 'h12' ? 'hh:mi pm' : 'hh:mi')); + break; -(function ($) { + case 'datetime': + break; - /* SINGELTON PATTERN */ + 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 + }; + options.items = this.normMenu(options.items); // need to be first + 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 + }); + this.options = options; + if (!$.isPlainObject(options.selected)) options.selected = {}; + $(this.el).data('selected', options.selected); + if (options.url) this.request(0); + if (this.type == 'list') this.addFocus(); + this.addPrefix(); + this.addSuffix(); + setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh + if ($(this.el).attr('placeholder') && options.placeholder == '') options.placeholder = $(this.el).attr('placeholder'); + $(this.el).attr('placeholder', options.placeholder).attr('autocomplete', 'off'); + if (typeof options.selected.text != 'undefined') $(this.el).val(options.selected.text); + break; - var w2field = new (function () { - this.customTypes = []; - }); + 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; - // ==================================================== - // -- Registers as a jQuery plugin + 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); + if ($(this.el).attr('placeholder')) options.placeholder = $(this.el).attr('placeholder'); + 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'); + } + if (['date', 'time'].indexOf(this.type) != -1) { + if ($(this.el).attr('placeholder') == options.format) $(this.el).attr('placeholder', ''); + } + 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 () { + if (!obj.helpers.focus) return; + // if empty show no icon + if (!$.isEmptyObject(selected) && options.icon) { + options.prefix = ''+ + ''; + obj.addPrefix(); + } else { + options.prefix = ''; + obj.addPrefix(); + } + // focus helpder + 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', options.placeholder || ''); + } else { + $(focus).css('opacity', 1).prev().css('opacity', 1); + $(obj.el).val(''); + $(obj.el).removeAttr('placeholder'); + setTimeout(function () { + if (obj.helpers.prefix) obj.helpers.prefix.hide(); + var tmp = 'position: absolute; opacity: 0; margin: 4px 0px 0px 2px; background-position: left !important;'; + if (options.icon) { + $(focus).css('margin-left', '17px'); + $(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 11px !important; opacity: 1'); + } else { + $(focus).css('margin-left', '0px'); + $(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 0px !important; opacity: 0'); + } + }, 1); + } + // if readonly or disabled + if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) { + setTimeout(function () { + $(obj.helpers.prefix).css('opacity', '0.6'); + $(obj.helpers.suffix).css('opacity', '0.6'); + }, 1); + } else { + setTimeout(function () { + $(obj.helpers.prefix).css('opacity', '1'); + $(obj.helpers.suffix).css('opacity', '1'); + }, 1); + } + }, 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).prop('readonly') || $(obj.el).prop('disabled')) { + div.addClass('w2ui-readonly'); + div.css('pointer-events', 'none').find('li').css('opacity', '0.6'); + $(obj.helpers.multi).find('input').prop('readonly', true); + } else { + div.removeClass('w2ui-readonly'); + div.css('pointer-events', 'auto').find('li').css('opacity', '1'); + $(obj.helpers.multi).find('input').prop('readonly', false); + } + // 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') || $(obj.el).attr('disabled')) 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 += '
    '+ + ' '+ + ' '+ + ' '+ + ' '+ + ' '+ + '
    '+ w2utils.lang('Name') +':'+ item.name +'
    '+ w2utils.lang('Size') +':'+ w2utils.size(item.size) +'
    '+ w2utils.lang('Type') +':' + + ' '+ item.type +''+ + '
    '+ w2utils.lang('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 (typeof val == 'string') val = val.replace(options.decimalSymbol, '.'); + 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(); + } + // list, enum + if (['list', 'enum', 'file'].indexOf(this.type) != -1) { + obj.refresh(); + // need time out to show icon indent properly + setTimeout(function () { obj.refresh(); }, 5); + } + // date, time + if (['date', 'time'].indexOf(this.type) != -1) { + // convert linux timestamps + var tmp = parseInt(obj.el.value); + if (w2utils.isInt(tmp) && tmp > 1000) { + if (this.type == 'time') $(obj.el).val(w2utils.formatTime(new Date(tmp), options.format)).change(); + if (this.type == 'date') $(obj.el).val(w2utils.formatDate(new Date(tmp), options.format)).change(); + } + } + }, - $.fn.w2field = function(method) { - // Method calling logic - if (w2field[method]) { - return w2field[method].apply( this, Array.prototype.slice.call( arguments, 1 )); - } else if ( typeof method === 'object') { - return w2field.init.apply( this, arguments ); - } else if ( typeof method === 'string') { - return w2field.init.apply( this, [{ type: method }] ); - } else { - console.log('ERROR: Method ' + method + ' does not exist on jQuery.w2field'); - } - }; - - $.extend(w2field, { - // CONTEXT: this - is jQuery object - init: function (options) { - var obj = w2field; - return $(this).each(function (field, index) { - // Check for Custom Types - if (typeof w2field.customTypes[options.type.toLowerCase()] == 'function') { - w2field.customTypes[options.type.toLowerCase()].call(this, options); - return; - } - // Common Types - var tp = options.type.toLowerCase(); - switch (tp) { - - case 'clear': // removes any previous field type - $(this) - .off('focus') - .off('blur') - .off('keypress') - .off('keydown') - .off('change') - .removeData(); // removes all attached data - if ($(this).prev().hasClass('w2ui-list')) { // if enum - $(this).prev().remove(); - $(this).removeAttr('tabindex').css('border-color', '').show(); - } - if ($(this).prev().hasClass('w2ui-upload')) { // if upload - $(this).prev().remove(); - $(this).removeAttr('tabindex').css('border-color', '').show(); - } - if ($(this).prev().hasClass('w2ui-field-helper')) { // helpers - $(this).css('padding-left', $(this).css('padding-top')); - $(this).prev().remove(); - } - if ($(this).next().hasClass('w2ui-field-helper')) { // helpers - $(this).css('padding-right', $(this).css('padding-top')); - $(this).next().remove(); - } - if ($(this).next().hasClass('w2ui-field-helper')) { // helpers - $(this).next().remove(); - } - break; - - case 'text': - case 'int': - case 'float': - case 'money': - case 'alphanumeric': - case 'hex': - var el = this; - var defaults = { - min : null, - max : null, - arrows : false, - keyboard: true, - suffix : '', - prefix : '' + click: function (event) { + event.stopPropagation(); + // lists + if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { + if (!$(this.el).is(':focus')) this.focus(event); } - options = $.extend({}, defaults, options); - if (['text', 'alphanumeric', 'hex'].indexOf(tp) != -1) { - options.arrows = false; - options.keyboard = false; - } - // init events - $(this) - .data('options', options) - .on('keypress', function (event) { // keyCode & charCode differ in FireFox + // 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') || $(obj.el).attr('disabled')) 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') || $(obj.el).attr('disabled')) 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) { + // 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; - if (event.keyCode == 13) $(this).change(); var ch = String.fromCharCode(event.charCode); - if (!checkType(ch, true)) { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; + if (!obj.checkType(ch, true) && event.keyCode != 13) { + event.preventDefault(); + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + return false; } - }) - .on('keydown', function (event, extra) { - if (!options.keyboard) return; + } + // 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 v = $(el).val(); - if (!checkType(v)) v = options.min || 0; else v = parseFloat(v); - var key = event.keyCode || extra.keyCode; - var inc = 1; + 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 - $(el).val((v + inc <= options.max || options.max == null ? v + inc : options.max)).change(); - if (tp == 'money') $(el).val( Number($(el).val()).toFixed(2) ); - cancel = true; - break; - case 40: // down - $(el).val((v - inc >= options.min || options.min == null ? v - inc : options.min)).change(); - if (tp == 'money') $(el).val( Number($(el).val()).toFixed(2) ); - cancel = true; - break; + 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(); - // set cursor to the end - setTimeout(function () { el.setSelectionRange(el.value.length, el.value.length); }, 0); + 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; + 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; } - }) - .on('change', function (event) { - // check max/min - var v = $(el).val(); - var cancel = false; - if (options.min != null && v != '' && v < options.min) { $(el).val(options.min).change(); cancel = true; } - if (options.max != null && v != '' && v > options.max) { $(el).val(options.max).change(); cancel = true; } if (cancel) { - event.stopPropagation(); - event.preventDefault(); - return false; - } - // check validity - if (this.value != '' && !checkType(this.value)) $(this).val(options.min != null ? options.min : ''); - }); - if ($(this).val() == '' && options.min != null) $(this).val(options.min); - if (options.prefix != '') { - $(this).before( - '
    '+ - options.prefix + - '
    '); - var helper = $(this).prev(); - helper - .css({ - 'color' : $(this).css('color'), - 'font-family' : $(this).css('font-family'), - 'font-size' : $(this).css('font-size'), - 'padding-top' : $(this).css('padding-top'), - 'padding-bottom': $(this).css('padding-bottom'), - 'padding-left' : $(this).css('padding-left'), - 'padding-right' : 0, - 'margin-top' : (parseInt($(this).css('margin-top')) + 1) + 'px', - 'margin-bottom' : (parseInt($(this).css('margin-bottom')) + 1) + 'px', - 'margin-left' : 0, - 'margin-right' : 0 - }) - .on('click', function () { - $(this).next().focus(); - }); - $(this).css('padding-left', (helper.width() + parseInt($(this).css('padding-left')) + 5) + 'px'); - } - var pr = parseInt($(this).css('padding-right')); - if (options.arrows != '') { - $(this).after( - '
     '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '); - var height = w2utils.getSize(this, 'height'); - var helper = $(this).next(); - helper - .css({ - 'color' : $(this).css('color'), - 'font-family' : $(this).css('font-family'), - 'font-size' : $(this).css('font-size'), - 'height' : ($(this).height() + parseInt($(this).css('padding-top')) + parseInt($(this).css('padding-bottom')) ) + 'px', - 'padding' : '0px', - 'margin-top' : (parseInt($(this).css('margin-top')) + 1) + 'px', - 'margin-bottom' : '0px', - 'border-left' : '1px solid silver' - }) - .css('margin-left', '-'+ (helper.width() + parseInt($(this).css('margin-right')) + 12) + 'px') - .on('mousedown', function (event) { - var btn = this; - var evt = 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) { - $(el).focus().trigger($.Event("keydown"), { - keyCode : ($(evt.target).attr('type') == 'up' ? 38 : 40) + 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 = (event.ctrlKey || event.metaKey ? 60 : 1); + 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() != '') $(focus).val(''); + 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: // backspace + case 46: // delete + if (obj.type == 'enum' && key == 8) { + 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' })); + } + } + if (obj.type == 'list' && $(focus).val() == '') { + $(obj.el).data('selected', {}).change(); + obj.refresh(); + } + 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 && $(obj.el).prop('readonly') != true && ( + (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(); + var ajaxOptions = { + type : 'GET', + url : url, + data : postData, + dataType : 'JSON' // expected from server + }; + if (w2utils.settings.dataType == 'JSON') { + ajaxOptions.type = 'POST'; + ajaxOptions.data = JSON.stringify(ajaxOptions.data); + ajaxOptions.contentType = 'application/json'; + } + obj.tmp.xhr = $.ajax(ajaxOptions) + .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 = obj.normMenu(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' })); + }) + .fail(function (xhr, status, error) { + // trigger event + var errorObj = { status: status, error: error, 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 + if (status != 'abort') { + var data; + try { data = $.parseJSON(xhr.responseText) } catch (e) {} + console.log('ERROR: Server communication failed.', + '\n EXPECTED:', { status: 'success', items: [{ id: 1, text: 'item' }] }, + '\n OR:', { status: 'error', message: 'error message' }, + '\n RECEIVED:', typeof data == 'object' ? data : xhr.responseText); + } + // 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); }); - if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60)); - }; - }); - pr += helper.width() + 12; - $(this).css('padding-right', pr + 'px'); - } - if (options.suffix != '') { - $(this).after( - '
    '+ - options.suffix + - '
    '); - var helper = $(this).next(); - helper - .css({ - 'color' : $(this).css('color'), - 'font-family' : $(this).css('font-family'), - 'font-size' : $(this).css('font-size'), - 'padding-top' : $(this).css('padding-top'), - 'padding-bottom': $(this).css('padding-bottom'), - 'padding-left' : '3px', - 'padding-right' : $(this).css('padding-right'), - 'margin-top' : (parseInt($(this).css('margin-top')) + 1) + 'px', - 'margin-bottom' : (parseInt($(this).css('margin-bottom')) + 1) + 'px' - }) - .on('click', function () { - $(this).prev().focus(); - }); - helper.css('margin-left', '-'+ (helper.width() + parseInt($(this).css('padding-right')) + 5) + 'px'); - pr += helper.width() + 3; - $(this).css('padding-right', pr + 'px'); } + // 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(''); + } + } + })); + } + } + }, + + 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; + }, - function checkType(ch, loose) { - switch (tp) { - case 'int': - if (loose && ['-'].indexOf(ch) != -1) return true; - return w2utils.isInt(ch); - break; - case 'float': - if (loose && ['-','.'].indexOf(ch) != -1) return true; - return w2utils.isFloat(ch); - break; - case 'money': - if (loose && ['-','.','$','€','£','¥'].indexOf(ch) != -1) return true; - return w2utils.isMoney(ch); - break; - case 'hex': - return w2utils.isHex(ch); - break; - case 'alphanumeric': - return w2utils.isAlphaNumeric(ch); - break; + /* + * INTERNAL FUNCTIONS + */ + + checkType: function (ch, loose) { + var obj = this; + switch (obj.type) { + case 'int': + if (loose && ['-', obj.options.groupSymbol].indexOf(ch) != -1) return true; + return w2utils.isInt(ch.replace(obj.options.numberRE, '')); + case 'percent': + ch = ch.replace(/%/g, ''); + case 'float': + if (loose && ['-', w2utils.settings.decimalSymbol, obj.options.groupSymbol].indexOf(ch) != -1) return true; + return w2utils.isFloat(ch.replace(obj.options.numberRE, '')); + case 'money': + case 'currency': + if (loose && ['-', obj.options.decimalSymbol, 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; - } - break; + }, - case 'date': + addPrefix: function () { var obj = this; - var defaults = { - format : w2utils.settings.date_format, // date format - start : '', // start of selectable range - end : '', // end of selectable range - blocked : {}, // {'4/11/2011': 'yes'} - colored : {} // {'4/11/2011': 'red:white'} - } - options = $.extend({}, defaults, options); - // -- insert div for calendar - $(this) // remove transtion needed for functionality - .css( { 'transition': 'none', '-webkit-transition': 'none', '-moz-transition': 'none', '-ms-transition': 'none', '-o-transition': 'none' }) - .data("options", options) - .on('focus', function () { - var top = parseFloat($(obj).offset().top) + parseFloat(obj.offsetHeight); - var left = parseFloat($(obj).offset().left); - clearInterval($(obj).data('mtimer')); - $('#global_calendar_div').remove(); - $('body').append('
    '+ - '
    '); - $('#global_calendar_div') - .html($().w2field('calendar_get', obj.value, options)) - .css({ - left: left + 'px', - top: top + 'px' - }) - .data('el', obj) - .show(); - var max = $(window).width() + $(document).scrollLeft() - 1; - if (left + $('#global_calendar_div').width() > max) { - $('#global_calendar_div').css('left', (max - $('#global_calendar_div').width()) + 'px'); - } - // monitors - var mtimer = setInterval(function () { - var max = $(window).width() + $(document).scrollLeft() - 1; - var left = $(obj).offset().left; - if (left + $('#global_calendar_div').width() > max) left = max - $('#global_calendar_div').width(); - // monitor if moved - if ($('#global_calendar_div').data('position') != ($(obj).offset().left) + 'x' + ($(obj).offset().top + obj.offsetHeight)) { - $('#global_calendar_div').css({ - '-webkit-transition': '.2s', - left: left + 'px', - top : ($(obj).offset().top + obj.offsetHeight) + 'px' - }).data('position', ($(obj).offset().left) + 'x' + ($(obj).offset().top + obj.offsetHeight)); - } - // monitor if destroyed - if ($(obj).length == 0 || ($(obj).offset().left == 0 && $(obj).offset().top == 0)) { - clearInterval(mtimer); - $('#global_calendar_div').remove(); - return; - } - }, 100); - $(obj).data('mtimer', mtimer); - }) - .on('blur', function (event) { - // trim empty spaces - $(obj).val($.trim($(obj).val())); - // check if date is valid - if ($.trim($(obj).val()) != '' && !w2utils.isDate($(obj).val(), options.format)) { - $(this).w2tag(w2utils.lang('Not a valid date') + ': '+ options.format); - } - clearInterval($(obj).data('mtimer')); - $('#global_calendar_div').remove(); - }) - .on('keypress', function (event) { - var obj = this; - setTimeout(function () { - $('#global_calendar_div').html( $().w2field('calendar_get', obj.value, options) ); - }, 10); - }); setTimeout(function () { - // if it is unix time - convert to readable date - if (w2utils.isInt(obj.value)) obj.value = w2utils.formatDate(obj.value, options.format); + 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); + // remove if already displaed + if (obj.helpers.prefix) $(obj.helpers.prefix).remove(); + if (obj.options.prefix !== '') { + // 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) + 2) + '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); - break; - - case 'time': - break; + }, - case 'datetime': - break; - - case 'color': + addSuffix: function () { var obj = this; - var defaults = { - prefix : '#', - suffix : '
    ' - } - options = $.extend({}, defaults, options); - // -- insert div for color - $(this) - .attr('maxlength', 6) - .on('focus', function () { - var top = parseFloat($(obj).offset().top) + parseFloat(obj.offsetHeight); - var left = parseFloat($(obj).offset().left); - clearInterval($(obj).data('mtimer')); - $('#global_color_div').remove(); - $('body').append('
    '+ - '
    '); - $('#global_color_div') - .html($().w2field('getColorHTML', obj.value)) - .css({ - left: left + 'px', - top: top + 'px' - }) - .data('el', obj) - .show(); - var max = $(window).width() + $(document).scrollLeft() - 1; - if (left + $('#global_color_div').width() > max) { - $('#global_color_div').css('left', (max - $('#global_color_div').width()) + 'px'); - } - // monitors - var mtimer = setInterval(function () { - var max = $(window).width() + $(document).scrollLeft() - 1; - var left = $(obj).offset().left; - if (left + $('#global_color_div').width() > max) left = max - $('#global_color_div').width(); - // monitor if moved - if ($('#global_color_div').data('position') != ($(obj).offset().left) + 'x' + ($(obj).offset().top + obj.offsetHeight)) { - $('#global_color_div').css({ - '-webkit-transition': '.2s', - left: left + 'px', - top : ($(obj).offset().top + obj.offsetHeight) + 'px' - }).data('position', ($(obj).offset().left) + 'x' + ($(obj).offset().top + obj.offsetHeight)); - } - // monitor if destroyed - if ($(obj).length == 0 || ($(obj).offset().left == 0 && $(obj).offset().top == 0)) { - clearInterval(mtimer); - $('#global_color_div').remove(); - return; - } - }, 100); - $(obj).data('mtimer', mtimer); - }) - .on('click', function () { - $(this).trigger('focus'); - }) - .on('blur', function (event) { - // trim empty spaces - $(obj).val($.trim($(obj).val())); - clearInterval($(obj).data('mtimer')); - $('#global_color_div').remove(); - }) - .on('keydown', function (event) { // need this for cut/paster - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { - var obj = this; - $(this).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); - } - }) - .on('keyup', function (event) { - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) $(this).prop('maxlength', 6); - }) - .on('keypress', function (event) { // keyCode & charCode differ in FireFox - if (event.keyCode == 13) $(this).change(); - //if (event.ct) - var ch = String.fromCharCode(event.charCode); - if (!w2utils.isHex(ch, true)) { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; - } - }) - .on('change', function (event) { - var color = '#' + $(this).val(); - if ($(this).val().length != 6 && $(this).val().length != 3) color = ''; - $(this).next().find('div').css('background-color', color); - }); - if (options.prefix != '') { - $(this).before( - '
    '+ - options.prefix + - '
    '); - var helper = $(this).prev(); - helper - .css({ - 'color' : $(this).css('color'), - 'font-family' : $(this).css('font-family'), - 'font-size' : $(this).css('font-size'), - 'padding-top' : $(this).css('padding-top'), - 'padding-bottom': $(this).css('padding-bottom'), - 'padding-left' : $(this).css('padding-left'), - 'padding-right' : 0, - 'margin-top' : (parseInt($(this).css('margin-top')) + 1) + 'px', - 'margin-bottom' : (parseInt($(this).css('margin-bottom')) + 1) + 'px', - 'margin-left' : 0, - 'margin-right' : 0 + 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) + 2) + '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 + // 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') }) - .on('click', function () { - $(this).next().focus(); - }); - $(this).css('padding-left', (helper.width() + parseInt($(this).css('padding-left')) + 2) + 'px'); - } - if (options.suffix != '') { - $(this).after( - '
    '+ - options.suffix + - '
    '); - var helper = $(this).next(); - helper + .find('input') .css({ - 'color' : $(this).css('color'), - 'font-family' : $(this).css('font-family'), - 'font-size' : $(this).css('font-size'), - 'padding-top' : $(this).css('padding-top'), - 'padding-bottom': $(this).css('padding-bottom'), - 'padding-left' : '3px', - 'padding-right' : $(this).css('padding-right'), - 'margin-top' : (parseInt($(this).css('margin-top')) + 1) + 'px', - 'margin-bottom' : (parseInt($(this).css('margin-bottom')) + 1) + 'px' - }) - .on('click', function () { - $(this).prev().focus(); + 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 > 0 ? width + 6 : 0), + "background-color" : 'transparent' }); - helper.css('margin-left', '-'+ (helper.width() + parseInt($(this).css('padding-right')) + 4) + 'px'); - var pr = helper.width() + parseInt($(this).css('padding-right')) + 4; - $(this).css('padding-right', pr + 'px'); - // set color to current - helper.find('div').css('background-color', '#' + $(obj).val()); - } - break; - - case 'select': - case 'list': - if (this.tagName != 'SELECT') { - console.log('ERROR: You can only apply $().w2field(\'list\') to a SELECT element'); - return; - } - var defaults = { - url : '', - items : [], - value : null, - showNone : true - }; - var obj = this; - var settings = $.extend({}, defaults, options); - $(obj).data('settings', settings); - // define refresh method - obj.refresh = function () { - var settings = $(obj).data('settings'); - var html = ''; - var items = w2field.cleanItems(settings.items); - // build options - if (settings.showNone) html = ''; - for (var i in items) { - if (!settings.showNone && settings.value == null) settings.value = items[i].id; - html += ''; - } - $(obj).html(html); - $(obj).val(settings.value); - if ($(obj).val() != settings.value) $(obj).change(); - } - // pull from server - if (settings.url != '' ) { - $.ajax({ - type : 'GET', - dataType : 'text', - url : settings.url, - complete: function (xhr, status) { - if (status == 'success') { - var data = $.parseJSON(xhr.responseText); - var settings = $(obj).data('settings'); - settings.items = w2field.cleanItems(data.items); - $(obj).data('settings', settings); - obj.refresh(); - } - } - }); - } else { // refresh local - obj.refresh(); - } - break; - - case 'enum': - if (this.tagName != 'INPUT') { - console.log('ERROR: You can only apply $().w2field(\'enum\') to an INPUT element'); - return; - } - var defaults = { - url : '', - items : [], - selected : [], // preselected items - max : 0, // maximum number of items that can be selected 0 for unlim - maxHeight : 172, // max height for input control to grow - showAll : false, // if true then show selected item in drop down - match : 'begins with', // ['begins with', 'contains'] - render : null, // render(item, selected) - maxCache : 500, // number items to cache - onShow : null, // when overlay is shown onShow(settings) - onHide : null, // when overlay is hidden onHide(settings) - onAdd : null, // onAdd(item, settings) - onRemove : null, // onRemove(index, settings) - onItemOver : null, - onItemOut : null, - onItemClick : null - } - var obj = this; - var settings = $.extend({}, defaults, options); - - // normalize items and selected - settings.items = w2field.cleanItems(settings.items); - settings.selected = w2field.cleanItems(settings.selected); - - $(this).data('selected', settings.selected); - $(this).css({ - 'padding' : '0px', - 'border-color' : 'transparent', - 'background-color' : 'transparent', - 'outline' : 'none' - }); - - // add item to selected - this.add = function (item) { - if ($(this).attr('readonly')) return; - var selected = $(this).data('selected'); - var settings = $(this).data('settings'); - if (typeof settings.onAdd == 'function') { - var cancel = settings.onAdd(item, settings); - if (cancel === false) return; - } - if (!$.isArray(selected)) selected = []; - if (settings.max != 0 && settings.max <= selected.length) { - // if max reached, replace last - selected.splice(selected.length - 1, 1); - } - selected.push(item); - $(this).data('last_del', null); - $(this).trigger('change'); - } - - this.remove = function (index) { - var settings = $(this).data('settings'); - if (typeof settings.onRemove == 'function') { - var cancel = settings.onRemove(index, settings); - if (cancel === false) return; - } - if ($(this).attr('readonly')) return; - $(this).data('selected').splice(index, 1); - $(this).parent().find('[title=Remove][index='+ index +']').remove(); - this.refresh(); - w2field.list_render.call(this); - $(this).trigger('change'); - } - - this.show = function () { - if ($(this).attr('readonly')) return; - var settings = $(this).data('settings'); - // insert global div - if ($('#w2ui-global-items').length == 0) { - $('body').append('
    '); - } else { - // ignore second click - return; - } - var div = $('#w2ui-global-items'); - div.css({ - display : 'block', - left : ($(obj).offset().left) + 'px', - top : ($(obj).offset().top + obj.offsetHeight + 3) + 'px' - }) - .width(w2utils.getSize(obj, 'width')) - .data('position', ($(obj).offset().left) + 'x' + ($(obj).offset().top + obj.offsetHeight)); - - // show drop content - w2field.list_render.call(obj); - - // monitors - var monitor = function () { - var div = $('#w2ui-global-items'); - // monitor if destroyed - if ($(obj).length == 0 || ($(obj).offset().left == 0 && $(obj).offset().top == 0)) { - clearInterval($(obj).data('mtimer')); - hide(); - return; - } - // monitor if moved - if (div.data('position') != ($(obj).offset().left) + 'x' + ($(obj).offset().top + obj.offsetHeight)) { - div.css({ - '-webkit-transition': '.2s', - left: ($(obj).offset().left) + 'px', - top : ($(obj).offset().top + obj.offsetHeight + 3) + 'px' - }) - .data('position', ($(obj).offset().left) + 'x' + ($(obj).offset().top + obj.offsetHeight)); - // if moved then resize - setTimeout(function () { - w2field.list_render.call(obj, $(obj).data('last_search')); - }, 200); - } - if (div.length > 0) $(obj).data('mtimer', setTimeout(monitor, 100)); - }; - $(obj).data('mtimer', setTimeout(monitor, 100)); - // onShow - if (typeof settings.onShow == 'function') settings.onShow.call(this, settings); - } - - this.hide = function () { - var settings = $(this).data('settings'); - clearTimeout($(obj).data('mtimer')); - $('#w2ui-global-items').remove(); - // onShow - if (typeof settings.onHide == 'function') settings.onHide.call(this, settings); - } - - // render controls with all items in it - this.refresh = function () { - var obj = this; - // remove all items - $($(this).data('div')).remove(); - // rebuild it - var margin = 'margin-top: ' + $(this).css('margin-top') + '; ' + - 'margin-bottom: ' + $(this).css('margin-bottom') + '; ' + - 'margin-left: ' + $(this).css('margin-left') + '; ' + - 'margin-right: ' + $(this).css('margin-right') + '; '+ - 'width: ' + (w2utils.getSize(this, 'width') - - parseInt($(this).css('margin-left')) - - parseInt($(this).css('margin-right'))) + 'px; '; - var html = '
    '+ - '
      '; - var selected = $(this).data('selected'); - for (var s in selected) { - html += '
    • '+ - '
        
      '+ - selected[s].text + - '
    • '; - } - html += '
    • '+ - ' '+ - '
    • '+ - '
    '+ - '
    '; - $(this).before(html); - - var div = $(this).prev()[0]; - $(this).data('div', div); - // click on item - $(div).find('li') - .data('mouse', 'out') - .on('click', function (event) { - if ($(event.target).hasClass('nomouse')) return; - if (event.target.title == w2utils.lang('Remove')) { - obj.remove($(event.target).attr('index')); - return; - } - event.stopPropagation(); - if (typeof settings.onItemClick == 'function') settings.onItemClick.call(this, settings); - }) - .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') { - if (typeof settings.onItemOver == 'function') settings.onItemOver.call(this, settings); - } - $(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'); - if (typeof settings.onItemOut == 'function') settings.onItemOut.call(this, settings); - } - }, 0); - }); - $(div) // click on item + // INPUT events + helper.find('input') .on('click', function (event) { - $(this).find('input').focus(); + if ($('#w2ui-overlay').length == 0) obj.focus(event); + event.stopPropagation(); }) - .find('input') .on('focus', function (event) { - $(div).css({ 'outline': 'auto 5px -webkit-focus-ring-color', 'outline-offset': '-2px' }); - obj.show(); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; + $(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) { - $(div).css('outline', 'none'); - obj.hide(); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }); - // adjust height - obj.resize(); - } - this.resize = function () { - var settings = $(this).data('settings'); - var div = $(this).prev(); - var cntHeight = $(div).find('>div').height(); //w2utils.getSize(div, 'height'); - if (cntHeight < 23) cntHeight = 23; - if (cntHeight > settings.maxHeight) cntHeight = settings.maxHeight; - $(div).height(cntHeight + (cntHeight % 23 == 0 ? 0 : 23 - cntHeight % 23) ); - if (div.length > 0) div[0].scrollTop = 1000; - $(this).height(cntHeight); - } - // init control - $(this).data('settings', settings).attr('tabindex', -1); + $(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(); - break; - - case 'upload': - if (this.tagName != 'INPUT') { - console.log('ERROR: You can only apply $().w2field(\'upload\') to an INPUT element'); - return; - } - // init defaults - var defaults = { - url : '', // not yet implemented - base64 : true, // if true max file size is 20mb (only tru for now) - hint : w2utils.lang('Attach files by dragging and dropping or Click to Select'), - max : 0, // max number of files, 0 - unlim - maxSize : 0, // max size of all files, 0 - unlim - maxFileSize : 0, // max size of a single file, 0 -unlim - onAdd : null, - onRemove : null, - onItemClick : null, - onItemDblClick : null, - onItemOver : null, - onItemOut : null, - onProgress : null, // not yet implemented - onComplete : null // not yet implemented - } - var obj = this; - var settings = $.extend({}, defaults, options); - if (settings.base64 === true) { - if (settings.maxSize == 0) settings.maxSize = 20 * 1024 * 1024; // 20mb - if (settings.maxFileSize == 0) settings.maxFileSize = 20 * 1024 * 1024; // 20mb - } - var selected = settings.selected; - delete settings.selected; - if (!$.isArray(selected)) selected = []; - $(this).data('selected', selected).data('settings', settings).attr('tabindex', -1); - w2field.upload_init.call(this); - - this.refresh = function () { - var obj = this; - var div = $(this).data('div'); - var settings = $(this).data('settings'); - var selected = $(this).data('selected'); - $(div).find('li').remove(); - $(div).find('> span:first-child').css('line-height', ($(div).height() - w2utils.getSize(div, '+height') - 8) + 'px'); - for (var s in selected) { - var file = selected[s]; - // add li element - var cnt = $(div).find('.file-list li').length; - $(div).find('> span:first-child').remove(); - $(div).find('.file-list').append('
  • ' + - '
      
    ' + - ' ' + file.name + '' + - ' - ' + w2utils.size(file.size) + ''+ - '
  • '); - var li = $(div).find('.file-list #file-' + cnt); - var previewHTML = ""; - if ((/image/i).test(file.type)) { // image - previewHTML = '
    '+ - ' '+ - '
    '; - } - var td1 = 'style="padding: 3px; text-align: right; color: #777;"'; - var td2 = 'style="padding: 3px"'; - previewHTML += '
    '+ - ' '+ - ' '+ - ' '+ - ' '+ - ' '+ - '
    Name:'+ file.name +'
    Size:'+ w2utils.size(file.size) +'
    Type:' + - ' '+ file.type +''+ - '
    Modified:'+ w2utils.date(file.modified) +'
    '+ - '
    '; - li.data('file', file) - .on('click', function (event) { - if (typeof settings.onItemClick == 'function') { - var ret = settings.onItemClick.call(obj, $(this).data('file')); - if (ret === false) return; - } - if (!$(event.target).hasClass('file-delete')) event.stopPropagation(); - }) - .on('dblclick', function (event) { - if (typeof settings.onItemDblClick == 'function') { - var ret = settings.onItemDblClick.call(obj, $(this).data('file')); - if (ret === false) return; - } - event.stopPropagation(); - if (document.selection) document.selection.empty(); else document.defaultView.getSelection().removeAllRanges(); - }) - .on('mouseover', function (event) { - if (typeof settings.onItemOver == 'function') { - var ret = settings.onItemOver.call(obj, $(this).data('file')); - if (ret === false) return; - } - var file = $(this).data('file'); - $(this).w2overlay( - previewHTML.replace('##FILE##', (file.content ? 'data:'+ file.type +';base64,'+ file.content : '')), - { top: -4 } - ); - }) - .on('mouseout', function () { - if (typeof settings.onItemOut == 'function') { - var ret = settings.onItemOut.call(obj, $(this).data('file')); - if (ret === false) return; - } - $(this).w2overlay(); - }); - } + }, + + 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 = '
    '+ + '
    '+ + '
      '+ + '
    • '+ + ' '+ + '
    • ' + '
    '+ + '
    '+ + '
    '; } - this.refresh(); - break; - - case 'slider': - // for future reference - break; - - default: - console.log('ERROR: w2field does not recognize "'+ options.type + '" field type.'); - break; - } - }); - }, - - // ****************************************************** - // -- Implementation - - addType: function (type, handler) { - w2field.customTypes[String(type).toLowerCase()] = handler; - }, - - cleanItems: function (items) { - var newItems = []; - for (var i in items) { - var id = ''; - var text = ''; - var opt = items[i]; - if (opt == null) continue; - if ($.isPlainObject(items)) { - id = i; - text = opt; - } else { - if (typeof opt == 'object') { - if (typeof opt.id != 'undefined') id = opt.id; - if (typeof opt.value != 'undefined') id = opt.value; - if (typeof opt.txt != 'undefined') text = opt.txt; - if (typeof opt.text != 'undefined') text = opt.text; - } - if (typeof opt == 'string') { - if (String(opt) == '') continue; - id = opt; - text = opt; - opt = {}; - } - } - if (w2utils.isInt(id)) id = parseInt(id); - if (w2utils.isFloat(id)) id = parseFloat(id); - newItems.push($.extend({}, opt, { id: id, text: text })); - } - return newItems; - }, - - // ****************************************************** - // -- Upload - - upload_init: function () { - var obj = this; // this -> input element - var settings = $(this).data('settings'); - // create drop area if needed - var el = $(obj).prev(); - if (el.length > 0 && el[0].tagName == 'DIV' && el.hasClass('w2ui-upload')) el.remove(); - // rebuild it - var margin = 'margin-top: ' + $(obj).css('margin-top') + '; ' + - 'margin-bottom: ' + $(obj).css('margin-bottom') + '; ' + - 'margin-left: ' + $(obj).css('margin-left') + '; ' + - 'margin-right: ' + $(obj).css('margin-right') + '; '+ - 'width: ' + (w2utils.getSize(obj, 'width') - - parseInt($(obj).css('margin-left')) - - parseInt($(obj).css('margin-right'))) + 'px; '+ - 'height: ' + (w2utils.getSize(obj, 'height') - - parseInt($(obj).css('margin-top')) - - parseInt($(obj).css('margin-bottom'))) + 'px; '; - var html = - '
    '+ - ' '+ settings.hint +''+ - '
      '+ - ' '+ - '
      '; - $(obj) - .css({ - 'display1' : 'none', - 'border-color' : 'transparent' - }) - .before(html); - $(obj).data('div', $(obj).prev()[0]); - var div = $(obj).data('div'); - // if user selects files through input control - $(div).find('.file-input') - .off('change') - .on('change', function () { - if (typeof this.files !== "undefined") { - for (var i = 0, l = this.files.length; i < l; i++) { - w2field.upload_add.call(obj, this.files[i]); - } - } - }); - - // if user clicks drop zone - $(div) - .off('click') - .on('click', function (event) { - $(div).w2tag(); - if (event.target.tagName == 'LI' || $(event.target).hasClass('file-size')) { - return; - } - if ($(event.target).hasClass('file-delete')) { - w2field.upload_remove.call(obj, event.target.parentNode); - return; - } - if (event.target.tagName != 'INPUT') { - var settings = $(obj).data('settings'); - var selected = $(obj).data('selected'); - var cnt = 0; - for (var s in selected) { cnt++; } - if (cnt < settings.max || settings.max == 0) $(div).find('.file-input').click(); - } - }) - .off('dragenter') - .on('dragenter', function (event) { - $(div).addClass('dragover'); - }) - .off('dragleave') - .on('dragleave', function (event) { - $(div).removeClass('dragover'); - }) - .off('drop') - .on('drop', function (event) { - $(div).removeClass('dragover'); - var files = event.originalEvent.dataTransfer.files; - for (var i=0, l=files.length; i input element - var div = $(obj).data('div'); - var settings = $(obj).data('settings'); - var selected = $(obj).data('selected'); - var newItem = { - name : file.name, - type : file.type, - modified : file.lastModifiedDate, - size : file.size, - content : null - }; - var size = 0; - var cnt = 0; - for (var s in selected) { size += selected[s].size; cnt++; } - // check params - if (settings.maxFileSize != 0 && newItem.size > settings.maxFileSize) { - var err = 'Maximum file size is '+ w2utils.size(settings.maxFileSize); - $(div).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (settings.maxSize != 0 && size + newItem.size > settings.maxSize) { - var err = 'Maximum total size is '+ w2utils.size(settings.maxFileSize); - $(div).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (settings.max != 0 && cnt >= settings.max) { - var err = 'Maximum number of files is '+ settings.max; - $(div).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (typeof settings.onAdd == 'function') { - var ret = settings.onAdd.call(obj, newItem); - if (ret === false) return; - } - selected.push(newItem); - // read file as base64 - if (typeof FileReader !== "undefined" && settings.base64 === true) { - 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).trigger('change'); - }; - })(); - reader.readAsDataURL(file); - } else { - obj.refresh(); - $(obj).trigger('change'); - } - }, - - upload_remove: function (li) { - var obj = this; // this -> input element - var div = $(obj).data('div'); - var settings = $(obj).data('settings'); - var selected = $(obj).data('selected'); - var file = $(li).data('file'); - // run event - if (typeof settings.onRemove == 'function') { - var ret = settings.onRemove.call(obj, file); - if (ret === false) return false; - } - // remove from selected - for (var i = selected.length - 1; i >= 0; i--) { - if (selected[i].name == file.name && selected[i].size == file.size) { - selected.splice(i, 1); - } - } - $(li).fadeOut('fast'); - setTimeout(function () { - $(li).remove(); - // if all files remoted - if (selected.length == 0) { - $(div).prepend(''+ settings.hint +''); - } - obj.refresh(); - $(obj).trigger('change'); - }, 300); - }, - - // ****************************************************** - // -- Enum - - list_render: function (search) { - var obj = this; - var div = $('#w2ui-global-items'); - var settings = $(this).data('settings'); - var items = settings.items; - var selected = $(this).data('selected'); - if (div.length == 0) return; // if it is hidden - - // build overall html - if (typeof search == 'undefined') { - var html = ''; - html += '
      '; - div.html(html); - search = ''; - } - $(this).data('last_search', search); - if (typeof $(obj).data('last_index') == 'undefined' || $(obj).data('last_index') == null) $(obj).data('last_index', 0); - - // pull items from url - if (typeof settings.last_total == 'undefined') settings.last_total = -1; - if (typeof settings.last_search_len == 'undefined') settings.last_search_len = 0; - if (typeof settings.last_search_match == 'undefined') settings.last_search_match = -1; - if (settings.url != '' && ( - (items.length == 0 && settings.last_total != 0) - || (search.length > settings.last_search_len && settings.last_total > settings.maxCache) - || (search.length < settings.last_search_match && search.length != settings.last_search_len) - ) - ) { - var match = false; - if (settings.last_total < settings.maxCache) match = true; - $.ajax({ - type : 'GET', - dataType : 'text', - url : settings.url, - data : { - search : search, - max : settings.maxCache - }, - complete: function (xhr, status) { - settings.last_total = 0; - if (status == 'success') { - var data = $.parseJSON(xhr.responseText); - if (match == false && data.total < settings.maxCache) { settings.last_search_match = search.length; } - settings.last_search_len = search.length; - settings.last_total = data.total - settings.items = data.items; - w2field.list_render.call(obj, search); - } - } - }); - } - - // build items - var i = 0; - var ihtml = '
        '; - // get ids of all selected items - var ids = []; - for (var a in selected) ids.push(w2utils.isInt(selected[a].id) ? parseInt(selected[a].id) : String(selected[a].id)) - // build list - var group = ''; - for (var a in items) { - var id = items[a].id; - var txt = items[a].text; - // if already selected - if ($.inArray(w2utils.isInt(id) ? parseInt(id) : String(id), ids) != -1 && settings.showAll !== true) continue; - // check match with search - var txt1 = String(search).toLowerCase(); - var txt2 = txt.toLowerCase(); - var match = (txt1.length <= txt2.length && txt2.substr(0, txt1.length) == txt1); - if (settings.match.toLowerCase() == 'contains' && txt2.indexOf(txt1) != -1) match = true; - if (match) { - if (typeof settings['render'] == 'function') { - txt = settings['render'](items[a], selected); - } - if (txt !== false) { - // render group if needed - if (typeof items[a].group != 'undefined' && items[a].group != group) { - group = items[a].group; - ihtml += '
      • '+ group +'
      • '; - } - // render item - ihtml += '\n
      • '+ - txt +'
      • '; - if (i == $(obj).data('last_index')) $(obj).data('last_item', items[a]); - i++; - } - } - } - ihtml += '
      '; - if (i == 0) { - ihtml = '
      '+ w2utils.lang('No items found') +'
      '; - var noItems = true; - } - div.find('.w2ui-items-list').html(ihtml); - $(this).data('last_max', i-1); - - // scroll selected into view - if (div.find('li.selected').length > 0) div.find('li.selected')[0].scrollIntoView(false); - - // if menu goes off screen - add scrollbar - div.css({ '-webkit-transition': '0s', height : 'auto' }); - var max_height = parseInt($(document).height()) - parseInt(div.offset().top) - 8; - if (parseInt(div.height()) > max_height) { - div.css({ - height : (max_height - 5) + 'px', - overflow: 'show' - }); - $(div).find('.w2ui-items-list').css({ - height : (max_height - 15) + 'px', - overflow: 'auto' - }); - } - - // add events - $(div) - .off('mousedown') - .on('mousedown', function (event) { - var target = event.target; - if (target.tagName != "LI") target = $(target).parents('li'); - var id = $(target).attr('index'); - if (!id) return; - var item = settings.items[id]; - if (typeof id == 'undefined') { if (event.preventDefault) event.preventDefault(); else return false; } - obj.add(item); - $(obj).data('last_index', 0); - obj.refresh(); - w2field.list_render.call(obj, ''); - } - ); - $(obj).prev().find('li > input') - .val(search) - .css('max-width', ($(div).width() - 25) + 'px') - .width(((search.length + 2) * 6) + 'px') - .focus() - .on('click', function (event) { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .off('keyup') - .on('keyup', function (event) { - var inp = this; - setTimeout(function () { - var curr = $(obj).data('last_index'); - switch (event.keyCode) { - case 38: // up - curr--; - if (curr < 0) curr = 0; - $(obj).data('last_index', curr); - if (event.preventDefault) event.preventDefault(); - break; - case 40: // down - curr++; - if (curr > $(obj).data('last_max')) curr = $(obj).data('last_max'); - $(obj).data('last_index', curr); - if (event.preventDefault) event.preventDefault(); - break; - case 13: // enter - if (typeof $(obj).data('last_item') == 'undefined' || $(obj).data('last_item') == null || noItems === true) break; - var selected = $(obj).data('selected'); - obj.add($(obj).data('last_item')); - // select next - if (curr > $(obj).data('last_max') - 1) curr = $(obj).data('last_max')-1; - $(obj).data('last_index', curr); - $(obj).data('last_item', null); - // refrech - $(inp).val(''); + 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(); - if (event.preventDefault) event.preventDefault(); - break; - case 8: // backspace - if (String(inp.value) == '') { - if (typeof $(obj).data('last_del') == 'undefined' || $(obj).data('last_del') == null) { - // mark for deletion - var selected = $(obj).data('selected'); - if (!$.isArray(selected)) selected = []; - $(obj).data('last_del', selected.length-1); - // refrech - obj.refresh(); - } else { - // delete marked one - var selected = $(obj).data('selected'); - obj.remove(selected.length - 1); - } + $(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; + } } - break; - default: - $(obj).data('last_index', 0); - $(obj).data('last_del', null); - break; + return menu; + } else if (typeof menu == 'object') { + var tmp = [] + for (var m in menu) tmp.push({ id: m, text: menu[m] }); + return tmp; } - // adjust height - obj.resize(); - - // refresh menu - if (!(event.keyCode == 8 && String(inp.value) == '')) { - $(obj).prev().find('li').css('opacity', '1'); - $(obj).data('last_del', null); + }, + + 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 += ''; } - if ($.inArray(event.keyCode, [16,91,37,39]) == -1) { // command and shift keys and arrows - w2field.list_render.call(obj, inp.value); + 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] + ''; } - }, 10); - }) - }, - - // ****************************************************** - // -- Calendar - - calendar_get: function (date, options) { - var td = new Date(); - var today = (Number(td.getMonth())+1) + '/' + td.getDate() + '/' + (String(td.getYear()).length > 3 ? td.getYear() : td.getYear() + 1900); - if (String(date) == '' || String(date) == 'undefined') date = w2utils.formatDate(today, options.format); - if (!w2utils.isDate(date, options.format)) date = w2utils.formatDate(today, options.format); - // format date - var tmp = date.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/'); - var tmp2 = options.format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase(); - var dt = new Date(); - if (tmp2 == 'mm/dd/yyyy') dt = new Date(tmp[0] + '/' + tmp[1] + '/' + tmp[2]); - if (tmp2 == 'm/d/yyyy') dt = new Date(tmp[0] + '/' + tmp[1] + '/' + tmp[2]); - if (tmp2 == 'dd/mm/yyyy') dt = new Date(tmp[1] + '/' + tmp[0] + '/' + tmp[2]); - if (tmp2 == 'd/m/yyyy') dt = new Date(tmp[1] + '/' + tmp[0] + '/' + tmp[2]); - if (tmp2 == 'yyyy/dd/mm') dt = new Date(tmp[2] + '/' + tmp[1] + '/' + tmp[0]); - if (tmp2 == 'yyyy/d/m') dt = new Date(tmp[2] + '/' + tmp[1] + '/' + tmp[0]); - if (tmp2 == 'yyyy/mm/dd') dt = new Date(tmp[1] + '/' + tmp[2] + '/' + tmp[0]); - if (tmp2 == 'yyyy/m/d') dt = new Date(tmp[1] + '/' + tmp[2] + '/' + tmp[0]); - var html = '' + - ''+ - // ''+ - '
      '+ $().w2field('calendar_month', (dt.getMonth() + 1), dt.getFullYear(), options) +'
      '; - return html; - }, - - calendar_next: function(month_year) { - var tmp = String(month_year).split('/'); - var month = tmp[0]; - var year = tmp[1]; - if (parseInt(month) < 12) { - month = parseInt(month) + 1; - } else { - month = 1; - year = parseInt(year) + 1; - } - var options = $($('#global_calendar_div.w2ui-calendar').data('el')).data('options'); - $('#global_calendar_div.w2ui-calendar').html( $().w2field('calendar_get', w2utils.formatDate(month+'/1/'+year, options.format), options) ); - }, - - calendar_previous: function(month_year) { - var tmp = String(month_year).split('/'); - var month = tmp[0]; - var year = tmp[1]; - if (parseInt(month) > 1) { - month = parseInt(month) - 1; - } else { - month = 12; - year = parseInt(year) - 1; - } - var options = $($('#global_calendar_div.w2ui-calendar').data('el')).data('options'); - $('#global_calendar_div.w2ui-calendar').html( $().w2field('calendar_get', w2utils.formatDate(month+'/1/'+year, options.format), options) ); - }, - - calendar_month: function(month, year, options) { - 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 = (Number(td.getMonth())+1) + '/' + td.getDate() + '/' + (String(td.getYear()).length > 3 ? td.getYear() : td.getYear() + 1900); - - year = Number(year); - month = Number(month); - if (year === null || year === '') year = String(td.getYear()).length > 3 ? td.getYear() : td.getYear() + 1900; - if (month === null || month === '') month = Number(td.getMonth())+1; - if (month > 12) { month = month - 12; year++; } - if (month < 1 || month == 0) { month = month + 12; year--; } - if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; } - if (year == null) { year = td.getYear(); } - if (month == null) { month = td.getMonth()-1; } - - // start with the required date - var td = new Date(); - td.setDate(1); - td.setMonth(month-1); - td.setYear(year); - 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 = month + '/' + day + '/' + year; - - 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 blocked = ''; - if (options.colored) if (options.colored[dt] != undefined) { // if there is predefined colors for dates - tmp = options.colored[dt].split(':'); - bgcol = 'background-color: ' + tmp[0] + ';'; - col = 'color: ' + tmp[1] + ';'; - } - var noSelect = false; - // enable range - if (options.start || options.end) { - var start = new Date(options.start); - var end = new Date(options.end); - var current = new Date(dt); - if (current < start || current > end) { - blocked = ' w2ui-blocked-date'; - noSelect = true; - } - } - // block predefined dates - if (options.blocked && $.inArray(dt, options.blocked) != -1) { - blocked = ' w2ui-blocked-date'; - noSelect = true; - } - html += ''; - day++; - } - html += '
        
      '; - if (ci % 7 == 0 || (weekDay == 0 && ci == 1)) html += '
      '; - return html; - }, + 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 +'
      '; + }, - getColorHTML: function (color) { - var html = '
      '+ - ''; - var colors = [ - ['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'] - ]; - for (var i=0; i<8; i++) { - html += ''; - for (var j=0; j<8; j++) { - html += ''; + 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 = + '
      '+ - '
      '+ - ' '+ (color == colors[i][j] ? '•' : ' ')+ - '
      '+ - '
      '+ + ' ' + + ' ' + + ' ' + + '
      '+ 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; } - html += ''; - if (i < 2) html += ''; - } - html += '
      '; - return html; } - }); - w2obj.field = w2field; + $.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 - * - Dependencies: jQuery, w2utils, w2fields, w2tabs, w2toolbar, w2alert - * - * == NICE TO HAVE == - * - refresh(field) - would refresh only one field - * - include delta on save - * - ************************************************************************/ +* Library: Web 2.0 UI for jQuery (using prototypical inheritance) +* - Following objects defined +* - 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 '; - if (field.type == 'list') 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; - }, + obj.last.xhr = $.ajax(ajaxOptions) + .done(function (data, status, xhr) { + obj.unlock(); + // event before + var eventData = obj.trigger({ phase: 'before', target: obj.name, type: 'save', xhr: xhr, status: status }); + if (eventData.isCancelled === true) 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 (data.status == 'success' && typeof callBack == 'function') callBack(data); + }) + .fail(function (xhr, status, error) { + // trigger event + var errorObj = { status: status, error: error, rawResponseText: xhr.responseText }; + var eventData2 = obj.trigger({ phase: 'before', type: 'error', error: errorObj, xhr: xhr }); + if (eventData2.isCancelled === true) return; + // default behavior + console.log('ERROR: server communication failed. The server should return', + { status: 'success' }, 'OR', { status: 'error', message: 'error message' }, + ', instead the AJAX request produced this: ', errorObj); + // event after + obj.trigger($.extend(eventData2, { phase: 'after' })); + }); + // 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 + }, - action: function (action, event) { - // event before - var eventData = this.trigger({ phase: 'before', target: action, type: 'action', originalEvent: event }); - if (eventData.isCancelled === true) return false; - // default actions - if (typeof (this.actions[action]) == 'function') { - this.actions[action].call(this, event); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - }, + 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 + var group = ''; + var 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 (typeof page == 'undefined') page = field.html.page; + if (field.html.caption == '') field.html.caption = field.name; + var input = ''; + if ((field.type === 'pass') || (field.type === 'password')){ + input = ''; + } + if (field.type == 'checkbox') input = ''; + if (field.type == 'textarea') input = ''; + if (field.type == 'toggle') input = '
      '; + if (field.html.group) { + if (group != '') html += '\n
      '; + html += '\n
      '+ field.html.group + '
      \n
      '; + group = field.html.group; + } + if (field.html.page != page && group != '') { + pages[pages.length-1] += '\n
      '; + group = ''; + } + html += '\n
      '+ + '\n '+ + '\n
      '+ input + w2utils.lang(field.html.text) + '
      '+ + '\n
      '; + if (typeof pages[field.html.page] == 'undefined') pages[field.html.page] = ''; + pages[field.html.page] += html; + page = field.html.page; + } + if (group != '') pages[pages.length-1] += '\n
      '; + if (this.tabs.tabs) { + for (var i = 0; i < this.tabs.tabs.length; i++) if (typeof pages[i] == 'undefined') pages[i] = ''; + } + for (var p in pages) pages[p] = '
      ' + pages[p] + '\n
      '; + // buttons if any + var buttons = ''; + if (!$.isEmptyObject(this.actions)) { + var addClass = ''; + buttons += '\n
      '; + for (var a in this.actions) { + if (['save', 'update', 'create'].indexOf(a.toLowerCase()) != -1) addClass = 'btn-green'; else addClass = ''; + buttons += '\n '; + } + buttons += '\n
      '; + } + return pages.join('') + buttons; + }, - resize: function () { - var obj = this; - // event before - var eventData = this.trigger({ phase: 'before', target: this.name, type: 'resize' }); - if (eventData.isCancelled === true) return false; - // 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) + - (this.tabs.tabs.length > 0 ? w2utils.getSize(tabs, 'height') : 0) + - (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) - + (obj.toolbar.items.length > 0 ? w2utils.getSize(toolbar, 'height') : 0)); - page.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0) - + (obj.toolbar.items.length > 0 ? w2utils.getSize(toolbar, 'height') + 5 : 0) - + (obj.tabs.tabs.length > 0 ? w2utils.getSize(tabs, 'height') + 5 : 0)); - page.css('bottom', (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0)); - } - }, + 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' })); + }, - refresh: function () { - 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 false; - // 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' && 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' && 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, '\\\\') +'"]')[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; - $(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 ((field.type == 'enum' || field.type == 'upload') && $(this).data('selected')) { - var new_arr = $(this).data('selected'); - var cur_arr = obj.record[this.name]; - var value_new = []; - var value_previous = []; - if ($.isArray(new_arr)) for (var i in new_arr) value_new[i] = $.extend(true, {}, new_arr[i]); // clone array - if ($.isArray(cur_arr)) for (var i in cur_arr) value_previous[i] = $.extend(true, {}, cur_arr[i]); // clone array - } - // 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 false; - } - // default action - var val = this.value; - if (this.type == 'checkbox') val = this.checked ? true : false; - if (this.type == 'radio') val = this.checked ? true : false; - if (field.type == 'enum') val = value_new; - if (field.type == 'upload') val = value_new; - 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; - switch (String(field.type).toLowerCase()) { - case 'email': - case 'text': - case 'textarea': - field.el.value = value; - break; - case 'date': - if (!field.options) field.options = {}; - if (!field.options.format) field.options.format = w2utils.settings.date_format; - field.el.value = value; - this.record[field.name] = value; - $(field.el).w2field($.extend({}, field.options, { type: 'date' })); - break; - case 'int': - field.el.value = value; - $(field.el).w2field('int'); - break; - case 'float': - field.el.value = value; - $(field.el).w2field('float'); - break; - case 'money': - field.el.value = value; - $(field.el).w2field('money'); - break; - case 'hex': - field.el.value = value; - $(field.el).w2field('hex'); - break; - case 'alphanumeric': - field.el.value = value; - $(field.el).w2field('alphaNumeric'); - break; - case 'checkbox': - if (this.record[field.name] == true || this.record[field.name] == 1 || this.record[field.name] == 't') { - $(field.el).prop('checked', true); + 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 { - $(field.el).prop('checked', false); - } - break; - case 'password': - // hide passwords - field.el.value = value; - break; - case 'select': - case 'list': - $(field.el).w2field($.extend({}, field.options, { type: 'list', value: value })); - break; - case 'enum': - if (typeof field.options == 'undefined' || (typeof field.options.url == 'undefined' && typeof field.options.items == 'undefined')) { - console.log("ERROR: (w2form."+ obj.name +") the field "+ field.name +" defined as enum but not field.options.url or field.options.items provided."); - break; - } - // normalize value - this.record[field.name] = w2obj.field.cleanItems(value); - value = this.record[field.name]; - $(field.el).w2field( $.extend({}, field.options, { type: 'enum', selected: value }) ); - break; - case 'upload': - $(field.el).w2field($.extend({}, field.options, { type: 'upload', selected: value })); - break; - default: - console.log('ERROR: field type "'+ field.type +'" is not recognized.'); - break; - } - } - // wrap pages in div - var tmp = $(this.box).find('.w2ui-page'); - for (var i = 0; i < tmp.length; i++) { - if ($(tmp[i]).find('> *').length > 1) $(tmp[i]).wrapInner('
      '); - } - // event after - this.trigger($.extend(eventData, { phase: 'after' })); - this.resize(); - }, + $('#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]; + if (typeof field.name == 'undefined' && typeof field.field != 'undefined') field.name = field.field; + if (typeof field.field == 'undefined' && typeof field.name != 'undefined') field.field = field.name; + 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 + } + } + if (field.type == 'toggle') value_new = ($(this).prop('checked') ? 1 : 0); + // 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', 'toggle'].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().parent().addClass('w2ui-required'); + } else { + $(field.el).parent().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.id) action = this.id; + if (this.name) action = this.name; + 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 'pass': + 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; + case 'toggle': + if (w2utils.isFloat(value)) value = parseFloat(value); + $(field.el).prop('checked', (value ? true : false)); + this.record[field.name] = (value ? 1 : 0); + break; + // enums + case 'list': + case 'combo': + if (field.type == 'list') { + var tmp_value = ($.isPlainObject(value) ? value.id : value); + // normalized options + var items = field.options.items; + if ($.isArray(items) && items.length > 0 && !$.isPlainObject(items[0])) { + field.options.items = w2obj.field.prototype.normMenu(items); + } + // find value from items + for (var i in field.options.items) { + var item = field.options.items[i]; + if (item.id == tmp_value) { + value = $.extend(true, {}, item); + obj.record[field.name] = value; + console.log(1); + 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+='"+s+'\t
      '+(r.caption==""?" ":r.caption)+"\t
      "}else i+='\t
      '+(t.caption==""?" ":t.caption)+"\t
      ";u+=t.span}return i+=""}function t(t){var u="",f,s,r,i,c,e,o,h;for(n.show.lineNumbers&&(u+='\t
      #
      "),n.show.selectColumn&&(u+='\t
      \t\t\t
      "),n.show.expandColumn&&(u+='\t
       
      '),f=0,s=0,r=0;r
      '),u+='"+h+'\t
      '+(i.caption==""?" ":i.caption)+"\t
      ")}return u+='
       
      ',u+=""}var n=this,i="";return this.show.columnHeaders&&(i=this.columnGroups.length>0?t(!0)+r()+t(!1):t(!0)),i},getRecordsHTML:function(){var r,i,n,t;for(this.show_extra=this.buffered>300?30:300,r=$("#grid_"+this.name+"_records"),i=Math.floor(r.height()/this.recordHeight)+this.show_extra+1,this.fixedBody||(i=this.buffered),n=""+this.getRecordHTML(-1,0),n+='\t',t=0;t\t\t
      ',this.last.range_start=0,this.last.range_end=i,n},getSummaryHTML:function(){var t,n;if(this.summary.length!=0){for(t="",n=0;n0&&$(i.box).find(".w2ui-grid-data > div").w2marker(n)},50))}var nt=+new Date,i=this,t=$("#grid_"+this.name+"_records"),l,v,p,f,e,h,s,y,k,u,o,r,g,a,b,w,c;if(this.records.length!=0&&t.length!=0&&t.height()!=0){if(this.show_extra=this.buffered>300?30:300,t.height()0&&this.refresh();return}if(l=Math.floor(t[0].scrollTop/this.recordHeight+1),v=Math.floor(t[0].scrollTop/this.recordHeight+1)+Math.round(t.height()/this.recordHeight),l>this.buffered&&(l=this.buffered),v>this.buffered&&(v=this.buffered),p=typeof this.url!="object"?this.url:this.url.get,$("#grid_"+this.name+"_footer .w2ui-footer-right").html(w2utils.formatNumber(this.offset+l)+"-"+w2utils.formatNumber(this.offset+v)+" "+w2utils.lang("of")+" "+w2utils.formatNumber(this.total)+(p?" ("+w2utils.lang("buffered")+" "+w2utils.formatNumber(this.buffered)+(this.offset>0?", skip "+w2utils.formatNumber(this.offset):"")+")":"")),p||this.fixedBody&&!(this.total<=300)){if(f=Math.floor(t[0].scrollTop/this.recordHeight)-this.show_extra,e=f+Math.floor(t.height()/this.recordHeight)+this.show_extra*2+1,f<1&&(f=1),e>this.total&&(e=this.total),h=t.find("#grid_"+this.name+"_rec_top"),s=t.find("#grid_"+this.name+"_rec_bottom"),String(h.next().prop("id")).indexOf("_expanded_row")!=-1&&h.next().remove(),String(s.prev().prop("id")).indexOf("_expanded_row")!=-1&&s.prev().remove(),y=parseInt(h.next().attr("line")),k=parseInt(s.prev().attr("line")),y=y-this.show_extra+2&&f>1)return;for(;;){if(u=t.find("#grid_"+this.name+"_rec_bottom").prev(),u.attr("line")=="top")break;if(parseInt(u.attr("line"))>e)u.remove();else break}for(u=t.find("#grid_"+this.name+"_rec_top").next(),o=u.attr("line"),o=="bottom"&&(o=e),r=parseInt(o)-1;r>=f;r--)this.records[r-1]&&(this.records[r-1].expanded===!0&&(this.records[r-1].expanded=!1),h.after(this.getRecordHTML(r-1,r)));d(),setTimeout(function(){i.refreshRanges()},0)}if(g=(f-1)*i.recordHeight,a=(this.buffered-e)*i.recordHeight,a<0&&(a=0),h.css("height",g+"px"),s.css("height",a+"px"),i.last.range_start=f,i.last.range_end=e,b=Math.floor(t[0].scrollTop/this.recordHeight),w=b+Math.floor(t.height()/this.recordHeight),w+10>this.buffered&&this.last.pull_more!==!0&&this.buffered
      '),i.last.pull_more=!0,i.last.xhr_offset+=i.limit,i.request("get-records")});c.find("td").text().indexOf("Load")==-1&&c.find("td").html("
      Load "+i.limit+" More...
      ")}this.buffered>=this.total-this.offset&&$("#grid_"+this.name+"_rec_more").hide();return}}},getRecordHTML:function(n,t,i){var r="",c,a,v,o,e,u,f,s,l;if(n==-1){r+='
      ',this.show.lineNumbers&&(r+=''),this.show.selectColumn&&(r+=''),this.show.expandColumn&&(r+='');for(c in this.columns)this.columns[c].hidden||(r+='');return r+='',r+=""}if(a=typeof this.url!="object"?this.url:this.url.get,i!==!0)if(this.searchData.length>0&&!a){if(n>=this.last.searchIds.length)return"";n=this.last.searchIds[n],record=this.records[n]}else{if(n>=this.records.length)return"";record=this.records[n]}else{if(n>=this.summary.length)return"";record=this.summary[n]}if(!record)return"";for(v=w2utils.escapeId(record.recid),o=!1,record.selected&&this.selectType=="row"&&(o=!0),r+='",this.show.lineNumbers&&(r+='"),this.show.selectColumn&&(r+='"),this.show.expandColumn&&(e="",e=record.expanded===!0?"-":"+",record.expanded=="none"&&(e=""),record.expanded=="spinner"&&(e='
      '),r+='"),u=0;;){if(f=this.columns[u],f.hidden)if(u++,typeof this.columns[u]=="undefined")break;else continue;var y=record.changed&&record.changes[f.field],p=this.getCellHTML(n,u,i),h="";if(typeof f.render=="string"&&(s=f.render.toLowerCase().split(":"),$.inArray(s[0],["number","int","float","money","percent"])!=-1&&(h="text-align: right"),$.inArray(s[0],["date"])!=-1&&(h="text-align: right")),l=!1,record.selected&&$.inArray(u,record.selectedColumns)!=-1&&(l=!0),r+='",u++,typeof this.columns[u]=="undefined")break}return r+='',r+=""},getCellHTML:function(n,t,i){var f=this.columns[t],e=i!==!0?this.records[n]:this.summary[n],r=this.parseField(e,f.field),c=e.changed&&typeof e.changes[f.field]!="undefined",s;if(c&&(r=e.changes[f.field]),(r==null||typeof r=="undefined")&&(r=""),typeof f.render!="undefined"){if(typeof f.render=="function"&&(r=f.render.call(this,e,n,t),r.length>=4&&r.substr(0,4)!=""+r+"")),typeof f.render=="object"&&(r="
      "+f.render[r]+"
      "),typeof f.render=="string"){var u=f.render.toLowerCase().split(":"),h="",o="";$.inArray(u[0],["number","int","float","money","percent"])!=-1&&(typeof u[1]!="undefined"&&w2utils.isInt(u[1])||(u[1]=0),u[1]>20&&(u[1]=20),u[1]<0&&(u[1]=0),u[0]=="money"&&(u[1]=2,h=w2utils.settings.currencySymbol),u[0]=="percent"&&(o="%",u[1]!=="0"&&(u[1]=1)),u[0]=="int"&&(u[1]=0),r="
      "+h+w2utils.formatNumber(Number(r).toFixed(u[1]))+o+"
      "),u[0]=="date"&&((typeof u[1]=="undefined"||u[1]=="")&&(u[1]=w2utils.settings.date_display),r="
      "+h+w2utils.formatDate(r,u[1])+o+"
      "),u[0]=="age"&&(r="
      "+h+w2utils.age(r)+o+"
      ")}}else this.show.recordTitles?(s=String(r).replace(/"/g,"''"),typeof f.title!="undefined"&&(typeof f.title=="function"&&(s=f.title.call(this,e,n,t)),typeof f.title=="string"&&(s=f.title)),r='
      '+r+"
      "):r="
      "+r+"
      ";return(r==null||typeof r=="undefined")&&(r=""),r},getFooterHTML:function(){return'
      \t\t\t
      '},status:function(n){var r,t,i;typeof n!="undefined"?$("#grid_"+this.name+"_footer").find(".w2ui-footer-left").html(n):(r="",t=this.getSelection(),t.length>0&&(r=String(t.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")+" "+w2utils.lang("selected"),i=t[0],typeof i=="object"&&(i=i.recid+", "+w2utils.lang("Column")+": "+i.column),t.length==1&&(r=w2utils.lang("Record ID")+": "+i+" ")),$("#grid_"+this.name+"_footer .w2ui-footer-left").html(r),t.length==1?this.toolbar.enable("edit"):this.toolbar.disable("edit"),t.length>=1?this.toolbar.enable("delete"):this.toolbar.disable("delete"))},lock:function(n,t){var i=$(this.box).find("> div:first-child");setTimeout(function(){w2utils.lock(i,n,t)},10)},unlock:function(){var n=this.box;setTimeout(function(){w2utils.unlock(n)},25)},parseField:function(n,t){var i="",r,u;try{i=n,r=String(t).split(".");for(u in r)i=i[r[u]]}catch(f){i=""}return i}},$.extend(w2grid.prototype,w2utils.event),w2obj.grid=w2grid}(jQuery),function(n){var t=function(t){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.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,n.extend(!0,this,w2obj.layout,t)};n.fn.w2layout=function(i){function s(t,i,r){var u=t.get(i);return(u!=null&&typeof r=="undefined"&&(r=u.tabs),u==null||r==null)?!1:(n.isArray(r)&&(r={tabs:r}),n().w2destroy(t.name+"_"+i+"_tabs"),u.tabs=n().w2tabs(n.extend({},r,{owner:t,name:t.name+"_"+i+"_tabs"})),u.show.tabs=!0,!0)}function o(t,i,r){var u=t.get(i);return(u!=null&&typeof r=="undefined"&&(r=u.toolbar),u==null||r==null)?!1:(n.isArray(r)&&(r={items:r}),n().w2destroy(t.name+"_"+i+"_toolbar"),u.toolbar=n().w2toolbar(n.extend({},r,{owner:t,name:t.name+"_"+i+"_toolbar"})),u.show.toolbar=!0,!0)}var f,r,u,e;if(typeof i!="object"&&i){if(w2ui[n(this).attr("name")])return e=w2ui[n(this).attr("name")],e[i].apply(e,Array.prototype.slice.call(arguments,1)),this;console.log("ERROR: Method "+i+" does not exist on jQuery.w2layout")}else{if(!i||typeof i.name=="undefined"){console.log('ERROR: The parameter "name" is required but not supplied in $().w2layout().');return}if(typeof w2ui[i.name]!="undefined"){console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+i.name+").");return}if(!w2utils.isAlphaNumeric(i.name)){console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). ');return}f=i.panels,r=new t(i),n.extend(r,{handlers:[],panels:[]});for(u in f)r.panels[u]=n.extend(!0,{},t.prototype.panel,f[u]),(n.isPlainObject(r.panels[u].tabs)||n.isArray(r.panels[u].tabs))&&s(r,f[u].type),(n.isPlainObject(r.panels[u].toolbar)||n.isArray(r.panels[u].toolbar))&&o(r,f[u].type);for(u in{top:"",left:"",main:"",preview:"",right:"",bottom:""})r.get(u)==null&&(r.panels[u]=n.extend(!0,{},t.prototype.panel,{type:u,hidden:!0,size:50}));return n(this).length>0&&r.render(n(this)[0]),w2ui[r.name]=r,r}},t.prototype={panel:{type:null,size:100,minSize:20,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(n,t,i){return this.content(n,t,i)},content:function(t,i,r){var s=this,u=this.get(t),o,h,c,e,f;return t=="css"?(n("#layout_"+s.name+"_panel_css").html(""),!0):u==null?!1:n("#layout_"+this.name+"_panel2_"+u.type).length>0?!1:(n("#layout_"+this.name+"_panel_"+u.type).scrollTop(0),i==null||typeof i=="undefined")?u.content:i instanceof jQuery?(console.log("ERROR: You can not pass jQuery object to w2layout.content() method"),!1):(o=n("#layout_"+this.name+"_panel_"+t+" > .w2ui-panel-content"),h=n(o).position().top,o.attr("class","w2ui-panel-content"),o.length>0&&typeof u.style!="undefined"&&(o[0].style.cssText=u.style),u.content==""?(u.content=i,u.hidden||this.refresh(t)):(u.content=i,u.hidden||(r!=null&&r!=""&&typeof r!="undefined"?(c="layout_"+this.name+"_panel_"+u.type,e=n("#"+c+" > .w2ui-panel-content"),e.after('
      '),f=n("#"+c+" > .w2ui-panel-content.new-panel"),e.css("top",h),f.css("top",h),typeof i=="object"?(i.box=f[0],i.render()):f.html(i),w2utils.transition(e[0],f[0],r,function(){e.remove(),f.removeClass("new-panel"),f.css("overflow",u.overflow),window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){s.resize()},100)})):u.hidden||this.refresh(t))),window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){s.resize()},100),!0)},load:function(t,i,r,u){var f=this;return t=="css"?(n.get(i,function(n,i,r){f.content(t,r.responseText),u&&u()}),!0):this.get(t)!=null?(n.get(i,function(n,i,e){f.content(t,e.responseText,r),u&&u(),window.navigator.userAgent.indexOf("MSIE")&&setTimeout(function(){f.resize()},100)}),!0):!1},sizeTo:function(t,i){var r=this,u=r.get(t);return u==null?!1:(n(r.box).find(" > div .w2ui-panel").css({"-webkit-transition":".35s","-moz-transition":".35s","-ms-transition":".35s","-o-transition":".35s"}),setTimeout(function(){r.set(t,{size:i})},1),setTimeout(function(){n(r.box).find(" > div .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),r.resize()},500),!0)},show:function(t,i){var r=this,f=this.trigger({phase:"before",type:"show",target:t,object:this.get(t),immediate:i}),u;return f.isCancelled===!0?!1:(u=r.get(t),u==null)?!1:(u.hidden=!1,i===!0?(n("#layout_"+r.name+"_panel_"+t).css({opacity:"1"}),u.resizabled&&n("#layout_"+r.name+"_resizer_"+t).show(),r.trigger(n.extend(f,{phase:"after"})),r.resize()):(u.resizabled&&n("#layout_"+r.name+"_resizer_"+t).show(),n("#layout_"+r.name+"_panel_"+t).css({opacity:"0"}),n(r.box).find(" > div .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),setTimeout(function(){r.resize()},1),setTimeout(function(){n("#layout_"+r.name+"_panel_"+t).css({opacity:"1"})},250),setTimeout(function(){n(r.box).find(" > div .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),r.trigger(n.extend(f,{phase:"after"})),r.resize()},500)),!0)},hide:function(t,i){var r=this,f=this.trigger({phase:"before",type:"hide",target:t,object:this.get(t),immediate:i}),u;return f.isCancelled===!0?!1:(u=r.get(t),u==null)?!1:(u.hidden=!0,i===!0?(n("#layout_"+r.name+"_panel_"+t).css({opacity:"0"}),n("#layout_"+r.name+"_resizer_"+t).hide(),r.trigger(n.extend(f,{phase:"after"})),r.resize()):(n("#layout_"+r.name+"_resizer_"+t).hide(),n(r.box).find(" > div .w2ui-panel").css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s"}),n("#layout_"+r.name+"_panel_"+t).css({opacity:"0"}),setTimeout(function(){r.resize()},1),setTimeout(function(){n(r.box).find(" > div .w2ui-panel").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s"}),r.trigger(n.extend(f,{phase:"after"})),r.resize()},500)),!0)},toggle:function(n,t){var i=this.get(n);return i==null?!1:i.hidden?this.show(n,t):this.hide(n,t)},set:function(t,i){var r=this.get(t,!0);return r==null?!1:(n.extend(this.panels[r],i),this.refresh(t),this.resize(),!0)},get:function(n,t){var r=null,i;for(i in this.panels)if(this.panels[i].type==n)return t===!0?i:this.panels[i];return null},el:function(t){var i=n("#layout_"+this.name+"_panel_"+t+" .w2ui-panel-content");return i.length!=1?null:i[0]},hideToolbar:function(t){var i=this.get(t);i&&(i.show.toolbar=!1,n("#layout_"+this.name+"_panel_"+t+" > .w2ui-panel-toolbar").hide(),this.resize())},showToolbar:function(t){var i=this.get(t);i&&(i.show.toolbar=!0,n("#layout_"+this.name+"_panel_"+t+" > .w2ui-panel-toolbar").show(),this.resize())},toggleToolbar:function(n){var t=this.get(n);t&&(t.show.toolbar?this.hideToolbar(n):this.showToolbar(n))},hideTabs:function(t){var i=this.get(t);i&&(i.show.tabs=!1,n("#layout_"+this.name+"_panel_"+t+" > .w2ui-panel-tabs").hide(),this.resize())},showTabs:function(t){var i=this.get(t);i&&(i.show.tabs=!0,n("#layout_"+this.name+"_panel_"+t+" > .w2ui-panel-tabs").show(),this.resize())},toggleTabs:function(n){var t=this.get(n);t&&(t.show.tabs?this.hideTabs(n):this.showTabs(n))},render:function(t){function a(){i.tmp.events={resize:function(){w2ui[i.name].resize()},resizeStart:c,mousemove:h,mouseup:s};n(window).on("resize",i.tmp.events.resize);n(document).on("mousemove",i.tmp.events.mousemove);n(document).on("mouseup",i.tmp.events.mouseup)}function c(t,r){i.box&&(r||(r=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),i.tmp.resize={type:t,x:r.screenX,y:r.screenY,div_x:0,div_y:0,value:0},(t=="left"||t=="right")&&(i.tmp.resize.value=parseInt(n("#layout_"+i.name+"_resizer_"+t)[0].style.left)),(t=="top"||t=="preview"||t=="bottom")&&(i.tmp.resize.value=parseInt(n("#layout_"+i.name+"_resizer_"+t)[0].style.top)))}function s(t){var u,f;if(i.box&&(t||(t=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),typeof i.tmp.resize!="undefined")){if(i.tmp.div_x!=0||i.tmp.resize.div_y!=0){var e=i.get("top"),o=i.get("bottom"),r=i.get(i.tmp.resize.type),h=parseInt(n(i.box).height()),c=parseInt(n(i.box).width()),s=String(r.size);switch(i.tmp.resize.type){case"top":u=parseInt(r.sizeCalculated)+i.tmp.resize.div_y,f=0;break;case"bottom":u=parseInt(r.sizeCalculated)-i.tmp.resize.div_y,f=0;break;case"preview":u=parseInt(r.sizeCalculated)-i.tmp.resize.div_y,f=(e&&!e.hidden?e.sizeCalculated:0)+(o&&!o.hidden?o.sizeCalculated:0);break;case"left":u=parseInt(r.sizeCalculated)+i.tmp.resize.div_x,f=0;break;case"right":u=parseInt(r.sizeCalculated)-i.tmp.resize.div_x,f=0}r.size=s.substr(s.length-1)=="%"?Math.floor(u*100/(r.type=="left"||r.type=="right"?c:h-f)*100)/100+"%":u,i.resize()}n("#layout_"+i.name+"_resizer_"+i.tmp.resize.type).removeClass("active"),delete i.tmp.resize}}function h(t){var f,u,r;if(i.box&&(t||(t=window.event),typeof i.tmp.resize!="undefined")){if(f=i.get(i.tmp.resize.type),u=i.trigger({phase:"before",type:"resizing",target:i.tmp.resize.type,object:f,originalEvent:t}),u.isCancelled===!0)return!1;r=n("#layout_"+i.name+"_resizer_"+i.tmp.resize.type),r.hasClass("active")||r.addClass("active"),i.tmp.resize.div_x=t.screenX-i.tmp.resize.x,i.tmp.resize.div_y=t.screenY-i.tmp.resize.y,i.tmp.resizing=="left"&&i.get("left").minSize-i.tmp.resize.div_x>i.get("left").width&&(i.tmp.resize.div_x=i.get("left").minSize-i.get("left").width),i.tmp.resize.type=="left"&&i.get("main").minSize+i.tmp.resize.div_x>i.get("main").width&&(i.tmp.resize.div_x=i.get("main").width-i.get("main").minSize),i.tmp.resize.type=="right"&&i.get("right").minSize+i.tmp.resize.div_x>i.get("right").width&&(i.tmp.resize.div_x=i.get("right").width-i.get("right").minSize),i.tmp.resize.type=="right"&&i.get("main").minSize-i.tmp.resize.div_x>i.get("main").width&&(i.tmp.resize.div_x=i.get("main").minSize-i.get("main").width),i.tmp.resize.type=="top"&&i.get("top").minSize-i.tmp.resize.div_y>i.get("top").height&&(i.tmp.resize.div_y=i.get("top").minSize-i.get("top").height),i.tmp.resize.type=="top"&&i.get("main").minSize+i.tmp.resize.div_y>i.get("main").height&&(i.tmp.resize.div_y=i.get("main").height-i.get("main").minSize),i.tmp.resize.type=="bottom"&&i.get("bottom").minSize+i.tmp.resize.div_y>i.get("bottom").height&&(i.tmp.resize.div_y=i.get("bottom").height-i.get("bottom").minSize),i.tmp.resize.type=="bottom"&&i.get("main").minSize-i.tmp.resize.div_y>i.get("main").height&&(i.tmp.resize.div_y=i.get("main").minSize-i.get("main").height),i.tmp.resize.type=="preview"&&i.get("preview").minSize+i.tmp.resize.div_y>i.get("preview").height&&(i.tmp.resize.div_y=i.get("preview").height-i.get("preview").minSize),i.tmp.resize.type=="preview"&&i.get("main").minSize-i.tmp.resize.div_y>i.get("main").height&&(i.tmp.resize.div_y=i.get("main").minSize-i.get("main").height);switch(i.tmp.resize.type){case"top":case"preview":case"bottom":i.tmp.resize.div_x=0,r.length>0&&(r[0].style.top=i.tmp.resize.value+i.tmp.resize.div_y+"px");break;case"left":case"right":i.tmp.resize.div_y=0,r.length>0&&(r[0].style.left=i.tmp.resize.value+i.tmp.resize.div_x+"px")}i.trigger(n.extend(u,{phase:"after"}))}}var i=this,o,f,r,u,l,e;if((window.getSelection&&window.getSelection().removeAllRanges(),o=+new Date,f=i.trigger({phase:"before",type:"render",target:i.name,box:t}),f.isCancelled===!0)||(typeof t!="undefined"&&t!=null&&(n(i.box).find("#layout_"+i.name+"_panel_main").length>0&&n(i.box).removeAttr("name").removeClass("w2ui-layout").html(""),i.box=t),!i.box))return!1;n(i.box).attr("name",i.name).addClass("w2ui-layout").html("
      "),n(i.box).length>0&&(n(i.box)[0].style.cssText+=i.style),r=["top","left","main","preview","right","bottom"];for(u in r)l=i.get(r[u]),e='
      \t
      \t
      \t
      ',n(i.box).find(" > div").append(e);return n(i.box).find(" > div").append('
      0&&(f.css("overflow",i.overflow)[0].style.cssText+=";"+i.style),i.resizable===!0?n("#layout_"+this.name+"_resizer_"+t).show():n("#layout_"+this.name+"_resizer_"+t).hide(),typeof i.content=="object"&&i.content.render?(i.content.box=n("#layout_"+r.name+"_panel_"+i.type+" > .w2ui-panel-content")[0],i.content.render()):n("#layout_"+r.name+"_panel_"+i.type+" > .w2ui-panel-content").html(i.content),u=n(r.box).find("#layout_"+r.name+"_panel_"+i.type+" .w2ui-panel-tabs"),i.show.tabs?u.find("[name="+i.tabs.name+"]").length==0&&i.tabs!=null?u.w2render(i.tabs):i.tabs.refresh():u.html("").removeClass("w2ui-tabs").hide(),u=n(r.box).find("#layout_"+r.name+"_panel_"+i.type+" .w2ui-panel-toolbar"),i.show.toolbar?u.find("[name="+i.toolbar.name+"]").length==0&&i.toolbar!=null?u.w2render(i.toolbar):i.toolbar.refresh():u.html("").removeClass("w2ui-toolbar").hide()}else{if(n("#layout_"+r.name+"_panel_main").length<=0){r.render();return}r.resize();for(i in this.panels)r.refresh(this.panels[i].type)}return r.trigger(n.extend(e,{phase:"after"})),+new Date-o}},resize:function(){var ut,nt,y,h,u,tt,b,a,p;if((window.getSelection&&window.getSelection().removeAllRanges(),!this.box)||(ut=+new Date,nt=this.trigger({phase:"before",type:"resize",target:this.name,panel:this.tmp.resizing}),nt.isCancelled===!0))return!1;this.padding<0&&(this.padding=0),y=parseInt(n(this.box).width()),h=parseInt(n(this.box).height()),n(this.box).find(" > div").css({width:y+"px",height:h+"px"});var p=this,it=this.get("main"),l=this.get("preview"),s=this.get("left"),c=this.get("right"),r=this.get("top"),f=this.get("bottom"),et=!0,ft=l!=null&&l.hidden!=!0?!0:!1,d=s!=null&&s.hidden!=!0?!0:!1,rt=c!=null&&c.hidden!=!0?!0:!1,w=r!=null&&r.hidden!=!0?!0:!1,g=f!=null&&f.hidden!=!0?!0:!1;for(a in{top:"",left:"",right:"",bottom:"",preview:""})u=this.get(a),tt=String(u.size),u&&tt.substr(tt.length-1)=="%"?(b=h,u.type=="preview"&&(b=b-(r&&!r.hidden?r.sizeCalculated:0)-(f&&!f.hidden?f.sizeCalculated:0)),u.sizeCalculated=parseInt((u.type=="left"||u.type=="right"?y:b)*parseFloat(u.size)/100)):u.sizeCalculated=parseInt(u.size),u.sizeCalculatedthis.padding?this.resizer:this.padding,n("#layout_"+this.name+"_resizer_top").show().css({display:"block",left:o+"px",top:e+"px",width:t+"px",height:i+"px",cursor:"ns-resize"}).bind("mousedown",function(n){return w2ui[p.name].tmp.events.resizeStart("top",n),!1}))}else n("#layout_"+this.name+"_panel_top").hide();if(s!=null&&s.hidden!=!0){var o=0,e=0+(w?r.sizeCalculated+this.padding:0),t=s.sizeCalculated,i=h-(w?r.sizeCalculated+this.padding:0)-(g?f.sizeCalculated+this.padding:0),v=n("#layout_"+this.name+"_panel_left");window.navigator.userAgent.indexOf("MSIE")>0&&v.length>0&&v[0].clientHeightthis.padding?this.resizer:this.padding,n("#layout_"+this.name+"_resizer_left").show().css({display:"block",left:o+"px",top:e+"px",width:t+"px",height:i+"px",cursor:"ew-resize"}).bind("mousedown",function(n){return w2ui[p.name].tmp.events.resizeStart("left",n),!1}))}else n("#layout_"+this.name+"_panel_left").hide(),n("#layout_"+this.name+"_resizer_left").hide();if(c!=null&&c.hidden!=!0){var o=y-c.sizeCalculated,e=0+(w?r.sizeCalculated+this.padding:0),t=c.sizeCalculated,i=h-(w?r.sizeCalculated+this.padding:0)-(g?f.sizeCalculated+this.padding:0);n("#layout_"+this.name+"_panel_right").css({display:"block",left:o+"px",top:e+"px",width:t+"px",height:i+"px"}).show(),c.width=t,c.height=i,c.resizable&&(o=o-this.padding,t=this.resizer>this.padding?this.resizer:this.padding,n("#layout_"+this.name+"_resizer_right").show().css({display:"block",left:o+"px",top:e+"px",width:t+"px",height:i+"px",cursor:"ew-resize"}).bind("mousedown",function(n){return w2ui[p.name].tmp.events.resizeStart("right",n),!1}))}else n("#layout_"+this.name+"_panel_right").hide();if(f!=null&&f.hidden!=!0){var o=0,e=h-f.sizeCalculated,t=y,i=f.sizeCalculated;n("#layout_"+this.name+"_panel_bottom").css({display:"block",left:o+"px",top:e+"px",width:t+"px",height:i+"px"}).show(),f.width=t,f.height=i,f.resizable&&(e=e-(this.padding==0?0:this.padding),i=this.resizer>this.padding?this.resizer:this.padding,n("#layout_"+this.name+"_resizer_bottom").show().css({display:"block",left:o+"px",top:e+"px",width:t+"px",height:i+"px",cursor:"ns-resize"}).bind("mousedown",function(n){return w2ui[p.name].tmp.events.resizeStart("bottom",n),!1}))}else n("#layout_"+this.name+"_panel_bottom").hide();var o=0+(d?s.sizeCalculated+this.padding:0),e=0+(w?r.sizeCalculated+this.padding:0),t=y-(d?s.sizeCalculated+this.padding:0)-(rt?c.sizeCalculated+this.padding:0),i=h-(w?r.sizeCalculated+this.padding:0)-(g?f.sizeCalculated+this.padding:0)-(ft?l.sizeCalculated+this.padding:0),v=n("#layout_"+this.name+"_panel_main");if(window.navigator.userAgent.indexOf("MSIE")>0&&v.length>0&&v[0].clientHeight0&&v.length>0&&v[0].clientHeightthis.padding?this.resizer:this.padding,n("#layout_"+this.name+"_resizer_preview").show().css({display:"block",left:o+"px",top:e+"px",width:t+"px",height:i+"px",cursor:"ns-resize"}).bind("mousedown",function(n){return w2ui[p.name].tmp.events.resizeStart("preview",n),!1}))}else n("#layout_"+this.name+"_panel_preview").hide();for(a in{top:"",left:"",main:"",preview:"",right:"",bottom:""}){var k=this.get(a),u="#layout_"+this.name+"_panel_"+a+" > .w2ui-panel-",h=0;k.show.tabs&&(k.tabs!=null&&w2ui[this.name+"_"+a+"_tabs"]&&w2ui[this.name+"_"+a+"_tabs"].resize(),h+=w2utils.getSize(n(u+"tabs").css({display:"block"}),"height")),k.show.toolbar&&(k.toolbar!=null&&w2ui[this.name+"_"+a+"_toolbar"]&&w2ui[this.name+"_"+a+"_toolbar"].resize(),h+=w2utils.getSize(n(u+"toolbar").css({top:h+"px",display:"block"}),"height")),n(u+"content").css({display:"block"}).css({top:h+"px"})}return p=this,clearTimeout(this._resize_timer),this._resize_timer=setTimeout(function(){var t,i;for(t in w2ui)typeof w2ui[t].resize=="function"&&(w2ui[t].panels=="undefined"&&w2ui[t].resize(),i=n(w2ui[t].box).parents(".w2ui-layout"),i.length>0&&i.attr("name")==p.name&&w2ui[t].resize())},100),this.trigger(n.extend(nt,{phase:"after"})),+new Date-ut},destroy:function(){var t=this.trigger({phase:"before",type:"destroy",target:this.name});return t.isCancelled===!0?!1:typeof w2ui[this.name]=="undefined"?!1:(n(this.box).find("#layout_"+this.name+"_panel_main").length>0&&n(this.box).removeAttr("name").removeClass("w2ui-layout").html(""),delete w2ui[this.name],this.trigger(n.extend(t,{phase:"after"})),this.tmp.events&&this.tmp.events.resize&&n(window).off("resize",this.tmp.events.resize),this.tmp.events&&this.tmp.events.mousemove&&n(document).off("mousemove",this.tmp.events.mousemove),this.tmp.events&&this.tmp.events.mouseup&&n(document).off("mouseup",this.tmp.events.mouseup),!0)},lock:function(t,i,r){if(n.inArray(String(t),["left","right","top","bottom","preview","main"])==-1){console.log("ERROR: First parameter needs to be the a valid panel name.");return}var u="#layout_"+this.name+"_panel_"+t;w2utils.lock(u,i,r)},unlock:function(t){if(n.inArray(String(t),["left","right","top","bottom","preview","main"])==-1){console.log("ERROR: First parameter needs to be the a valid panel name.");return}var i="#layout_"+this.name+"_panel_"+t;w2utils.unlock(i)}},n.extend(t.prototype,w2utils.event),w2obj.layout=t}(jQuery),w2popup={},function(n){n.fn.w2popup=function(t,i){typeof t=="undefined"&&(i={},t="open"),n.isPlainObject(t)&&(i=t,t="open"),t=t.toLowerCase(),t=="load"&&typeof i=="string"&&(i={url:i}),t=="open"&&typeof i.url!="undefined"&&(t="load"),typeof i=="undefined"&&(i={});var r={};return n(this).length>0&&(n(this).find("div[rel=title], div[rel=body], div[rel=buttons]").length>0?(n(this).find("div[rel=title]").length>0&&(r.title=n(this).find("div[rel=title]").html()),n(this).find("div[rel=body]").length>0&&(r.body=n(this).find("div[rel=body]").html(),r.style=n(this).find("div[rel=body]")[0].style.cssText),n(this).find("div[rel=buttons]").length>0&&(r.buttons=n(this).find("div[rel=buttons]").html())):(r.title=" ",r.body=n(this).html()),parseInt(n(this).css("width"))!=0&&(r.width=parseInt(n(this).css("width"))),parseInt(n(this).css("height"))!=0&&(r.height=parseInt(n(this).css("height")))),w2popup[t](n.extend({},r,i))},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},handlers:[],onOpen:null,onClose:null,onMax:null,onMin:null,onKeydown:null,open:function(t){function w(n){if(n||(n=window.event),window.addEventListener||window.document.attachEvent("onselectstart",function(){return!1}),i.resizing=!0,i.tmp_x=n.screenX,i.tmp_y=n.screenY,n.stopPropagation?n.stopPropagation():n.cancelBubble=!0,n.preventDefault)n.preventDefault();else return!1}function c(t){i.resizing==!0&&(t||(t=window.event),i.tmp_div_x=t.screenX-i.tmp_x,i.tmp_div_y=t.screenY-i.tmp_y,n("#w2ui-popup").css({"-webkit-transition":"none","-webkit-transform":"translate3d("+i.tmp_div_x+"px, "+i.tmp_div_y+"px, 0px)","-moz-transition":"none","-moz-transform":"translate("+i.tmp_div_x+"px, "+i.tmp_div_y+"px)","-ms-transition":"none","-ms-transform":"translate("+i.tmp_div_x+"px, "+i.tmp_div_y+"px)","-o-transition":"none","-o-transform":"translate("+i.tmp_div_x+"px, "+i.tmp_div_y+"px)"}),n("#w2ui-panel").css({"-webkit-transition":"none","-webkit-transform":"translate3d("+i.tmp_div_x+"px, "+i.tmp_div_y+"px, 0px)","-moz-transition":"none","-moz-transform":"translate("+i.tmp_div_x+"px, "+i.tmp_div_y+"px)","-ms-transition":"none","-ms-transform":"translate("+i.tmp_div_x+"px, "+i.tmp_div_y+"px","-o-transition":"none","-o-transform":"translate("+i.tmp_div_x+"px, "+i.tmp_div_y+"px)"}))}function h(t){i.resizing==!0&&(t||(t=window.event),i.tmp_div_x=t.screenX-i.tmp_x,i.tmp_div_y=t.screenY-i.tmp_y,n("#w2ui-popup").css({"-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)",left:parseInt(n("#w2ui-popup").css("left"))+parseInt(i.tmp_div_x)+"px",top:parseInt(n("#w2ui-popup").css("top"))+parseInt(i.tmp_div_y)+"px"}),n("#w2ui-panel").css({"-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)",left:parseInt(n("#w2ui-panel").css("left"))+parseInt(i.tmp_div_x)+"px",top:parseInt(n("#w2ui-panel").css("top"))+parseInt(i.tmp_div_y)+"px"}),i.resizing=!1)}var p=this,o=n("#w2ui-popup").data("options"),t=n.extend({},this.defaults,{body:""},o,t),e,f,v,y,r,u,a,l,s,i;if(n("#w2ui-popup").length==0&&(w2popup.handlers=[],w2popup.onMax=null,w2popup.onMin=null,w2popup.onOpen=null,w2popup.onClose=null,w2popup.onKeydown=null),t.onOpen&&(w2popup.onOpen=t.onOpen),t.onClose&&(w2popup.onClose=t.onClose),t.onMax&&(w2popup.onMax=t.onMax),t.onMin&&(w2popup.onMin=t.onMin),t.onKeydown&&(w2popup.onKeydown=t.onKeydown),window.innerHeight==undefined?(e=document.documentElement.offsetWidth,f=document.documentElement.offsetHeight,w2utils.engine=="IE7"&&(e+=21,f+=4)):(e=window.innerWidth,f=window.innerHeight),parseInt(e)-10',t.title!=""&&(r+='
      '+(t.showClose?'
      Close
      ':"")+(t.showMax?'
      Max
      ':"")+t.title+"
      "),r+='
      ',r+='
      '+t.body+"
      ",r+="
      ",r+='
      ',r+='
      ',r+="
      ",t.buttons!=""&&(r+='
      '+t.buttons+"
      "),r+="
      ",n("body").append(r),setTimeout(function(){n("#w2ui-popup .w2ui-box2").hide(),n("#w2ui-popup").css({"-webkit-transition":t.speed+"s opacity, "+t.speed+"s -webkit-transform","-webkit-transform":"scale(1)","-moz-transition":t.speed+"s opacity, "+t.speed+"s -moz-transform","-moz-transform":"scale(1)","-ms-transition":t.speed+"s opacity, "+t.speed+"s -ms-transform","-ms-transform":"scale(1)","-o-transition":t.speed+"s opacity, "+t.speed+"s -o-transform","-o-transform":"scale(1)",opacity:"1"})},1),setTimeout(function(){n("#w2ui-popup").css({"-webkit-transform":"","-moz-transform":"","-ms-transform":"","-o-transform":""}),p.trigger(n.extend(u,{phase:"after"}))},t.speed*1e3)}else{if(u=this.trigger({phase:"before",type:"open",target:"popup",options:t,present:!0}),u.isCancelled===!0)return;(typeof o=="undefined"||o.width!=t.width||o.height!=t.height)&&(n("#w2ui-panel").remove(),w2popup.resize(t.width,t.height)),a=n("#w2ui-popup .w2ui-box2 > .w2ui-msg-body").html(t.body),a.length>0&&(a[0].style.cssText=t.style),n("#w2ui-popup .w2ui-msg-buttons").html(t.buttons),n("#w2ui-popup .w2ui-msg-title").html((t.showClose?'
      Close
      ':"")+(t.showMax?'
      Max
      ':"")+t.title),l=n("#w2ui-popup .w2ui-box1")[0],s=n("#w2ui-popup .w2ui-box2")[0],w2utils.transition(l,s,t.transition),s.className="w2ui-box1",l.className="w2ui-box2",n(s).addClass("w2ui-current-box"),n("#w2ui-popup").data("prev-size",null),setTimeout(function(){p.trigger(n.extend(u,{phase:"after"}))},1)}if(t._last_w2ui_name=w2utils.keyboard.active(),w2utils.keyboard.active(null),n("#w2ui-popup").data("options",t),t.keyboard)n(document).on("keydown",this.keydown);i={resizing:!1};n("#w2ui-popup .w2ui-msg-title").on("mousedown",function(n){w(n)}).on("mousemove",function(n){c(n)}).on("mouseup",function(n){h(n)});n("#w2ui-popup .w2ui-msg-body").on("mousemove",function(n){c(n)}).on("mouseup",function(n){h(n)});n("#w2ui-lock").on("mousemove",function(n){c(n)}).on("mouseup",function(n){h(n)});return this},keydown:function(t){var r=n("#w2ui-popup").data("options"),i;if(r.keyboard&&(i=w2popup.trigger({phase:"before",type:"keydown",target:"popup",options:r,object:w2popup,originalEvent:t}),i.isCancelled!==!0)){switch(t.keyCode){case 27:t.preventDefault(),n("#w2ui-popup .w2ui-popup-message").length>0?w2popup.message():w2popup.close()}w2popup.trigger(n.extend(i,{phase:"after"}))}},close:function(t){var r=this,t=n.extend({},n("#w2ui-popup").data("options"),t),i=this.trigger({phase:"before",type:"close",target:"popup",options:t});i.isCancelled!==!0&&(n("#w2ui-popup, #w2ui-panel").css({"-webkit-transition":t.speed+"s opacity, "+t.speed+"s -webkit-transform","-webkit-transform":"scale(0.9)","-moz-transition":t.speed+"s opacity, "+t.speed+"s -moz-transform","-moz-transform":"scale(0.9)","-ms-transition":t.speed+"s opacity, "+t.speed+"s -ms-transform","-ms-transform":"scale(0.9)","-o-transition":t.speed+"s opacity, "+t.speed+"s -o-transform","-o-transform":"scale(0.9)",opacity:"0"}),w2popup.unlockScreen(),setTimeout(function(){n("#w2ui-popup").remove(),n("#w2ui-panel").remove(),r.trigger(n.extend(i,{phase:"after"}))},t.speed*1e3),w2utils.keyboard.active(t._last_w2ui_name),t.keyboard&&n(document).off("keydown",this.keydown))},toggle:function(){var t=n("#w2ui-popup").data("options");t.maximized===!0?w2popup.min():w2popup.max()},max:function(){var r=this,t=n("#w2ui-popup").data("options"),i;t.maximized!==!0&&(i=this.trigger({phase:"before",type:"max",target:"popup",options:t}),i.isCancelled!==!0)&&(t.maximized=!0,t.prevSize=n("#w2ui-popup").css("width")+":"+n("#w2ui-popup").css("height"),n("#w2ui-popup").data("options",t),w2popup.resize(1e4,1e4,function(){r.trigger(n.extend(i,{phase:"after"}))}))},min:function(){var u=this,t=n("#w2ui-popup").data("options"),i,r;t.maximized===!0&&(i=t.prevSize.split(":"),r=this.trigger({phase:"before",type:"min",target:"popup",options:t}),r.isCancelled!==!0)&&(t.maximized=!1,t.prevSize=null,n("#w2ui-popup").data("options",t),w2popup.resize(i[0],i[1],function(){u.trigger(n.extend(r,{phase:"after"}))}))},get:function(){return n("#w2ui-popup").data("options")},set:function(n){w2popup.open(n)},clear:function(){n("#w2ui-popup .w2ui-msg-title").html(""),n("#w2ui-popup .w2ui-msg-body").html(""),n("#w2ui-popup .w2ui-msg-buttons").html("")},reset:function(){w2popup.open(w2popup.defaults)},load:function(t){function u(i,r){if(delete t.url,n("body").append('"),typeof r!="undefined"&&n("#w2ui-tmp #"+r).length>0?n("#w2ui-tmp #"+r).w2popup(t):n("#w2ui-tmp > div").w2popup(t),n("#w2ui-tmp > style").length>0){var u=n("
      ").append(n("#w2ui-tmp > style").clone()).html();n("#w2ui-popup #div-style").length==0&&n("#w2ui-ppopup").append('
      '),n("#w2ui-popup #div-style").html(u)}n("#w2ui-tmp").remove()}var i;if(String(t.url)=="undefined"){console.log("ERROR: The url parameter is empty.");return}var f=String(t.url).split("#"),r=f[0],e=f[1];String(t)=="undefined"&&(t={}),i=n("#w2ui-popup").data(r),typeof i!="undefined"&&i!=null?u(i,e):n.get(r,function(t,i,f){u(f.responseText,e),n("#w2ui-popup").data(r,f.responseText)})},message:function(t){var r,u,i,t;n().w2tag(),t||(t={width:200,height:100}),parseInt(t.width)<10&&(t.width=10),parseInt(t.height)<10&&(t.height=10),typeof t.hideOnClick=="undefined"&&(t.hideOnClick=!1),r=n("#w2ui-popup .w2ui-msg-title"),n("#w2ui-popup .w2ui-popup-message").length==0?(u=parseInt(n("#w2ui-popup").width()),n("#w2ui-popup .w2ui-box1").before('"),n("#w2ui-popup .w2ui-popup-message").data("options",t)):(typeof t.width=="undefined"&&(t.width=w2utils.getSize(n("#w2ui-popup .w2ui-popup-message"),"width")),typeof t.height=="undefined"&&(t.height=w2utils.getSize(n("#w2ui-popup .w2ui-popup-message"),"height"))),i=n("#w2ui-popup .w2ui-popup-message").css("display"),n("#w2ui-popup .w2ui-popup-message").css({"-webkit-transform":i=="none"?"translateY(-"+t.height+"px)":"translateY(0px)","-moz-transform":i=="none"?"translateY(-"+t.height+"px)":"translateY(0px)","-ms-transform":i=="none"?"translateY(-"+t.height+"px)":"translateY(0px)","-o-transform":i=="none"?"translateY(-"+t.height+"px)":"translateY(0px)"}),i=="none"?(n("#w2ui-popup .w2ui-popup-message").show().html(t.html),setTimeout(function(){n("#w2ui-popup .w2ui-popup-message").css({"-webkit-transition":"0s","-moz-transition":"0s","-ms-transition":"0s","-o-transition":"0s","z-Index":1500}),w2popup.lock(),typeof t.onOpen=="function"&&t.onOpen()},300)):(n("#w2ui-popup .w2ui-popup-message").css("z-Index",250),t=n("#w2ui-popup .w2ui-popup-message").data("options"),n("#w2ui-popup .w2ui-popup-message").remove(),w2popup.unlock(),typeof t.onClose=="function"&&t.onClose()),setTimeout(function(){n("#w2ui-popup .w2ui-popup-message").css({"-webkit-transform":i=="none"?"translateY(0px)":"translateY(-"+t.height+"px)","-moz-transform":i=="none"?"translateY(0px)":"translateY(-"+t.height+"px)","-ms-transform":i=="none"?"translateY(0px)":"translateY(-"+t.height+"px)","-o-transform":i=="none"?"translateY(0px)":"translateY(-"+t.height+"px)"})},1)},lock:function(t,i){w2utils.lock(n("#w2ui-popup"),t,i)},unlock:function(){w2utils.unlock(n("#w2ui-popup"))},lockScreen:function(t){if(n("#w2ui-lock").length>0)return!1;if(typeof t=="undefined"&&(t=n("#w2ui-popup").data("options")),typeof t=="undefined"&&(t={}),t=n.extend({},w2popup.defaults,t),n("body").append('
      '),setTimeout(function(){n("#w2ui-lock").css({"-webkit-transition":t.speed+"s opacity","-moz-transition":t.speed+"s opacity","-ms-transition":t.speed+"s opacity","-o-transition":t.speed+"s opacity",opacity:t.opacity})},1),t.modal==!0){n("#w2ui-lock").on("mousedown",function(){n("#w2ui-lock").css({"-webkit-transition":".1s","-moz-transition":".1s","-ms-transition":".1s","-o-transition":".1s",opacity:"0.6"}),window.getSelection&&window.getSelection().removeAllRanges()});n("#w2ui-lock").on("mouseup",function(){setTimeout(function(){n("#w2ui-lock").css({"-webkit-transition":".1s","-moz-transition":".1s","-ms-transition":".1s","-o-transition":".1s",opacity:t.opacity})},100),window.getSelection&&window.getSelection().removeAllRanges()})}else n("#w2ui-lock").on("mouseup",function(){w2popup.close()});return!0},unlockScreen:function(){if(n("#w2ui-lock").length==0)return!1;var t=n.extend({},n("#w2ui-popup").data("options"),t);return n("#w2ui-lock").css({"-webkit-transition":t.speed+"s opacity","-moz-transition":t.speed+"s opacity","-ms-transition":t.speed+"s opacity","-o-transition":t.speed+"s opacity",opacity:0}),setTimeout(function(){n("#w2ui-lock").remove()},t.speed*1e3),!0},resize:function(t,i,r){var u=n("#w2ui-popup").data("options"),e,f;parseInt(n(window).width())-100?w2popup.message({width:400,height:150,html:'
      \t\t
      '+n+'
      \t\t
      ',onClose:function(){typeof i=="function"&&i()}}):w2popup.open({width:450,height:200,showMax:!1,title:t,body:'
      '+n+"
      ",buttons:'',onClose:function(){typeof i=="function"&&i()}})},w2confirm=function(n,t,i){(typeof i=="undefined"||typeof t=="function")&&(i=t,t=w2utils.lang("Confirmation")),typeof t=="undefined"&&(t=w2utils.lang("Confirmation")),jQuery("#w2ui-popup").length>0?w2popup.message({width:400,height:150,html:'
      \t\t
      '+n+'
      \t\t\t\t
      ',onOpen:function(){jQuery("#w2ui-popup .w2ui-popup-message .w2ui-popup-button").on("click",function(n){w2popup.message(),typeof i=="function"&&i(n.target.id)})},onKeydown:function(n){switch(n.originalEvent.keyCode){case 13:typeof i=="function"&&i("Yes"),w2popup.message();break;case 27:typeof i=="function"&&i("No"),w2popup.message()}}}):w2popup.open({width:450,height:200,title:t,modal:!0,showClose:!1,body:'
      '+n+"
      ",buttons:'',onOpen:function(n){n.onComplete=function(){jQuery("#w2ui-popup .w2ui-popup-button").on("click",function(n){w2popup.close(),typeof i=="function"&&i(n.target.id)})}},onKeydown:function(n){switch(n.originalEvent.keyCode){case 13:typeof i=="function"&&i("Yes"),w2popup.close();break;case 27:typeof i=="function"&&i("No"),w2popup.close()}}})},function(n){var t=function(t){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,n.extend(!0,this,w2obj.tabs,t)};n.fn.w2tabs=function(i){var e,r,f,u;if(typeof i!="object"&&i){if(w2ui[n(this).attr("name")])return u=w2ui[n(this).attr("name")],u[i].apply(u,Array.prototype.slice.call(arguments,1)),this;console.log("ERROR: Method "+i+" does not exist on jQuery.w2tabs")}else{if(!i||typeof i.name=="undefined"){console.log('ERROR: The parameter "name" is required but not supplied in $().w2tabs().');return}if(typeof w2ui[i.name]!="undefined"){console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+i.name+").");return}if(!w2utils.isAlphaNumeric(i.name)){console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). ');return}e=i.tabs,r=new t(i),n.extend(r,{tabs:[],handlers:[]});for(f in e)r.tabs[f]=n.extend({},t.prototype.tab,e[f]);return n(this).length!=0&&r.render(n(this)[0]),w2ui[r.name]=r,r}},t.prototype={tab:{id:null,text:"",hidden:!1,disabled:!1,closable:!1,hint:"",onClick:null,onRefresh:null,onClose:null},add:function(n){return this.insert(null,n)},insert:function(t,i){var r,f,e,i,u;n.isArray(i)||(i=[i]);for(r in i){if(String(i[r].id)=="undefined"){console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+this.name+")");return}f=!0;for(e in this.tabs)if(this.tabs[e].id==i[r].id){f=!1;break}if(!f){console.log('ERROR: The parameter "id='+i[r].id+'" is not unique within the current tabs. (obj: '+this.name+")");return}if(!w2utils.isAlphaNumeric(i[r].id)){console.log('ERROR: The parameter "id='+i[r].id+'" must be alpha-numeric + "-_". (obj: '+this.name+")");return}i=n.extend({},i,i[r]),t==null||typeof t=="undefined"?this.tabs.push(i):(u=this.get(t,!0),this.tabs=this.tabs.slice(0,u).concat([i],this.tabs.slice(u))),this.refresh(i[r].id)}},remove:function(){for(var u=0,r,i=0;i
      ":"")+'\t
      "+i.text+"
      ",r.length==0?(u="",i.hidden&&(u+="display: none;"),i.disabled&&(u+="opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);"),html='
      ",this.get(t,!0)!=this.tabs.length-1&&n(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(t,!0))+1].id)).length>0?n(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(t,!0))+1].id)).before(html):n(this.box).find("#tabs_"+this.name+"_right").before(html)):(r.html(f),i.hidden?r.css("display","none"):r.css("display",""),i.disabled?r.css({opacity:"0.2","-moz-opacity":"0.2","-webkit-opacity":"0.2","-o-opacity":"0.2",filter:"alpha(opacity=20)"}):r.css({opacity:"1","-moz-opacity":"1","-webkit-opacity":"1","-o-opacity":"1",filter:"alpha(opacity=100)"})),this.trigger(n.extend(e,{phase:"after"})),+new Date-s)},render:function(t){var u=+new Date,i=this.trigger({phase:"before",type:"render",target:this.name,box:t}),r;return i.isCancelled===!0?!1:(window.getSelection&&window.getSelection().removeAllRanges(),String(t)!="undefined"&&t!=null&&(n(this.box).find("> table #tabs_"+this.name+"_right").length>0&&n(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),this.box=t),!this.box)?void 0:(r='
      '+(i!==!0?"
      "+t+"
      ":"")+"
      '+(i!==!0?'\t
      \t\t\t
      ":"")+"
      '+(i!==!0?'\t
      \t\t"+e+"
      ":"")+"
      "+p+"
      '+f+"
      \t
      '+this.right+"
      ",n(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-tabs").html(r),n(this.box).length>0&&(n(this.box)[0].style.cssText+=this.style),this.trigger(n.extend(i,{phase:"after"})),this.refresh(),+new Date-u)},resize:function(){window.getSelection&&window.getSelection().removeAllRanges();var t=this.trigger({phase:"before",type:"resize",target:this.name});if(t.isCancelled===!0)return!1;this.trigger(n.extend(t,{phase:"after"}))},destroy:function(){var t=this.trigger({phase:"before",type:"destroy",target:this.name});if(t.isCancelled===!0)return!1;n(this.box).find("> table #tabs_"+this.name+"_right").length>0&&n(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-tabs").html(""),delete w2ui[this.name],this.trigger(n.extend(t,{phase:"after"}))},click:function(t,i){var u=this.get(t),r;if(u==null||u.disabled||(r=this.trigger({phase:"before",type:"click",target:t,object:this.get(t),originalEvent:i}),r.isCancelled===!0))return!1;n(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.active)+" .w2ui-tab").removeClass("active"),this.active=u.id,this.trigger(n.extend(r,{phase:"after"})),this.refresh(t)},animateClose:function(t,i){var u=this.get(t),f,r;if(u==null||u.disabled||(f=this.trigger({phase:"before",type:"close",target:t,object:this.get(t),originalEvent:i}),f.isCancelled===!0))return!1;r=this,n(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(u.id)).css({"-webkit-transition":".2s","-moz-transition":"2s","-ms-transition":".2s","-o-transition":".2s",opacity:"0"}),setTimeout(function(){var t=n(r.box).find("#tabs_"+r.name+"_tab_"+w2utils.escapeId(u.id)).width();n(r.box).find("#tabs_"+r.name+"_tab_"+w2utils.escapeId(u.id)).html('
      '),setTimeout(function(){n(r.box).find("#tabs_"+r.name+"_tab_"+w2utils.escapeId(u.id)).find(":first-child").css({width:"0px"})},50)},200),setTimeout(function(){r.remove(t)},450),this.trigger(n.extend(f,{phase:"after"})),this.refresh()},animateInsert:function(t,i){var f,e,o,s,r,u;if(this.get(t)!=null&&n.isPlainObject(i)){f=!0;for(e in this.tabs)if(this.tabs[e].id==i.id){f=!1;break}if(!f){console.log('ERROR: The parameter "id='+i.id+'" is not unique within the current tabs. (obj: '+this.name+")");return}(o=n(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(i.id)),o.length==0)&&(typeof i.caption!="undefined"&&(i.text=i.caption),s='
      '+(i.closable?'
      ':"")+'\t
      '+i.text+"
      ",n("body").append(s),tabHTML='
       
      ',r="",i.hidden&&(r+="display: none;"),i.disabled&&(r+="opacity: 0.2; -moz-opacity: 0.2; -webkit-opacity: 0.2; -o-opacity: 0.2; filter:alpha(opacity=20);"),html=''+tabHTML+"",this.get(t,!0)!=this.tabs.length&&n(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(t,!0))].id)).length>0?n(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(this.tabs[parseInt(this.get(t,!0))].id)).before(html):n(this.box).find("#tabs_"+this.name+"_right").before(html),u=this,setTimeout(function(){var t=n("#_tmp_simple_tab").width();n("#_tmp_tabs").remove(),n("#tabs_"+u.name+"_tab_"+w2utils.escapeId(i.id)+" > div").css("width",t+"px")},1),setTimeout(function(){u.insert(t,i)},200))}}},n.extend(t.prototype,w2utils.event),w2obj.tabs=t}(jQuery),function(n){var t=function(t){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,n.extend(!0,this,w2obj.toolbar,t)};n.fn.w2toolbar=function(i){var e,r,f,u;if(typeof i!="object"&&i){if(w2ui[n(this).attr("name")])return u=w2ui[n(this).attr("name")],u[i].apply(u,Array.prototype.slice.call(arguments,1)),this;console.log("ERROR: Method "+i+" does not exist on jQuery.w2toolbar")}else{if(!i||typeof i.name=="undefined"){console.log('ERROR: The parameter "name" is required but not supplied in $().w2toolbar().');return}if(typeof w2ui[i.name]!="undefined"){console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+i.name+").");return}if(!w2utils.isAlphaNumeric(i.name)){console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). ');return}e=i.items,r=new t(i),n.extend(r,{items:[],handlers:[]});for(f in e)r.items[f]=n.extend({},t.prototype.item,e[f]);return n(this).length!=0&&r.render(n(this)[0]),w2ui[r.name]=r,r}},t.prototype={item:{id:null,type:"button",text:"",html:"",img:null,icon:null,hidden:!1,disabled:!1,checked:!1,arrow:!0,hint:"",group:null,items:null,onClick:null},add:function(n){this.insert(null,n)},insert:function(i,r){var u,s,e,f,o;n.isArray(r)||(r=[r]);for(u in r){if(typeof r[u].type=="undefined"){console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.');return}if(n.inArray(String(r[u].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 r[u].id=="undefined"){console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.');return}for(s=!0,e=0;e table #tb_"+this.name+"_right").length>0&&n(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),this.box=t),this.box){for(r='',u=0;u':'");r+='",r+="
      '+this.getItemHTML(i)+"'+this.right+"
      ",n(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-toolbar").html(r),n(this.box).length>0&&(n(this.box)[0].style.cssText+=this.style),this.trigger(n.extend(f,{phase:"after"}))}},refresh:function(t){var o=+new Date,e,f,i,r,u;if(window.getSelection&&window.getSelection().removeAllRanges(),e=this.trigger({phase:"before",type:"refresh",target:typeof t!="undefined"?t:this.name,item:this.get(t)}),e.isCancelled===!0)return!1;if(typeof t=="undefined")for(f=0;f':''+u+"",this.get(t,!0)==this.items.length-1?n(this.box).find("#tb_"+this.name+"_right").before(u):n(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(this.items[parseInt(this.get(t,!0))+1].id)).before(u)):(r.html(u),i.hidden?r.css("display","none"):r.css("display",""),i.disabled?r.addClass("disabled"):r.removeClass("disabled")),this.trigger(n.extend(e,{phase:"after"})),+new Date-o},resize:function(){var i=+new Date,t;return(window.getSelection&&window.getSelection().removeAllRanges(),t=this.trigger({phase:"before",type:"resize",target:this.name}),t.isCancelled===!0)?!1:(this.trigger(n.extend(t,{phase:"after"})),+new Date-i)},destroy:function(){var t=this.trigger({phase:"before",type:"destroy",target:this.name});if(t.isCancelled===!0)return!1;n(this.box).find("> table #tb_"+this.name+"_right").length>0&&n(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-toolbar").html(""),n(this.box).html(""),delete w2ui[this.name],this.trigger(n.extend(t,{phase:"after"}))},getItemHTML:function(n){var t="",r,i;typeof n.caption!="undefined"&&(n.text=n.caption),typeof n.hint=="undefined"&&(n.hint=""),typeof n.text=="undefined"&&(n.text="");switch(n.type){case"menu":case"button":case"check":case"radio":case"drop":r=" ",n.img&&(r='
      '),n.icon&&(r='
      '),t+='
      '+r+(n.text!=""?'":"")+((n.type=="drop"||n.type=="menu")&&n.arrow!==!1?'':"")+"
      '+n.text+"   
      ";break;case"break":t+='
       
      ';break;case"html":t+='
      '+n.html+"
      "}return i="",typeof n.onRender=="function"&&(i=n.onRender.call(this,n.id,t)),typeof this.onRender=="function"&&(i=this.onRender(n.id,t)),i!=""&&typeof i!="undefined"&&(t=i),t},menuClick:function(t,i,r){var e,f,u;if(window.getSelection&&window.getSelection().removeAllRanges(),e=this,f=this.get(t),f&&!f.disabled){if(u=this.trigger({phase:"before",type:"click",target:typeof t!="undefined"?t:this.name,item:this.get(t),subItem:typeof i!="undefined"&&this.get(t)?this.get(t).items[i]:null,originalEvent:r}),u.isCancelled===!0)return!1;this.trigger(n.extend(u,{phase:"after"}))}},click:function(t,i){var f,r,o,e,u;if(window.getSelection&&window.getSelection().removeAllRanges(),f=this,r=this.get(t),r&&!r.disabled){if(o=this.trigger({phase:"before",type:"click",target:typeof t!="undefined"?t:this.name,item:this.get(t),originalEvent:i}),o.isCancelled===!0)return!1;if(n("#tb_"+this.name+"_item_"+w2utils.escapeId(r.id)+" table.w2ui-button").removeClass("down"),r.type=="radio"){for(e=0;e0&&this.insert(e,null,h)}return this.refresh(i.id),e},remove:function(){for(var r=0,n,i,t=0;t0&&arguments.length==1?this.refresh(n.parent.id):this.refresh(),r},set:function(t,i,r){var u,f;if(arguments.length==2&&(r=i,i=t,t=this),this._tmp=null,typeof t=="string"&&(t=this.get(t)),t.nodes==null)return null;for(u=0;u+
      '),r.expanded=!1,this.trigger(n.extend(i,{phase:"after"})),this.resize()},collapseAll:function(n){if(typeof n=="undefined"&&(n=this),typeof n=="string"&&(n=this.get(n)),n.nodes==null)return null;for(var t=0;t0&&this.collapseAll(n.nodes[t]);this.refresh(n.id)},expand:function(t){var r=this.get(t),i=this.trigger({phase:"before",type:"expand",target:t,object:r});if(i.isCancelled===!0)return!1;n(this.box).find("#node_"+w2utils.escapeId(t)+"_sub").slideDown("fast"),n(this.box).find("#node_"+w2utils.escapeId(t)+" .w2ui-node-dots:first-child").html('
      -
      '),r.expanded=!0,this.trigger(n.extend(i,{phase:"after"})),this.resize()},expandAll:function(n){if(typeof n=="undefined"&&(n=this),typeof n=="string"&&(n=this.get(n)),n.nodes==null)return null;for(var t=0;t0&&this.collapseAll(n.nodes[t]);this.refresh(n.id)},expandParents:function(n){var t=this.get(n);t!=null&&(t.parent&&(t.parent.expanded=!0,this.expandParents(t.parent.id)),this.refresh(n))},click:function(t,i){var r=this,f=this.get(t),u;f!=null&&((u=this.selected,f.disabled||f.group)||(n(r.box).find("#node_"+w2utils.escapeId(u)).removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected"),n(r.box).find("#node_"+w2utils.escapeId(t)).addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected"),setTimeout(function(){var e=r.trigger({phase:"before",type:"click",target:t,originalEvent:i,object:f});if(e.isCancelled===!0)return n(r.box).find("#node_"+w2utils.escapeId(t)).removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected"),n(r.box).find("#node_"+w2utils.escapeId(u)).addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected"),!1;u!=null&&(r.get(u).selected=!1),r.get(t).selected=!0,r.selected=t,r.trigger(n.extend(e,{phase:"after"}))},1)))},keydown:function(t){function f(n,t){var u;if(n==null)return null;var e=n.parent,o=i.get(n.id,!0),r=null;return n.expanded&&n.nodes.length>0&&t!==!0?(u=n.nodes[0],r=u.disabled||u.group?f(u):u):r=e&&o+10?(t=f.nodes[u-1],t.expanded&&t.nodes.length>0&&(r=t.nodes[t.nodes.length-1],t=r.disabled||r.group?e(r):r)):(t=f,o=!0),t!=null&&(t.disabled||t.group)&&(t=e(t)),t}var i=this,r=i.get(i.selected),o,u;if(r&&i.keyboard===!0){if(o=i.trigger({phase:"before",type:"keydown",target:i.name,originalEvent:t}),o.isCancelled===!0)return!1;(t.keyCode==13||t.keyCode==32)&&r.nodes.length>0&&i.toggle(i.selected),t.keyCode==37&&(r.nodes.length>0?i.collapse(i.selected):!r.parent||r.parent.disabled||r.parent.group||(i.collapse(r.parent.id),i.click(r.parent.id),setTimeout(function(){i.scrollIntoView()},50))),t.keyCode==39&&r.nodes.length>0&&i.expand(i.selected),t.keyCode==38&&(u=e(r),u!=null&&(i.click(u.id,t),setTimeout(function(){i.scrollIntoView()},50))),t.keyCode==40&&(u=f(r),u!=null&&(i.click(u.id,t),setTimeout(function(){i.scrollIntoView()},50))),n.inArray(t.keyCode,[13,32,37,38,39,40])!=-1&&(t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()),i.trigger(n.extend(o,{phase:"after"}));return}},scrollIntoView:function(t){var f;if(typeof t=="undefined"&&(t=this.selected),f=this.get(t),f!=null){var i=n(this.box).find(".w2ui-sidebar-div"),u=n(this.box).find("#node_"+w2utils.escapeId(t)),r=u.offset().top-i.offset().top;r+u.height()>i.height()&&i.animate({scrollTop:i.scrollTop()+i.height()/1.3}),r<=0&&i.animate({scrollTop:i.scrollTop()-i.height()/1.3})}},dblClick:function(t,i){window.getSelection&&window.getSelection().removeAllRanges();var u=this.get(t),r=this.trigger({phase:"before",type:"dblClick",target:t,originalEvent:i,object:u});if(r.isCancelled===!0)return!1;u.nodes.length>0&&this.toggle(t),this.trigger(n.extend(r,{phase:"after"}))},contextMenu:function(t,i){var r=this,u=r.get(t);t!=r.selected&&r.click(t),setTimeout(function(){var f=r.trigger({phase:"before",type:"contextMenu",target:t,originalEvent:i,object:u});if(f.isCancelled===!0)return!1;u.group||u.disabled||(r.menu.length>0&&n(r.box).find("#node_"+w2utils.escapeId(t)).w2menu(r.menu,{left:(i?i.offsetX||i.pageX:50)-25,select:function(n,i,u){r.menuClick(t,u,i)}}),r.trigger(n.extend(f,{phase:"after"})))},1)},menuClick:function(t,i,r){var u=this,f=u.trigger({phase:"before",type:"menuClick",target:t,originalEvent:r,menuIndex:i,menuItem:u.menu[i]});if(f.isCancelled===!0)return!1;u.trigger(n.extend(f,{phase:"after"}))},render:function(t){var i=this.trigger({phase:"before",type:"render",target:this.name,box:t});if(i.isCancelled===!0)return!1;(typeof t!="undefined"&&t!=null&&(n(this.box).find("> div > div.w2ui-sidebar-div").length>0&&n(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),this.box=t),this.box)&&(n(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-sidebar").html('
      '),n(this.box).find("> div").css({width:n(this.box).width()+"px",height:n(this.box).height()+"px"}),n(this.box).length>0&&(n(this.box)[0].style.cssText+=this.style),this.topHTML!=""&&(n(this.box).find(".w2ui-sidebar-top").html(this.topHTML),n(this.box).find(".w2ui-sidebar-div").css("top",n(this.box).find(".w2ui-sidebar-top").height()+"px")),this.bottomHTML!=""&&(n(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),n(this.box).find(".w2ui-sidebar-div").css("bottom",n(this.box).find(".w2ui-sidebar-bottom").height()+"px")),this.trigger(n.extend(i,{phase:"after"})),this.refresh())},refresh:function(t){function h(n){var e="",f=n.img,i,u,t;for(f==null&&(f=this.img),i=n.icon,i==null&&(i=this.icon),t=n.parent,u=0;t&&t.parent!=null;)t.group&&u--,t=t.parent,u++;return typeof n.caption!="undefined"&&(n.text=n.caption),n.group?e='
      \t"+(!n.hidden&&n.expanded?w2utils.lang("Hide"):w2utils.lang("Show"))+"\t"+n.text+'
      ':(n.selected&&!n.disabled&&(r.selected=n.id),t="",f&&(t='
      '),i&&(t='
      '),e='
      \t
      '+(n.nodes.length>0?n.expanded?"-":"+":n.plus?"+":"")+'
      '+t+(n.count!==""?'
      '+n.count+"
      ":"")+'
      '+n.text+'
      '),e}var c=+new Date,s,r,i,f,o,u,e;if(window.getSelection&&window.getSelection().removeAllRanges(),s=this.trigger({phase:"before",type:"refresh",target:typeof t!="undefined"?t:this.name}),s.isCancelled===!0)return!1;if(this.topHTML!=""&&(n(this.box).find(".w2ui-sidebar-top").html(this.topHTML),n(this.box).find(".w2ui-sidebar-div").css("top",n(this.box).find(".w2ui-sidebar-top").height()+"px")),this.bottomHTML!=""&&(n(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),n(this.box).find(".w2ui-sidebar-div").css("bottom",n(this.box).find(".w2ui-sidebar-bottom").height()+"px")),n(this.box).find("> div").css({width:n(this.box).width()+"px",height:n(this.box).height()+"px"}),r=this,typeof t=="undefined")i=this,f=".w2ui-sidebar-div";else{if(i=this.get(t),i==null)return;f="#node_"+w2utils.escapeId(i.id)+"_sub"}for(i!=this&&(o="#node_"+w2utils.escapeId(i.id),e=h(i),n(this.box).find(o).before(''),n(this.box).find(o).remove(),n(this.box).find(f).remove(),n("#sidebar_"+this.name+"_tmp").before(e),n("#sidebar_"+this.name+"_tmp").remove()),n(this.box).find(f).html(""),u=0;u div").css({width:n(this.box).width()+"px",height:n(this.box).height()+"px"}),this.trigger(n.extend(t,{phase:"after"})),+new Date-i)},destroy:function(){var t=this.trigger({phase:"before",type:"destroy",target:this.name});if(t.isCancelled===!0)return!1;n(this.box).find("> div > div.w2ui-sidebar-div").length>0&&n(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-sidebar").html(""),delete w2ui[this.name],this.trigger(n.extend(t,{phase:"after"}))},lock:function(t,i){var r=n(this.box).find("> div:first-child");w2utils.lock(r,t,i)},unlock:function(){w2utils.unlock(this.box)}},n.extend(t.prototype,w2utils.event),w2obj.sidebar=t}(jQuery),function(n){var t=new function(){this.customTypes=[]};n.fn.w2field=function(n){if(t[n])return t[n].apply(this,Array.prototype.slice.call(arguments,1));if(typeof n=="object")return t.init.apply(this,arguments);if(typeof n=="string")return t.init.apply(this,[{type:n}]);console.log("ERROR: Method "+n+" does not exist on jQuery.w2field")},n.extend(t,{init:function(i){var r=t;return n(this).each(function(){var l,s,y,f,h,o,c,a;if(typeof t.customTypes[i.type.toLowerCase()]=="function"){t.customTypes[i.type.toLowerCase()].call(this,i);return}l=i.type.toLowerCase();switch(l){case"clear":n(this).off("focus").off("blur").off("keypress").off("keydown").off("change").removeData(),n(this).prev().hasClass("w2ui-list")&&(n(this).prev().remove(),n(this).removeAttr("tabindex").css("border-color","").show()),n(this).prev().hasClass("w2ui-upload")&&(n(this).prev().remove(),n(this).removeAttr("tabindex").css("border-color","").show()),n(this).prev().hasClass("w2ui-field-helper")&&(n(this).css("padding-left",n(this).css("padding-top")),n(this).prev().remove()),n(this).next().hasClass("w2ui-field-helper")&&(n(this).css("padding-right",n(this).css("padding-top")),n(this).next().remove()),n(this).next().hasClass("w2ui-field-helper")&&n(this).next().remove();break;case"text":case"int":case"float":case"money":case"alphanumeric":case"hex":s=this,h={min:null,max:null,arrows:!1,keyboard:!0,suffix:"",prefix:""},i=n.extend({},h,i),["text","alphanumeric","hex"].indexOf(l)!=-1&&(i.arrows=!1,i.keyboard=!1);n(this).data("options",i).on("keypress",function(t){if(!t.metaKey&&!t.ctrlKey&&!t.altKey&&(t.charCode==t.keyCode||!(t.keyCode>0))){t.keyCode==13&&n(this).change();var i=String.fromCharCode(t.charCode);if(!v(i,!0))return t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,!1}}).on("keydown",function(t,r){var e,u,o,f;if(i.keyboard){e=!1,u=n(s).val(),u=v(u)?parseFloat(u):i.min||0,o=t.keyCode||r.keyCode,f=1,(t.ctrlKey||t.metaKey)&&(f=10);switch(o){case 38:n(s).val(u+f<=i.max||i.max==null?u+f:i.max).change(),l=="money"&&n(s).val(Number(n(s).val()).toFixed(2)),e=!0;break;case 40:n(s).val(u-f>=i.min||i.min==null?u-f:i.min).change(),l=="money"&&n(s).val(Number(n(s).val()).toFixed(2)),e=!0}e&&(t.preventDefault(),setTimeout(function(){s.setSelectionRange(s.value.length,s.value.length)},0))}}).on("change",function(t){var r=n(s).val(),u=!1;if(i.min!=null&&r!=""&&ri.max&&(n(s).val(i.max).change(),u=!0),u)return t.stopPropagation(),t.preventDefault(),!1;this.value==""||v(this.value)||n(this).val(i.min!=null?i.min:"")});if(n(this).val()==""&&i.min!=null&&n(this).val(i.min),i.prefix!=""){n(this).before('
      '+i.prefix+"
      "),o=n(this).prev();o.css({color:n(this).css("color"),"font-family":n(this).css("font-family"),"font-size":n(this).css("font-size"),"padding-top":n(this).css("padding-top"),"padding-bottom":n(this).css("padding-bottom"),"padding-left":n(this).css("padding-left"),"padding-right":0,"margin-top":parseInt(n(this).css("margin-top"))+1+"px","margin-bottom":parseInt(n(this).css("margin-bottom"))+1+"px","margin-left":0,"margin-right":0}).on("click",function(){n(this).next().focus()});n(this).css("padding-left",o.width()+parseInt(n(this).css("padding-left"))+5+"px")}if(c=parseInt(n(this).css("padding-right")),i.arrows!=""){n(this).after('
       \t
      \t\t
      \t
      \t
      \t\t
      \t
      \t
      '),y=w2utils.getSize(this,"height"),o=n(this).next();o.css({color:n(this).css("color"),"font-family":n(this).css("font-family"),"font-size":n(this).css("font-size"),height:n(this).height()+parseInt(n(this).css("padding-top"))+parseInt(n(this).css("padding-bottom"))+"px",padding:"0px","margin-top":parseInt(n(this).css("margin-top"))+1+"px","margin-bottom":"0px","border-left":"1px solid silver"}).css("margin-left","-"+(o.width()+parseInt(n(this).css("margin-right"))+12)+"px").on("mousedown",function(t){function r(){clearTimeout(n("body").data("_field_update_timer")),n("body").off("mouseup",r)}function i(t){n(s).focus().trigger(n.Event("keydown"),{keyCode:n(u.target).attr("type")=="up"?38:40}),t!==!1&&n("body").data("_field_update_timer",setTimeout(i,60))}var f=this,u=t;n("body").on("mouseup",r);n("body").data("_field_update_timer",setTimeout(i,700)),i(!1)});c+=o.width()+12,n(this).css("padding-right",c+"px")}if(i.suffix!=""){n(this).after('
      '+i.suffix+"
      "),o=n(this).next();o.css({color:n(this).css("color"),"font-family":n(this).css("font-family"),"font-size":n(this).css("font-size"),"padding-top":n(this).css("padding-top"),"padding-bottom":n(this).css("padding-bottom"),"padding-left":"3px","padding-right":n(this).css("padding-right"),"margin-top":parseInt(n(this).css("margin-top"))+1+"px","margin-bottom":parseInt(n(this).css("margin-bottom"))+1+"px"}).on("click",function(){n(this).prev().focus()});o.css("margin-left","-"+(o.width()+parseInt(n(this).css("padding-right"))+5)+"px"),c+=o.width()+3,n(this).css("padding-right",c+"px")}function v(n,t){switch(l){case"int":return t&&["-"].indexOf(n)!=-1?!0:w2utils.isInt(n);case"float":return t&&["-","."].indexOf(n)!=-1?!0:w2utils.isFloat(n);case"money":return t&&["-",".","$","€","£","¥"].indexOf(n)!=-1?!0:w2utils.isMoney(n);case"hex":return w2utils.isHex(n);case"alphanumeric":return w2utils.isAlphaNumeric(n)}return!0}break;case"date":f=this,h={format:w2utils.settings.date_format,start:"",end:"",blocked:{},colored:{}},i=n.extend({},h,i);n(this).css({transition:"none","-webkit-transition":"none","-moz-transition":"none","-ms-transition":"none","-o-transition":"none"}).data("options",i).on("focus",function(){var e=parseFloat(n(f).offset().top)+parseFloat(f.offsetHeight),u=parseFloat(n(f).offset().left),t,r;clearInterval(n(f).data("mtimer")),n("#global_calendar_div").remove(),n("body").append('
      '),n("#global_calendar_div").html(n().w2field("calendar_get",f.value,i)).css({left:u+"px",top:e+"px"}).data("el",f).show(),t=n(window).width()+n(document).scrollLeft()-1,u+n("#global_calendar_div").width()>t&&n("#global_calendar_div").css("left",t-n("#global_calendar_div").width()+"px"),r=setInterval(function(){var i=n(window).width()+n(document).scrollLeft()-1,t=n(f).offset().left;if(t+n("#global_calendar_div").width()>i&&(t=i-n("#global_calendar_div").width()),n("#global_calendar_div").data("position")!=n(f).offset().left+"x"+(n(f).offset().top+f.offsetHeight)&&n("#global_calendar_div").css({"-webkit-transition":".2s",left:t+"px",top:n(f).offset().top+f.offsetHeight+"px"}).data("position",n(f).offset().left+"x"+(n(f).offset().top+f.offsetHeight)),n(f).length==0||n(f).offset().left==0&&n(f).offset().top==0){clearInterval(r),n("#global_calendar_div").remove();return}},100),n(f).data("mtimer",r)}).on("blur",function(){n(f).val(n.trim(n(f).val())),n.trim(n(f).val())==""||w2utils.isDate(n(f).val(),i.format)||n(this).w2tag(w2utils.lang("Not a valid date")+": "+i.format),clearInterval(n(f).data("mtimer")),n("#global_calendar_div").remove()}).on("keypress",function(){var r=this;setTimeout(function(){n("#global_calendar_div").html(n().w2field("calendar_get",r.value,i))},10)});setTimeout(function(){w2utils.isInt(f.value)&&(f.value=w2utils.formatDate(f.value,i.format))},1);break;case"time":break;case"datetime":break;case"color":f=this,h={prefix:"#",suffix:'
      '},i=n.extend({},h,i);n(this).attr("maxlength",6).on("focus",function(){var u=parseFloat(n(f).offset().top)+parseFloat(f.offsetHeight),r=parseFloat(n(f).offset().left),t,i;clearInterval(n(f).data("mtimer")),n("#global_color_div").remove(),n("body").append('
      '),n("#global_color_div").html(n().w2field("getColorHTML",f.value)).css({left:r+"px",top:u+"px"}).data("el",f).show(),t=n(window).width()+n(document).scrollLeft()-1,r+n("#global_color_div").width()>t&&n("#global_color_div").css("left",t-n("#global_color_div").width()+"px"),i=setInterval(function(){var r=n(window).width()+n(document).scrollLeft()-1,t=n(f).offset().left;if(t+n("#global_color_div").width()>r&&(t=r-n("#global_color_div").width()),n("#global_color_div").data("position")!=n(f).offset().left+"x"+(n(f).offset().top+f.offsetHeight)&&n("#global_color_div").css({"-webkit-transition":".2s",left:t+"px",top:n(f).offset().top+f.offsetHeight+"px"}).data("position",n(f).offset().left+"x"+(n(f).offset().top+f.offsetHeight)),n(f).length==0||n(f).offset().left==0&&n(f).offset().top==0){clearInterval(i),n("#global_color_div").remove();return}},100),n(f).data("mtimer",i)}).on("click",function(){n(this).trigger("focus")}).on("blur",function(){n(f).val(n.trim(n(f).val())),clearInterval(n(f).data("mtimer")),n("#global_color_div").remove()}).on("keydown",function(t){if(t.keyCode==86&&(t.ctrlKey||t.metaKey)){var i=this;n(this).prop("maxlength",7),setTimeout(function(){var t=n(i).val();t.substr(0,1)=="#"&&(t=t.substr(1)),w2utils.isHex(t)||(t=""),n(i).val(t).prop("maxlength",6).change()},20)}}).on("keyup",function(t){t.keyCode==86&&(t.ctrlKey||t.metaKey)&&n(this).prop("maxlength",6)}).on("keypress",function(t){t.keyCode==13&&n(this).change();var i=String.fromCharCode(t.charCode);if(!w2utils.isHex(i,!0))return t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,!1}).on("change",function(){var i="#"+n(this).val();n(this).val().length!=6&&n(this).val().length!=3&&(i=""),n(this).next().find("div").css("background-color",i)});if(i.prefix!=""){n(this).before('
      '+i.prefix+"
      "),o=n(this).prev();o.css({color:n(this).css("color"),"font-family":n(this).css("font-family"),"font-size":n(this).css("font-size"),"padding-top":n(this).css("padding-top"),"padding-bottom":n(this).css("padding-bottom"),"padding-left":n(this).css("padding-left"),"padding-right":0,"margin-top":parseInt(n(this).css("margin-top"))+1+"px","margin-bottom":parseInt(n(this).css("margin-bottom"))+1+"px","margin-left":0,"margin-right":0}).on("click",function(){n(this).next().focus()});n(this).css("padding-left",o.width()+parseInt(n(this).css("padding-left"))+2+"px")}if(i.suffix!=""){n(this).after('
      '+i.suffix+"
      "),o=n(this).next();o.css({color:n(this).css("color"),"font-family":n(this).css("font-family"),"font-size":n(this).css("font-size"),"padding-top":n(this).css("padding-top"),"padding-bottom":n(this).css("padding-bottom"),"padding-left":"3px","padding-right":n(this).css("padding-right"),"margin-top":parseInt(n(this).css("margin-top"))+1+"px","margin-bottom":parseInt(n(this).css("margin-bottom"))+1+"px"}).on("click",function(){n(this).prev().focus()});o.css("margin-left","-"+(o.width()+parseInt(n(this).css("padding-right"))+4)+"px"),c=o.width()+parseInt(n(this).css("padding-right"))+4,n(this).css("padding-right",c+"px"),o.find("div").css("background-color","#"+n(f).val())}break;case"select":case"list":if(this.tagName!="SELECT"){console.log("ERROR: You can only apply $().w2field('list') to a SELECT element");return}var h={url:"",items:[],value:null,showNone:!0},f=this,e=n.extend({},h,i);n(f).data("settings",e),f.refresh=function(){var i=n(f).data("settings"),e="",r=t.cleanItems(i.items),u;i.showNone&&(e='");for(u in r)i.showNone||i.value!=null||(i.value=r[u].id),e+='";n(f).html(e),n(f).val(i.value),n(f).val()!=i.value&&n(f).change()},e.url!=""?n.ajax({type:"GET",dataType:"text",url:e.url,complete:function(i,r){if(r=="success"){var e=n.parseJSON(i.responseText),u=n(f).data("settings");u.items=t.cleanItems(e.items),n(f).data("settings",u),f.refresh()}}}):f.refresh();break;case"enum":if(this.tagName!="INPUT"){console.log("ERROR: You can only apply $().w2field('enum') to an INPUT element");return}var h={url:"",items:[],selected:[],max:0,maxHeight:172,showAll:!1,match:"begins with",render:null,maxCache:500,onShow:null,onHide:null,onAdd:null,onRemove:null,onItemOver:null,onItemOut:null,onItemClick:null},f=this,e=n.extend({},h,i);e.items=t.cleanItems(e.items),e.selected=t.cleanItems(e.selected),n(this).data("selected",e.selected),n(this).css({padding:"0px","border-color":"transparent","background-color":"transparent",outline:"none"}),this.add=function(t){var i,r,u;n(this).attr("readonly")||(i=n(this).data("selected"),r=n(this).data("settings"),typeof r.onAdd!="function"||(u=r.onAdd(t,r),u!==!1))&&(n.isArray(i)||(i=[]),r.max!=0&&r.max<=i.length&&i.splice(i.length-1,1),i.push(t),n(this).data("last_del",null),n(this).trigger("change"))},this.remove=function(i){var r=n(this).data("settings"),u;(typeof r.onRemove!="function"||(u=r.onRemove(i,r),u!==!1))&&(n(this).attr("readonly")||(n(this).data("selected").splice(i,1),n(this).parent().find("[title=Remove][index="+i+"]").remove(),this.refresh(),t.list_render.call(this),n(this).trigger("change")))},this.show=function(){var i,u,r;if(!n(this).attr("readonly")){if(i=n(this).data("settings"),n("#w2ui-global-items").length==0)n("body").append('
      ');else return;u=n("#w2ui-global-items"),u.css({display:"block",left:n(f).offset().left+"px",top:n(f).offset().top+f.offsetHeight+3+"px"}).width(w2utils.getSize(f,"width")).data("position",n(f).offset().left+"x"+(n(f).offset().top+f.offsetHeight)),t.list_render.call(f),r=function(){var i=n("#w2ui-global-items");if(n(f).length==0||n(f).offset().left==0&&n(f).offset().top==0){clearInterval(n(f).data("mtimer")),hide();return}i.data("position")!=n(f).offset().left+"x"+(n(f).offset().top+f.offsetHeight)&&(i.css({"-webkit-transition":".2s",left:n(f).offset().left+"px",top:n(f).offset().top+f.offsetHeight+3+"px"}).data("position",n(f).offset().left+"x"+(n(f).offset().top+f.offsetHeight)),setTimeout(function(){t.list_render.call(f,n(f).data("last_search"))},200)),i.length>0&&n(f).data("mtimer",setTimeout(r,100))},n(f).data("mtimer",setTimeout(r,100)),typeof i.onShow=="function"&&i.onShow.call(this,i)}},this.hide=function(){var t=n(this).data("settings");clearTimeout(n(f).data("mtimer")),n("#w2ui-global-items").remove(),typeof t.onHide=="function"&&t.onHide.call(this,t)},this.refresh=function(){var r=this,i,t;n(n(this).data("div")).remove();var o="margin-top: "+n(this).css("margin-top")+"; margin-bottom: "+n(this).css("margin-bottom")+"; margin-left: "+n(this).css("margin-left")+"; margin-right: "+n(this).css("margin-right")+"; width: "+(w2utils.getSize(this,"width")-parseInt(n(this).css("margin-left"))-parseInt(n(this).css("margin-right")))+"px; ",u='
        ',f=n(this).data("selected");for(i in f)u+='
      • \t
          
        '+f[i].text+"
      • ";u+='
      • \t
      ',n(this).before(u),t=n(this).prev()[0],n(this).data("div",t);n(t).find("li").data("mouse","out").on("click",function(t){if(!n(t.target).hasClass("nomouse")){if(t.target.title==w2utils.lang("Remove")){r.remove(n(t.target).attr("index"));return}t.stopPropagation(),typeof e.onItemClick=="function"&&e.onItemClick.call(this,e)}}).on("mouseover",function(t){var i=t.target;(i.tagName!="LI"&&(i=i.parentNode),n(i).hasClass("nomouse"))||(n(i).data("mouse")=="out"&&typeof e.onItemOver=="function"&&e.onItemOver.call(this,e),n(i).data("mouse","over"))}).on("mouseout",function(t){var i=t.target;(i.tagName!="LI"&&(i=i.parentNode),n(i).hasClass("nomouse"))||(n(i).data("mouse","leaving"),setTimeout(function(){n(i).data("mouse")=="leaving"&&(n(i).data("mouse","out"),typeof e.onItemOut=="function"&&e.onItemOut.call(this,e))},0))});n(t).on("click",function(){n(this).find("input").focus()}).find("input").on("focus",function(i){n(t).css({outline:"auto 5px -webkit-focus-ring-color","outline-offset":"-2px"}),r.show(),i.stopPropagation?i.stopPropagation():i.cancelBubble=!0}).on("blur",function(i){n(t).css("outline","none"),r.hide(),i.stopPropagation?i.stopPropagation():i.cancelBubble=!0});r.resize()},this.resize=function(){var r=n(this).data("settings"),i=n(this).prev(),t=n(i).find(">div").height();t<23&&(t=23),t>r.maxHeight&&(t=r.maxHeight),n(i).height(t+(t%23==0?0:23-t%23)),i.length>0&&(i[0].scrollTop=1e3),n(this).height(t)},n(this).data("settings",e).attr("tabindex",-1),f.refresh();break;case"upload":if(this.tagName!="INPUT"){console.log("ERROR: You can only apply $().w2field('upload') to an INPUT element");return}var h={url:"",base64:!0,hint:w2utils.lang("Attach files by dragging and dropping or Click to Select"),max:0,maxSize:0,maxFileSize:0,onAdd:null,onRemove:null,onItemClick:null,onItemDblClick:null,onItemOver:null,onItemOut:null,onProgress:null,onComplete:null},f=this,e=n.extend({},h,i);e.base64===!0&&(e.maxSize==0&&(e.maxSize=20971520),e.maxFileSize==0&&(e.maxFileSize=20971520)),a=e.selected,delete e.selected,n.isArray(a)||(a=[]),n(this).data("selected",a).data("settings",e).attr("tabindex",-1),t.upload_init.call(this),this.refresh=function(){var o=this,r=n(this).data("div"),i=n(this).data("settings"),c=n(this).data("selected"),h,t,s,l,e,f,u;n(r).find("li").remove(),n(r).find("> span:first-child").css("line-height",n(r).height()-w2utils.getSize(r,"+height")-8+"px");for(h in c){t=c[h],s=n(r).find(".file-list li").length,n(r).find("> span:first-child").remove(),n(r).find(".file-list").append('
    • \t
        
      \t'+t.name+'\t - '+w2utils.size(t.size)+"
    • "),l=n(r).find(".file-list #file-"+s),e="",/image/i.test(t.type)&&(e='
      \t
      '),f='style="padding: 3px; text-align: right; color: #777;"',u='style="padding: 3px"',e+='
      \t\t\t\t\t\t
      Name:"+t.name+"
      Size:"+w2utils.size(t.size)+"
      Type:\t\t'+t.type+"\t
      Modified:"+w2utils.date(t.modified)+"
      ";l.data("file",t).on("click",function(t){if(typeof i.onItemClick=="function"){var r=i.onItemClick.call(o,n(this).data("file"));if(r===!1)return}n(t.target).hasClass("file-delete")||t.stopPropagation()}).on("dblclick",function(t){if(typeof i.onItemDblClick=="function"){var r=i.onItemDblClick.call(o,n(this).data("file"));if(r===!1)return}t.stopPropagation(),document.selection?document.selection.empty():document.defaultView.getSelection().removeAllRanges()}).on("mouseover",function(){var u,r;(typeof i.onItemOver!="function"||(u=i.onItemOver.call(o,n(this).data("file")),u!==!1))&&(r=n(this).data("file"),n(this).w2overlay(e.replace("##FILE##",r.content?"data:"+r.type+";base64,"+r.content:""),{top:-4}))}).on("mouseout",function(){if(typeof i.onItemOut=="function"){var t=i.onItemOut.call(o,n(this).data("file"));if(t===!1)return}n(this).w2overlay()})}},this.refresh();break;case"slider":break;default:console.log('ERROR: w2field does not recognize "'+i.type+'" field type.')}})},addType:function(n,i){t.customTypes[String(n).toLowerCase()]=i},cleanItems:function(t){var e=[],f;for(f in t){var r="",u="",i=t[f];if(i!=null){if(n.isPlainObject(t))r=f,u=i;else if(typeof i=="object"&&(typeof i.id!="undefined"&&(r=i.id),typeof i.value!="undefined"&&(r=i.value),typeof i.txt!="undefined"&&(u=i.txt),typeof i.text!="undefined"&&(u=i.text)),typeof i=="string"){if(String(i)=="")continue;r=i,u=i,i={}}w2utils.isInt(r)&&(r=parseInt(r)),w2utils.isFloat(r)&&(r=parseFloat(r)),e.push(n.extend({},i,{id:r,text:u}))}}return e},upload_init:function(){var i=this,o=n(this).data("settings"),u=n(i).prev(),e,f,r;u.length>0&&u[0].tagName=="DIV"&&u.hasClass("w2ui-upload")&&u.remove(),e="margin-top: "+n(i).css("margin-top")+"; margin-bottom: "+n(i).css("margin-bottom")+"; margin-left: "+n(i).css("margin-left")+"; margin-right: "+n(i).css("margin-right")+"; width: "+(w2utils.getSize(i,"width")-parseInt(n(i).css("margin-left"))-parseInt(n(i).css("margin-right")))+"px; height: "+(w2utils.getSize(i,"height")-parseInt(n(i).css("margin-top"))-parseInt(n(i).css("margin-bottom")))+"px; ",f='
      \t'+o.hint+'\t
        \t
        ',n(i).css({display1:"none","border-color":"transparent"}).before(f),n(i).data("div",n(i).prev()[0]),r=n(i).data("div");n(r).find(".file-input").off("change").on("change",function(){if(typeof this.files!="undefined")for(var n=0,r=this.files.length;ni.maxFileSize){r="Maximum file size is "+w2utils.size(i.maxFileSize),n(o).w2tag(r),console.log("ERROR: "+r);return}if(i.maxSize!=0&&l+f.size>i.maxSize){r="Maximum total size is "+w2utils.size(i.maxFileSize),n(o).w2tag(r),console.log("ERROR: "+r);return}if(i.max!=0&&a>=i.max){r="Maximum number of files is "+i.max,n(o).w2tag(r),console.log("ERROR: "+r);return}(typeof i.onAdd!="function"||(h=i.onAdd.call(u,f),h!==!1))&&(s.push(f),typeof FileReader!="undefined"&&i.base64===!0?(e=new FileReader,e.onload=function(){return function(t){var i=t.target.result,r=i.indexOf(",");f.content=i.substr(r+1),u.refresh(),n(u).trigger("change")}}(),e.readAsDataURL(t)):(u.refresh(),n(u).trigger("change")))},upload_remove:function(t){var r=this,s=n(r).data("div"),e=n(r).data("settings"),u=n(r).data("selected"),f=n(t).data("file"),o,i;if(typeof e.onRemove=="function"&&(o=e.onRemove.call(r,f),o===!1))return!1;for(i=u.length-1;i>=0;i--)u[i].name==f.name&&u[i].size==f.size&&u.splice(i,1);n(t).fadeOut("fast"),setTimeout(function(){n(t).remove(),u.length==0&&n(s).prepend(""+e.hint+""),r.refresh(),n(r).trigger("change")},300)},list_render:function(i){var r=this,e=n("#w2ui-global-items"),u=n(this).data("settings"),o=u.items,v=n(this).data("selected"),k,a,w,f,c,h,g,y;if(e.length!=0){typeof i=="undefined"&&(k="",k+='
        ',e.html(k),i=""),n(this).data("last_search",i),(typeof n(r).data("last_index")=="undefined"||n(r).data("last_index")==null)&&n(r).data("last_index",0),typeof u.last_total=="undefined"&&(u.last_total=-1),typeof u.last_search_len=="undefined"&&(u.last_search_len=0),typeof u.last_search_match=="undefined"&&(u.last_search_match=-1),u.url!=""&&(o.length==0&&u.last_total!=0||i.length>u.last_search_len&&u.last_total>u.maxCache||i.length",d=[];for(f in v)d.push(w2utils.isInt(v[f].id)?parseInt(v[f].id):String(v[f].id));w="";for(f in o)if(c=o[f].id,h=o[f].text,n.inArray(w2utils.isInt(c)?parseInt(c):String(c),d)==-1||u.showAll===!0){var p=String(i).toLowerCase(),b=h.toLowerCase(),a=p.length<=b.length&&b.substr(0,p.length)==p;u.match.toLowerCase()=="contains"&&b.indexOf(p)!=-1&&(a=!0),a&&(typeof u.render=="function"&&(h=u.render(o[f],v)),h!==!1&&(typeof o[f].group!="undefined"&&o[f].group!=w&&(w=o[f].group,l+='
      • '+w+"
      • "),l+='\n
      • '+h+"
      • ",s==n(r).data("last_index")&&n(r).data("last_item",o[f]),s++))}l+="",s==0&&(l='
        '+w2utils.lang("No items found")+"
        ",g=!0),e.find(".w2ui-items-list").html(l),n(this).data("last_max",s-1),e.find("li.selected").length>0&&e.find("li.selected")[0].scrollIntoView(!1),e.css({"-webkit-transition":"0s",height:"auto"}),y=parseInt(n(document).height())-parseInt(e.offset().top)-8,parseInt(e.height())>y&&(e.css({height:y-5+"px",overflow:"show"}),n(e).find(".w2ui-items-list").css({height:y-15+"px",overflow:"auto"}));n(e).off("mousedown").on("mousedown",function(i){var e=i.target,f,o;if(e.tagName!="LI"&&(e=n(e).parents("li")),f=n(e).attr("index"),f){if(o=u.items[f],typeof f=="undefined")if(i.preventDefault)i.preventDefault();else return!1;r.add(o),n(r).data("last_index",0),r.refresh(),t.list_render.call(r,"")}});n(r).prev().find("li > input").val(i).css("max-width",n(e).width()-25+"px").width((i.length+2)*6+"px").focus().on("click",function(n){n.stopPropagation?n.stopPropagation():n.cancelBubble=!0}).off("keyup").on("keyup",function(i){var u=this;setTimeout(function(){var f=n(r).data("last_index"),e;switch(i.keyCode){case 38:f--,f<0&&(f=0),n(r).data("last_index",f),i.preventDefault&&i.preventDefault();break;case 40:f++,f>n(r).data("last_max")&&(f=n(r).data("last_max")),n(r).data("last_index",f),i.preventDefault&&i.preventDefault();break;case 13:if(typeof n(r).data("last_item")=="undefined"||n(r).data("last_item")==null||g===!0)break;e=n(r).data("selected"),r.add(n(r).data("last_item")),f>n(r).data("last_max")-1&&(f=n(r).data("last_max")-1),n(r).data("last_index",f),n(r).data("last_item",null),n(u).val(""),r.refresh(),i.preventDefault&&i.preventDefault();break;case 8:String(u.value)==""&&(typeof n(r).data("last_del")=="undefined"||n(r).data("last_del")==null?(e=n(r).data("selected"),n.isArray(e)||(e=[]),n(r).data("last_del",e.length-1),r.refresh()):(e=n(r).data("selected"),r.remove(e.length-1)));break;default:n(r).data("last_index",0),n(r).data("last_del",null)}r.resize(),i.keyCode==8&&String(u.value)==""||(n(r).prev().find("li").css("opacity","1"),n(r).data("last_del",null)),n.inArray(i.keyCode,[16,91,37,39])==-1&&t.list_render.call(r,u.value)},10)})}},calendar_get:function(t,i){var e=new Date,s=Number(e.getMonth())+1+"/"+e.getDate()+"/"+(String(e.getYear()).length>3?e.getYear():e.getYear()+1900),o;(String(t)==""||String(t)=="undefined")&&(t=w2utils.formatDate(s,i.format)),w2utils.isDate(t,i.format)||(t=w2utils.formatDate(s,i.format));var r=t.replace(/-/g,"/").replace(/\./g,"/").toLowerCase().split("/"),f=i.format.replace(/-/g,"/").replace(/\./g,"/").toLowerCase(),u=new Date;return f=="mm/dd/yyyy"&&(u=new Date(r[0]+"/"+r[1]+"/"+r[2])),f=="m/d/yyyy"&&(u=new Date(r[0]+"/"+r[1]+"/"+r[2])),f=="dd/mm/yyyy"&&(u=new Date(r[1]+"/"+r[0]+"/"+r[2])),f=="d/m/yyyy"&&(u=new Date(r[1]+"/"+r[0]+"/"+r[2])),f=="yyyy/dd/mm"&&(u=new Date(r[2]+"/"+r[1]+"/"+r[0])),f=="yyyy/d/m"&&(u=new Date(r[2]+"/"+r[1]+"/"+r[0])),f=="yyyy/mm/dd"&&(u=new Date(r[1]+"/"+r[2]+"/"+r[0])),f=="yyyy/m/d"&&(u=new Date(r[1]+"/"+r[2]+"/"+r[0])),o='
        '+n().w2field("calendar_month",u.getMonth()+1,u.getFullYear(),i)+"
        "},calendar_next:function(t){var f=String(t).split("/"),i=f[0],u=f[1],r;parseInt(i)<12?i=parseInt(i)+1:(i=1,u=parseInt(u)+1),r=n(n("#global_calendar_div.w2ui-calendar").data("el")).data("options"),n("#global_calendar_div.w2ui-calendar").html(n().w2field("calendar_get",w2utils.formatDate(i+"/1/"+u,r.format),r))},calendar_previous:function(t){var f=String(t).split("/"),i=f[0],u=f[1],r;parseInt(i)>1?i=parseInt(i)-1:(i=12,u=parseInt(u)-1),r=n(n("#global_calendar_div.w2ui-calendar").data("el")).data("options"),n("#global_calendar_div.w2ui-calendar").html(n().w2field("calendar_get",w2utils.formatDate(i+"/1/"+u,r.format),r))},calendar_month:function(t,i,r){var u=new Date,rt=w2utils.settings.fullmonths,et=w2utils.settings.fulldays,p=["31","28","31","30","31","30","31","31","30","31","30","31"],ft=Number(u.getMonth())+1+"/"+u.getDate()+"/"+(String(u.getYear()).length>3?u.getYear():u.getYear()+1900),c,g,e,s,f,v,o,h,l;i=Number(i),t=Number(t),(i===null||i==="")&&(i=String(u.getYear()).length>3?u.getYear():u.getYear()+1900),(t===null||t==="")&&(t=Number(u.getMonth())+1),t>12&&(t=t-12,i++),(t<1||t==0)&&(t=t+12,i--),p[1]=i/4==Math.floor(i/4)?"29":"28",i==null&&(i=u.getYear()),t==null&&(t=u.getMonth()-1),u=new Date,u.setDate(1),u.setMonth(t-1),u.setYear(i);var y=u.getDay(),nt=w2utils.settings.shortdays,d="";for(c=0,g=nt.length;c"+nt[c]+"";for(e='
        \t
        <-
        \t
        ->
        "+rt[t-1]+", "+i+'
        \t'+d+"\t",s=1,f=1;f<43;f++){if(y==0&&f==1){for(v=0;v<6;v++)e+='';f+=6}else if(fp[t-1]){e+='',f%7==0&&(e+="");continue}o=t+"/"+s+"/"+i,h="",f%7==6&&(h="w2ui-saturday"),f%7==0&&(h="w2ui-sunday"),o==ft&&(h+=" w2ui-today");var ut=s,b="",w="",a="";if(r.colored&&r.colored[o]!=undefined&&(tmp=r.colored[o].split(":"),w="background-color: "+tmp[0]+";",b="color: "+tmp[1]+";"),l=!1,r.start||r.end){var tt=new Date(r.start),it=new Date(r.end),k=new Date(o);(kit)&&(a=" w2ui-blocked-date",l=!0)}r.blocked&&n.inArray(o,r.blocked)!=-1&&(a=" w2ui-blocked-date",l=!0),e+='"),s++}return e+="
          
        ",(f%7==0||y==0&&f==1)&&(e+="
        "},getColorHTML:function(n){for(var r='
        ',u=[["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"]],i,t=0;t<8;t++){for(r+="",i=0;i<8;i++)r+="";r+="",t<2&&(r+='')}return r+="
        \t
        \t\t'+(n==u[t][i]?"•":" ")+"\t
        "}}),w2obj.field=t}(jQuery),function($){var w2form=function(n){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.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,n)};$.fn.w2form=function(n){var s,u,i,r;if(typeof n!="object"&&n){if(w2ui[$(this).attr("name")])return r=w2ui[$(this).attr("name")],r[n].apply(r,Array.prototype.slice.call(arguments,1)),this;console.log("ERROR: Method "+n+" does not exist on jQuery.w2form")}else{if(r=this,!n||typeof n.name=="undefined"){console.log('ERROR: The parameter "name" is required but not supplied in $().w2form().');return}if(typeof w2ui[n.name]!="undefined"){console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+n.name+").");return}if(!w2utils.isAlphaNumeric(n.name)){console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). ');return}var o=n.record,e=n.original,h=n.fields,c=n.toolbar,f=n.tabs,t=new w2form(n);if($.extend(t,{record:{},original:{},fields:[],tabs:{},toolbar:{},handlers:[]}),$.isArray(f)){$.extend(!0,t.tabs,{tabs:[]});for(s in f)u=f[s],typeof u=="object"?t.tabs.tabs.push(u):t.tabs.tabs.push({id:u,caption:u})}else $.extend(!0,t.tabs,f);$.extend(!0,t.toolbar,c);for(i in h)t.fields[i]=$.extend(!0,{},h[i]);for(i in o)t.record[i]=$.isPlainObject(o[i])?$.extend(!0,{},o[i]):o[i];for(i in e)t.original[i]=$.isPlainObject(e[i])?$.extend(!0,{},e[i]):e[i];return r.length>0&&(t.box=r[0]),t.formURL!=""?$.get(t.formURL,function(n){t.formHTML=n,t.isGenerated=!0,($(t.box).length!=0||n.length!=0)&&($(t.box).html(n),t.render(t.box))}):t.formHTML!=""||(t.formHTML=$(this).length!=0&&$.trim($(this).html())!=""?$(this).html():t.generateHTML()),w2ui[t.name]=t,t.formURL==""&&(String(t.formHTML).indexOf("w2ui-page")==-1&&(t.formHTML='
        '+t.formHTML+"
        "),$(t.box).html(t.formHTML),t.isGenerated=!0,t.render(t.box)),t}},w2form.prototype={get:function(n,t){for(var i in this.fields)if(this.fields[i].name==n)return t===!0?i:this.fields[i];return null},set:function(n,t){for(var i in this.fields)if(this.fields[i].name==n)return $.extend(this.fields[i],t),this.refresh(),!0;return!1},reload:function(n){var t=typeof this.url!="object"?this.url:this.url.get;t&&this.recid!=0?this.request(n):(this.refresh(),typeof n=="function"&&n())},clear:function(){var n,t;this.recid=0,this.record={};for(n in this.fields)t=this.fields[n];$().w2tag(),this.refresh()},error:function(n){var i=this,t=this.trigger({target:this.name,type:"error",message:n,xhr:this.last.xhr});if(t.isCancelled===!0)return typeof callBack=="function"&&callBack(),!1;setTimeout(function(){w2alert(n,"Error")},1),this.trigger($.extend(t,{phase:"after"}))},validate:function(n){var i,e,t,u,r,o,f;typeof n=="undefined"&&(n=!0),i=[];for(e in this.fields){t=this.fields[e],this.record[t.name]==null&&(this.record[t.name]="");switch(t.type){case"int":this.record[t.name]&&!w2utils.isInt(this.record[t.name])&&i.push({field:t,error:w2utils.lang("Not an integer")});break;case"float":this.record[t.name]&&!w2utils.isFloat(this.record[t.name])&&i.push({field:t,error:w2utils.lang("Not a float")});break;case"money":this.record[t.name]&&!w2utils.isMoney(this.record[t.name])&&i.push({field:t,error:w2utils.lang("Not in money format")});break;case"hex":this.record[t.name]&&!w2utils.isHex(this.record[t.name])&&i.push({field:t,error:w2utils.lang("Not a hex number")});break;case"email":this.record[t.name]&&!w2utils.isEmail(this.record[t.name])&&i.push({field:t,error:w2utils.lang("Not a valid email")});break;case"checkbox":this.record[t.name]=this.record[t.name]==!0?1:0;break;case"date":this.record[t.name]&&!w2utils.isDate(this.record[t.name],t.options.format)&&i.push({field:t,error:w2utils.lang("Not a valid date")+": "+t.options.format})}u=this.record[t.name],t.required&&(u===""||$.isArray(u)&&u.length==0)&&i.push({field:t,error:w2utils.lang("Required field")}),t.equalto&&this.record[t.name]!=this.record[t.equalto]&&i.push({field:t,error:w2utils.lang("Field should be equal to ")+t.equalto})}if(r=this.trigger({phase:"before",target:this.name,type:"validate",errors:i}),r.isCancelled===!0)return i;if(n)for(o in r.errors)f=r.errors[o],$(f.field.el).w2tag(f.error,{"class":"w2ui-error"});return this.trigger($.extend(r,{phase:"after"})),i},request:function(postData,callBack){var obj=this,params,eventData,url;if(typeof postData=="function"&&(callBack=postData,postData=null),(typeof postData=="undefined"||postData==null)&&(postData={}),this.url&&(typeof this.url!="object"||this.url.get)){if((this.recid==null||typeof this.recid=="undefined")&&(this.recid=0),params={},params.cmd="get-record",params.name=this.name,params.recid=this.recid,$.extend(params,this.postData),$.extend(params,postData),eventData=this.trigger({phase:"before",type:"request",target:this.name,url:this.url,postData:params}),eventData.isCancelled===!0)return typeof callBack=="function"&&callBack({status:"error",message:"Request aborted."}),!1;if(this.record={},this.original={},this.lock(this.msgRefresh),url=eventData.url,typeof eventData.url=="object"&&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){var eventData,responseText,data;if(obj.unlock(),eventData=obj.trigger({phase:"before",target:obj.name,type:"load",xhr:xhr,status:status}),eventData.isCancelled===!0)return typeof callBack=="function"&&callBack({status:"error",message:"Request aborted."}),!1;if(responseText=obj.last.xhr.responseText,status!="error"){if(typeof responseText!="undefined"&&responseText!=""){if(typeof responseText=="object")data=responseText;else try{eval("data = "+responseText)}catch(e){}typeof data=="undefined"&&(data={status:"error",message:obj.msgNotJSON,responseText:responseText}),data.status=="error"?obj.error(data.message):(obj.record=$.extend({},data.record),obj.original=$.extend({},data.record))}}else obj.error("AJAX Error "+xhr.status+": "+xhr.statusText);obj.trigger($.extend(eventData,{phase:"after"})),obj.refresh(),typeof callBack=="function"&&callBack(data)}}),this.trigger($.extend(eventData,{phase:"after"}))}},submit:function(n,t){return this.save(n,t)},save:function(postData,callBack){var obj=this,errors;if(typeof postData=="function"&&(callBack=postData,postData=null),errors=obj.validate(!0),errors.length!==0){obj.goto(errors[0].field.page);return}if((typeof postData=="undefined"||postData==null)&&(postData={}),!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+' '),setTimeout(function(){var params={},f,field,tmp,dt,eventData,url;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);for(f in obj.fields){field=obj.fields[f];switch(String(field.type).toLowerCase()){case"date":dt=params.record[field.name],(field.options.format.toLowerCase()=="dd/mm/yyyy"||field.options.format.toLowerCase()=="dd-mm-yyyy"||field.options.format.toLowerCase()=="dd.mm.yyyy")&&(tmp=dt.replace(/-/g,"/").replace(/\./g,"/").split("/"),dt=new Date(tmp[2]+"-"+tmp[1]+"-"+tmp[0])),params.record[field.name]=w2utils.formatDate(dt,"yyyy-mm-dd")}}if(eventData=obj.trigger({phase:"before",type:"submit",target:obj.name,url:obj.url,postData:params}),eventData.isCancelled===!0)return typeof callBack=="function"&&callBack({status:"error",message:"Saving aborted."}),!1;if(url=eventData.url,typeof eventData.url=="object"&&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?obj.recid==0?"POST":"PUT":"POST",url:url,data:String($.param(eventData.postData,!1)).replace(/%5B/g,"[").replace(/%5D/g,"]"),dataType:"text",xhr:function(){var n=new window.XMLHttpRequest;return n.upload.addEventListener("progress",function(n){if(n.lengthComputable){var t=Math.round(n.loaded/n.total*100);$("#"+obj.name+"_progress").text(""+t+"%")}},!1),n},complete:function(xhr,status){var eventData,responseText,data;if(obj.unlock(),eventData=obj.trigger({phase:"before",target:obj.name,type:"save",xhr:xhr,status:status}),eventData.isCancelled===!0)return typeof callBack=="function"&&callBack({status:"error",message:"Saving aborted."}),!1;if(responseText=xhr.responseText,status!="error"){if(typeof responseText!="undefined"&&responseText!=""){if(typeof responseText=="object")data=responseText;else try{eval("data = "+responseText)}catch(e){}typeof data=="undefined"&&(data={status:"error",message:obj.msgNotJSON,responseText:responseText}),data.status=="error"?obj.error(data.message):obj.original=$.extend({},obj.record)}}else obj.error("AJAX Error "+xhr.status+": "+xhr.statusText);obj.trigger($.extend(eventData,{phase:"after"})),obj.refresh(),typeof callBack=="function"&&callBack(data)}}),obj.trigger($.extend(eventData,{phase:"after"}))},50)},lock:function(n,t){var i=$(this.box).find("> div:first-child");w2utils.lock(i,n,t)},unlock:function(){var n=this;setTimeout(function(){w2utils.unlock(n.box)},25)},goto:function(n){typeof n!="undefined"&&(this.page=n),$(this.box).data("auto-size")===!0&&$(this.box).height(0),this.refresh()},generateHTML:function(){var t=[],e,f,n,r,o,i,u;for(e in this.fields)f="",n=this.fields[e],typeof n.html=="undefined"&&(n.html={}),n.html=$.extend(!0,{caption:"",span:6,attr:"",text:"",page:0},n.html),n.html.caption==""&&(n.html.caption=n.name),r='",n.type=="list"&&(r='"),n.type=="checkbox"&&(r='"),n.type=="textarea"&&(r='"),f+='\n
        '+n.html.caption+':
        \n
        '+r+n.html.text+"
        ",typeof t[n.html.page]=="undefined"&&(t[n.html.page]='
        '),t[n.html.page]+=f;for(o in t)t[o]+="\n
        ";if(i="",!$.isEmptyObject(this.actions)){i+='\n
        ';for(u in this.actions)i+='\n ';i+="\n
        "}return t.join("")+i},action:function(n,t){var i=this.trigger({phase:"before",target:n,type:"action",originalEvent:t});if(i.isCancelled===!0)return!1;typeof this.actions[n]=="function"&&this.actions[n].call(this,t),this.trigger($.extend(i,{phase:"after"}))},resize:function(){function o(){s.width($(n.box).width()).height($(n.box).height()),i.css("top",n.header!=""?w2utils.getSize(t,"height"):0),f.css("top",(n.header!=""?w2utils.getSize(t,"height"):0)+(n.toolbar.items.length>0?w2utils.getSize(i,"height"):0)),u.css("top",(n.header!=""?w2utils.getSize(t,"height"):0)+(n.toolbar.items.length>0?w2utils.getSize(i,"height")+5:0)+(n.tabs.tabs.length>0?w2utils.getSize(f,"height")+5:0)),u.css("bottom",r.length>0?w2utils.getSize(r,"height"):0)}var n=this,e=this.trigger({phase:"before",target:this.name,type:"resize"});if(e.isCancelled===!0)return!1;var s=$(this.box).find("> div"),t=$(this.box).find("> div .w2ui-form-header"),i=$(this.box).find("> div .w2ui-form-toolbar"),f=$(this.box).find("> div .w2ui-form-tabs"),u=$(this.box).find("> div .w2ui-page"),h=$(this.box).find("> div .w2ui-page.page-"+this.page),c=$(this.box).find("> div .w2ui-page.page-"+this.page+" > div"),r=$(this.box).find("> div .w2ui-buttons");o(),(parseInt($(this.box).height())==0||$(this.box).data("auto-size")===!0)&&($(this.box).height((t.length>0?w2utils.getSize(t,"height"):0)+(this.tabs.tabs.length>0?w2utils.getSize(f,"height"):0)+(this.toolbar.items.length>0?w2utils.getSize(i,"height"):0)+(u.length>0?w2utils.getSize(c,"height")+w2utils.getSize(h,"+height")+12:0)+(r.length>0?w2utils.getSize(r,"height"):0)),$(this.box).data("auto-size",!0)),o(),n.trigger($.extend(e,{phase:"after"}))},refresh:function(){var i=this,e,f,n,t,u,r;if(this.box&&this.isGenerated&&typeof $(this.box).html()!="undefined"){if($(this.box).find("input, textarea, select").each(function(n,t){var e=typeof $(t).attr("name")!="undefined"?$(t).attr("name"):$(t).attr("id"),f=i.get(e),u,r;if(f&&(u=$(t).parents(".w2ui-page"),u.length>0))for(r=0;r<100;r++)if(u.hasClass("page-"+r)){f.page=r;break}}),e=this.trigger({phase:"before",target:this.name,type:"refresh",page:this.page}),e.isCancelled===!0)return!1;$(this.box).find(".w2ui-page").hide(),$(this.box).find(".w2ui-page.page-"+this.page).show(),$(this.box).find(".w2ui-form-header").html(this.header),typeof this.tabs=="object"&&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(),typeof this.toolbar=="object"&&this.toolbar.items.length>0?($("#form_"+this.name+"_toolbar").show(),this.toolbar.refresh()):$("#form_"+this.name+"_toolbar").hide();for(f in this.fields){n=this.fields[f],n.el=$(this.box).find('[name="'+String(n.name).replace(/\\/g,"\\\\")+'"]')[0],typeof n.el=="undefined"&&console.log('ERROR: Cannot associate field "'+n.name+'" with html control. Make sure html control exists with the same name.'),n.el&&(n.el.id=n.name);$(n.el).off("change").on("change",function(){var r=this.value,s=i.record[this.name]?i.record[this.name]:"",u=i.get(this.name),n,f,t;if((u.type=="enum"||u.type=="upload")&&$(this).data("selected")){var e=$(this).data("selected"),o=i.record[this.name],r=[],s=[];if($.isArray(e))for(n in e)r[n]=$.extend(!0,{},e[n]);if($.isArray(o))for(n in o)s[n]=$.extend(!0,{},o[n])}if(f=i.trigger({phase:"before",target:this.name,type:"change",value_new:r,value_previous:s}),f.isCancelled===!0)return $(this).val(i.record[this.name]),!1;t=this.value,this.type=="checkbox"&&(t=this.checked?!0:!1),this.type=="radio"&&(t=this.checked?!0:!1),u.type=="enum"&&(t=r),u.type=="upload"&&(t=r),i.record[this.name]=t,i.trigger($.extend(f,{phase:"after"}))});n.required?$(n.el).parent().addClass("w2ui-required"):$(n.el).parent().removeClass("w2ui-required")}$(this.box).find("button, input[type=button]").each(function(n,t){$(t).off("click").on("click",function(n){var t=this.value;this.name&&(t=this.name),this.id&&(t=this.id),i.action(t,n)})});for(f in this.fields)if(n=this.fields[f],t=typeof this.record[n.name]!="undefined"?this.record[n.name]:"",n.el)switch(String(n.type).toLowerCase()){case"email":case"text":case"textarea":n.el.value=t;break;case"date":n.options||(n.options={}),n.options.format||(n.options.format=w2utils.settings.date_format),n.el.value=t,this.record[n.name]=t,$(n.el).w2field($.extend({},n.options,{type:"date"}));break;case"int":n.el.value=t,$(n.el).w2field("int");break;case"float":n.el.value=t,$(n.el).w2field("float");break;case"money":n.el.value=t,$(n.el).w2field("money");break;case"hex":n.el.value=t,$(n.el).w2field("hex");break;case"alphanumeric":n.el.value=t,$(n.el).w2field("alphaNumeric");break;case"checkbox":this.record[n.name]==!0||this.record[n.name]==1||this.record[n.name]=="t"?$(n.el).prop("checked",!0):$(n.el).prop("checked",!1);break;case"password":n.el.value=t;break;case"select":case"list":$(n.el).w2field($.extend({},n.options,{type:"list",value:t}));break;case"enum":if(typeof n.options=="undefined"||typeof n.options.url=="undefined"&&typeof n.options.items=="undefined"){console.log("ERROR: (w2form."+i.name+") the field "+n.name+" defined as enum but not field.options.url or field.options.items provided.");break}this.record[n.name]=w2obj.field.cleanItems(t),t=this.record[n.name],$(n.el).w2field($.extend({},n.options,{type:"enum",selected:t}));break;case"upload":$(n.el).w2field($.extend({},n.options,{type:"upload",selected:t}));break;default:console.log('ERROR: field type "'+n.type+'" is not recognized.')}for(u=$(this.box).find(".w2ui-page"),r=0;r *").length>1&&$(u[r]).wrapInner("
        ");this.trigger($.extend(e,{phase:"after"})),this.resize()}},render:function(n){function f(){var n=$(t.box).find("input, select, textarea");n.length>t.focus&&n[t.focus].focus()}var t=this,i,u,r;if(typeof n=="object"&&($(this.box).find("#form_"+this.name+"_tabs").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-form").html(""),this.box=n),this.isGenerated){if(i=this.trigger({phase:"before",target:this.name,type:"render",box:typeof n!="undefined"?n:this.box}),i.isCancelled===!0)return!1;if(u="
        "+(this.header!=""?'
        '+this.header+"
        ":"")+'\t
        \t
        '+this.formHTML+"
        ",$(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-form").html(u),$(this.box).length>0&&($(this.box)[0].style.cssText+=this.style),typeof this.toolbar.render=="undefined"){this.toolbar=$().w2toolbar($.extend({},this.toolbar,{name:this.name+"_toolbar",owner:this}));this.toolbar.on("click",function(n){var i=t.trigger({phase:"before",type:"toolbar",target:n.target,originalEvent:n});if(i.isCancelled===!0)return!1;t.trigger($.extend(i,{phase:"after"}))})}if(typeof this.toolbar=="object"&&typeof this.toolbar.render=="function"&&this.toolbar.render($("#form_"+this.name+"_toolbar")[0]),typeof this.tabs.render=="undefined"){this.tabs=$().w2tabs($.extend({},this.tabs,{name:this.name+"_tabs",owner:this}));this.tabs.on("click",function(n){t.goto(this.get(n.target,!0))})}if(typeof this.tabs=="object"&&typeof this.tabs.render=="function"&&this.tabs.render($("#form_"+this.name+"_tabs")[0]),this.trigger($.extend(i,{phase:"after"})),this.resize(),r=typeof this.url!="object"?this.url:this.url.get,r&&this.recid!=0?this.request():this.refresh(),$(".w2ui-layout").length==0){this.tmp_resize=function(){w2ui[t.name].resize()};$(window).off("resize","body").on("resize","body",this.tmp_resize)}setTimeout(function(){t.resize(),t.refresh()},150),this.focus>=0&&setTimeout(f,500)}},destroy:function(){var n=this.trigger({phase:"before",target:this.name,type:"destroy"});if(n.isCancelled===!0)return!1;typeof this.toolbar=="object"&&this.toolbar.destroy&&this.toolbar.destroy(),typeof this.tabs=="object"&&this.tabs.destroy&&this.tabs.destroy(),$(this.box).find("#form_"+this.name+"_tabs").length>0&&$(this.box).removeAttr("name").removeClass("w2ui-reset w2ui-form").html(""),delete w2ui[this.name],this.trigger($.extend(n,{phase:"after"})),$(window).off("resize","body")}},$.extend(w2form.prototype,w2utils.event),w2obj.form=w2form}(jQuery); \ No newline at end of file +var w2ui=w2ui||{},w2obj=w2obj||{},w2utils=function(n){function i(n){var t=/^[-+]?[0-9]+$/;return t.test(n)}function r(n){return typeof n=="string"&&(n=n.replace(w2utils.settings.decimalSymbol,".")),(typeof n=="number"||typeof n=="string"&&n!=="")&&!isNaN(Number(n))}function u(n){var t=w2utils.settings,i=new RegExp("^"+(t.currencyPrefix?"\\"+t.currencyPrefix+"?":"")+"[-+]?[0-9]*[\\"+w2utils.settings.decimalSymbol+"]?[0-9]+"+(t.currencySuffix?"\\"+t.currencySuffix+"?":"")+"$","i");return(typeof n=="string"&&(n=n.replace(new RegExp(t.groupSymbol,"g"),"")),typeof n=="object"||n==="")?!1:i.test(n)}function f(n){return/^[a-fA-F0-9]+$/.test(n)}function e(n){return/^[a-zA-Z0-9_-]+$/.test(n)}function o(n){return/^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(n)}function s(n,t,r){var h,f,e,o,c,a,l,u,s;if(!n)return!1;if(h="Invalid Date",t==null&&(t=w2utils.settings.date_format),typeof n.getUTCFullYear=="function"&&typeof n.getUTCMonth=="function"&&typeof n.getUTCDate=="function")o=n.getUTCFullYear(),f=n.getUTCMonth(),e=n.getUTCDate();else if(typeof n.getFullYear=="function"&&typeof n.getMonth=="function"&&typeof n.getDate=="function")o=n.getFullYear(),f=n.getMonth(),e=n.getDate();else{if(n=String(n),RegExp("mon","ig").test(t))for(t=t.replace(/month/ig,"m").replace(/mon/ig,"m").replace(/dd/ig,"d").replace(/[, ]/ig,"/").replace(/\/\//g,"/").toLowerCase(),n=n.replace(/[, ]/ig,"/").replace(/\/\//g,"/").toLowerCase(),c=0,a=w2utils.settings.fullmonths.length;c=0;f=s||t.indexOf("AM")>=0;o=f?12:24;t=t.replace("AM","").replace("PM","");t=n.trim(t);var r=t.split(":"),u=parseInt(r[0]||0),e=parseInt(r[1]||0);return(!f||r.length!==1)&&r.length!==2?!1:r[0]===""||u<0||u>o||!this.isInt(r[0])||r[0].length>2?!1:r.length===2&&(r[1]===""||e<0||e>59||!this.isInt(r[1])||r[1].length!==2)?!1:!f&&o===u&&e!==0?!1:f&&r.length===1&&u===0?!1:i===!0?(s&&(u+=12),{hours:u,minutes:e}):!0}function c(n){var u;if(n===""||n==null||(u=new Date(n),w2utils.isInt(n)&&(u=new Date(Number(n))),u==="Invalid Date"))return"";var f=new Date,t=(f.getTime()-u.getTime())/1e3,i="",r="";return t<0?(i='future<\/span>',r=""):t<60?(i=Math.floor(t),r="sec",t<0&&(i=0,r="sec")):t<3600?(i=Math.floor(t/60),r="min"):t<86400?(i=Math.floor(t/3600),r="hour"):t<2592e3?(i=Math.floor(t/86400),r="day"):t<365.25*86400?(i=Math.floor(t/365.25/8640)/10,r="month"):t>=365.25*86400&&(i=Math.floor(t/365.25/8640)/10,r="year"),i+" "+r+(i>1?"s":"")}function l(n){var t;if(n===""||n==null||(t=new Date(n),w2utils.isInt(n)&&(t=new Date(Number(n))),t==="Invalid Date"))return"";var u=w2utils.settings.shortmonths,f=new Date,i=new Date;i.setTime(i.getTime()-864e5);var r=u[t.getMonth()]+" "+t.getDate()+", "+t.getFullYear(),o=u[f.getMonth()]+" "+f.getDate()+", "+f.getFullYear(),s=u[i.getMonth()]+" "+i.getDate()+", "+i.getFullYear(),h=t.getHours()-(t.getHours()>12?12:0)+":"+(t.getMinutes()<10?"0":"")+t.getMinutes()+" "+(t.getHours()>=12?"pm":"am"),c=t.getHours()-(t.getHours()>12?12:0)+":"+(t.getMinutes()<10?"0":"")+t.getMinutes()+":"+(t.getSeconds()<10?"0":"")+t.getSeconds()+" "+(t.getHours()>=12?"pm":"am"),e=r;return r===o&&(e=h),r===s&&(e=w2utils.lang("Yesterday")),''+e+"<\/span>"}function a(n){if(!w2utils.isFloat(n)||n==="")return"";if(n=parseFloat(n),n===0)return 0;var t=parseInt(Math.floor(Math.log(n)/Math.log(1024)));return(Math.floor(n/Math.pow(1024,t)*10)/10).toFixed(t===0?0:1)+" "+["Bt","KB","MB","GB","TB"][t]}function v(n,i,r){var u="";return i==null&&(i=w2utils.settings.groupSymbol||","),r==null&&(r=w2utils.settings.decimalSymbol||"."),(w2utils.isFloat(n)||w2utils.isInt(n)||w2utils.isMoney(n))&&(t=String(n).split("."),u=String(t[0]).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1"+i),t[1]!=null&&(u+=w2utils.settings.decimalSymbol+t[1])),u}function y(n,t){var e=w2utils.settings.shortmonths,o=w2utils.settings.fullmonths,i;if((t||(t=this.settings.date_format),n===""||n==null||typeof n=="object"&&!n.getMonth)||(i=new Date(n),w2utils.isInt(n)&&(i=new Date(Number(n))),i==="Invalid Date"))return"";var r=i.getFullYear(),f=i.getMonth(),u=i.getDate();return t.toLowerCase().replace("month",w2utils.settings.fullmonths[f]).replace("mon",w2utils.settings.shortmonths[f]).replace(/yyyy/g,r).replace(/yyy/g,r).replace(/yy/g,r>2e3?100+parseInt(String(r).substr(2)):String(r).substr(2)).replace(/(^|[^a-z$])y/g,"$1"+r).replace(/mm/g,(f+1<10?"0":"")+(f+1)).replace(/dd/g,(u<10?"0":"")+u).replace(/th/g,u==1?"st":"th").replace(/th/g,u==2?"nd":"th").replace(/th/g,u==3?"rd":"th").replace(/(^|[^a-z$])m/g,"$1"+(f+1)).replace(/(^|[^a-z$])d/g,"$1"+u)}function p(n,t){var h=w2utils.settings.shortmonths,c=w2utils.settings.fullmonths,i,o;if((t||(t=this.settings.time_format),n===""||n==null||typeof n=="object"&&!n.getMonth)||(i=new Date(n),w2utils.isInt(n)&&(i=new Date(Number(n))),w2utils.isTime(n)&&(o=w2utils.isTime(n,!0),i=new Date,i.setHours(o.hours),i.setMinutes(o.minutes)),i==="Invalid Date"))return"";var s="am",r=i.getHours(),e=i.getHours(),u=i.getMinutes(),f=i.getSeconds();return u<10&&(u="0"+u),f<10&&(f="0"+f),(t.indexOf("am")!==-1||t.indexOf("pm")!==-1)&&(r>=12&&(s="pm"),r>12&&(r=r-12)),t.toLowerCase().replace("am",s).replace("pm",s).replace("hhh",r<10?"0"+r:r).replace("hh24",e<10?"0"+e:e).replace("h24",e).replace("hh",r).replace("mm",u).replace("mi",u).replace("ss",f).replace(/(^|[^a-z$])h/g,"$1"+r).replace(/(^|[^a-z$])m/g,"$1"+u).replace(/(^|[^a-z$])s/g,"$1"+f)}function w(n,t){var i;return n===""||n==null||typeof n=="object"&&!n.getMonth?"":(i=typeof t!="string"?[this.settings.date_format,this.settings.time_format]:t.split("|"),this.formatDate(n,i[0])+" "+this.formatTime(n,i[1]))}function b(t){if(t===null)return t;switch(typeof t){case"string":t=n.trim(String(t).replace(/(<([^>]+)>)/ig,""));break;case"object":for(var i in t)t[i]=this.stripTags(t[i])}return t}function k(n){if(n===null)return n;switch(typeof n){case"string":n=String(n).replace(/&/g,"&").replace(/>/g,">").replace(/\|\/? {}\\])/g,"\\$1")}function g(n){function l(n){for(var t,n=String(n).replace(/\r\n/g,"\n"),i="",r=0;r127&&t<2048?(i+=String.fromCharCode(t>>6|192),i+=String.fromCharCode(t&63|128)):(i+=String.fromCharCode(t>>12|224),i+=String.fromCharCode(t>>6&63|128),i+=String.fromCharCode(t&63|128));return i}var e="",o,t,i,h,c,s,r,u=0,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";for(n=l(n);u>2,c=(o&3)<<4|t>>4,s=(t&15)<<2|i>>6,r=i&63,isNaN(t)?s=r=64:isNaN(i)&&(r=64),e=e+f.charAt(h)+f.charAt(c)+f.charAt(s)+f.charAt(r);return e}function nt(n){function l(n){for(var r="",t=0,i=0,u,f;t191&&i<224?(u=n.charCodeAt(t+1),r+=String.fromCharCode((i&31)<<6|u&63),t+=2):(u=n.charCodeAt(t+1),f=n.charCodeAt(t+2),r+=String.fromCharCode((i&15)<<12|(u&63)<<6|f&63),t+=3);return r}var t="",o,s,h,c,f,r,e,i=0,u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";for(n=n.replace(/[^A-Za-z0-9\+\/\=]/g,"");i>4,s=(f&15)<<4|r>>2,h=(r&3)<<6|e,t=t+String.fromCharCode(o),r!==64&&(t=t+String.fromCharCode(s)),e!==64&&(t=t+String.fromCharCode(h));return l(t)}function tt(t,i,r,u){function f(n,t,i){var r=!!window.webkitURL;return r||typeof i=="undefined"||(t=i),";"+n+": "+t+"; -webkit-"+n+": "+t+"; -moz-"+n+": "+t+"; -ms-"+n+": "+t+"; -o-"+n+": "+t+";"}var o=n(t).width(),s=n(t).height(),e=.5;if(!t||!i){console.log("ERROR: Cannot do transition when one of the divs is null");return}t.parentNode.style.cssText+=f("perspective","700px")+"; overflow: hidden;";t.style.cssText+="; position: absolute; z-index: 1019; "+f("backface-visibility","hidden");i.style.cssText+="; position: absolute; z-index: 1020; "+f("backface-visibility","hidden");switch(r){case"slide-left":t.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");i.style.cssText+="overflow: hidden; "+f("transform","translate3d("+o+"px, 0, 0)","translate("+o+"px, 0)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+";"+f("transform","translate3d(0, 0, 0)","translate(0, 0)");t.style.cssText+=f("transition",e+"s")+";"+f("transform","translate3d(-"+o+"px, 0, 0)","translate(-"+o+"px, 0)")},1);break;case"slide-right":t.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");i.style.cssText+="overflow: hidden; "+f("transform","translate3d(-"+o+"px, 0, 0)","translate(-"+o+"px, 0)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","translate3d(0px, 0, 0)","translate(0px, 0)");t.style.cssText+=f("transition",e+"s")+"; "+f("transform","translate3d("+o+"px, 0, 0)","translate("+o+"px, 0)")},1);break;case"slide-down":t.style.cssText+="overflow: hidden; z-index: 1; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");i.style.cssText+="overflow: hidden; z-index: 0; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");t.style.cssText+=f("transition",e+"s")+"; "+f("transform","translate3d(0, "+s+"px, 0)","translate(0, "+s+"px)")},1);break;case"slide-up":t.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");i.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, "+s+"px, 0)","translate(0, "+s+"px)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");t.style.cssText+=f("transition",e+"s")+"; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)")},1);break;case"flip-left":t.style.cssText+="overflow: hidden; "+f("transform","rotateY(0deg)");i.style.cssText+="overflow: hidden; "+f("transform","rotateY(-180deg)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateY(0deg)");t.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateY(180deg)")},1);break;case"flip-right":t.style.cssText+="overflow: hidden; "+f("transform","rotateY(0deg)");i.style.cssText+="overflow: hidden; "+f("transform","rotateY(180deg)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateY(0deg)");t.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateY(-180deg)")},1);break;case"flip-down":t.style.cssText+="overflow: hidden; "+f("transform","rotateX(0deg)");i.style.cssText+="overflow: hidden; "+f("transform","rotateX(180deg)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateX(0deg)");t.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateX(-180deg)")},1);break;case"flip-up":t.style.cssText+="overflow: hidden; "+f("transform","rotateX(0deg)");i.style.cssText+="overflow: hidden; "+f("transform","rotateX(-180deg)");n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateX(0deg)");t.style.cssText+=f("transition",e+"s")+"; "+f("transform","rotateX(180deg)")},1);break;case"pop-in":t.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");i.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; "+f("transform","scale(.8)")+"; opacity: 0;";n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; "+f("transform","scale(1)")+"; opacity: 1;";t.style.cssText+=f("transition",e+"s")+";"},1);break;case"pop-out":t.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; "+f("transform","scale(1)")+"; opacity: 1;";i.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; opacity: 0;";n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; opacity: 1;";t.style.cssText+=f("transition",e+"s")+"; "+f("transform","scale(1.7)")+"; opacity: 0;"},1);break;default:t.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)");i.style.cssText+="overflow: hidden; "+f("transform","translate3d(0, 0, 0)","translate(0, 0)")+"; opacity: 0;";n(i).show();window.setTimeout(function(){i.style.cssText+=f("transition",e+"s")+"; opacity: 1;";t.style.cssText+=f("transition",e+"s")},1)}setTimeout(function(){r==="slide-down"&&(n(t).css("z-index","1019"),n(i).css("z-index","1020"));i&&n(i).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":""});t&&(n(t).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":""}),t.parentNode&&n(t.parentNode).css({"-webkit-perspective":"","-moz-perspective":"","-ms-perspective":"","-o-perspective":""}));typeof u=="function"&&u()},e*1e3)}function it(t,i,r){var u={},f,e;typeof i=="object"?u=i:(u.msg=i,u.spinner=r);u.msg||u.msg===0||(u.msg="");w2utils.unlock(t);n(t).prepend('
        <\/div>
        <\/div>');f=n(t).find(".w2ui-lock");e=n(t).find(".w2ui-lock-msg");u.msg||e.css({"background-color":"transparent",border:"0px"});u.spinner===!0&&(u.msg='
        <\/div>"+u.msg);u.opacity!=null&&f.css("opacity",u.opacity);typeof f.fadeIn=="function"?(f.fadeIn(200),e.html(u.msg).fadeIn(200)):(f.show(),e.html(u.msg).show(0));n().w2tag()}function rt(t){n(t).find(".w2ui-lock").remove();n(t).find(".w2ui-lock-msg").remove()}function ut(t,i){var r=n(t),u={left:parseInt(r.css("border-left-width"))||0,right:parseInt(r.css("border-right-width"))||0,top:parseInt(r.css("border-top-width"))||0,bottom:parseInt(r.css("border-bottom-width"))||0},f={left:parseInt(r.css("margin-left"))||0,right:parseInt(r.css("margin-right"))||0,top:parseInt(r.css("margin-top"))||0,bottom:parseInt(r.css("margin-bottom"))||0},e={left:parseInt(r.css("padding-left"))||0,right:parseInt(r.css("padding-right"))||0,top:parseInt(r.css("padding-top"))||0,bottom:parseInt(r.css("padding-bottom"))||0};switch(i){case"top":return u.top+f.top+e.top;case"bottom":return u.bottom+f.bottom+e.bottom;case"left":return u.left+f.left+e.left;case"right":return u.right+f.right+e.right;case"width":return u.left+u.right+f.left+f.right+e.left+e.right+parseInt(r.width());case"height":return u.top+u.bottom+f.top+f.bottom+e.top+e.bottom+parseInt(r.height());case"+width":return u.left+u.right+f.left+f.right+e.left+e.right;case"+height":return u.top+u.bottom+f.top+f.bottom+e.top+e.bottom}return 0}function ft(n){var t=this.settings.phrases[n];return t==null?n:t}function et(t){t||(t="en-us");t.length===5&&(t="locale/"+t+".json");n.ajax({url:t,type:"GET",dataType:"JSON",async:!1,cache:!1,success:function(t){var i,r;w2utils.settings=n.extend(!0,w2utils.settings,t);i=w2obj.grid.prototype;for(r in i.buttons)i.buttons[r].caption=w2utils.lang(i.buttons[r].caption),i.buttons[r].hint=w2utils.lang(i.buttons[r].hint);i.msgDelete=w2utils.lang(i.msgDelete);i.msgNotJSON=w2utils.lang(i.msgNotJSON);i.msgRefresh=w2utils.lang(i.msgRefresh)},error:function(){console.log("ERROR: Cannot load locale "+t)}})}function ot(){if(t.scrollBarSize)return t.scrollBarSize;return n("body").append('
        1<\/div><\/div>'),t.scrollBarSize=100-n("#_scrollbar_width > div").width(),n("#_scrollbar_width").remove(),String(navigator.userAgent).indexOf("MSIE")>=0&&(t.scrollBarSize=t.scrollBarSize/2),t.scrollBarSize}function st(n,t){return!n||typeof n.name=="undefined"?(console.log('ERROR: The parameter "name" is required but not supplied in $().'+t+"()."),!1):typeof w2ui[n.name]!="undefined"?(console.log('ERROR: The parameter "name" is not unique. There are other objects already created with the same name (obj: '+n.name+")."),!1):w2utils.isAlphaNumeric(n.name)?!0:(console.log('ERROR: The parameter "name" has to be alpha-numeric (a-z, 0-9, dash and underscore). '),!1)}function ht(t,i,r,u){n.isArray(i)||(i=[i]);for(var f=0;f=0;e--)if(t=this.handlers[e],(t.event.type===n.type||t.event.type==="*")&&(t.event.target===n.target||t.event.target===null)&&(t.event.execute===n.phase||t.event.execute==="*"||t.event.phase==="*")&&(n=jQuery.extend({},t.event,n),i=[],r=RegExp(/\((.*?)\)/).exec(t.handler),r&&(i=r[1].split(/\s*,\s*/)),i.length===2?t.handler.call(this,n.target,n):t.handler.call(this,n),n.isStopped===!0||n.stop===!0))return n;return(f="on"+n.type.substr(0,1).toUpperCase()+n.type.substr(1),n.phase==="before"&&typeof this[f]=="function"&&(u=this[f],i=[],r=RegExp(/\((.*?)\)/).exec(u),r&&(i=r[1].split(/\s*,\s*/)),i.length===2?u.call(this,n.target,n):u.call(this,n),n.isStopped===!0||n.stop===!0))?n:n.object!=null&&n.phase==="before"&&typeof n.object[f]=="function"&&(u=n.object[f],i=[],r=RegExp(/\((.*?)\)/).exec(u),r&&(i=r[1].split(/\s*,\s*/)),i.length===2?u.call(this,n.target,n):u.call(this,n),n.isStopped===!0||n.stop===!0)?n:(n.phase==="after"&&typeof n.onComplete=="function"&&n.onComplete.call(this,n),n)}};w2utils.keyboard=function(n){function i(){jQuery(document).on("keydown",r);jQuery(document).on("mousedown",u)}function r(n){var i=n.target.tagName;jQuery.inArray(i,["INPUT","SELECT","TEXTAREA"])===-1&&jQuery(n.target).prop("contenteditable")!=="true"&&t&&w2ui[t]&&typeof w2ui[t].keydown=="function"&&w2ui[t].keydown.call(w2ui[t],n)}function u(n){var u=n.target.tagName,r=jQuery(n.target).parents(".w2ui-reset"),i;r.length>0&&(i=r.attr("name"),w2ui[i]&&w2ui[i].keyboard&&(t=i))}function f(n){return typeof n!="undefined"&&(t=n),t}function e(){t=null}var t=null;return n.active=f,n.clear=e,i(),n}({}),function(n){n.fn.w2render=function(t){n(this).length>0&&(typeof t=="string"&&w2ui[t]&&w2ui[t].render(n(this)[0]),typeof t=="object"&&t.render(n(this)[0]))};n.fn.w2destroy=function(n){!n&&this.length>0&&(n=this.attr("name"));typeof n=="string"&&w2ui[n]&&w2ui[n].destroy();typeof n=="object"&&n.destroy()};n.fn.w2marker=function(t){return t===""||t==null?n(this).each(function(n,t){t.innerHTML=t.innerHTML.replace(/\(.*)\<\/span\>/ig,"$1")}):n(this).each(function(n,i){function e(n){return''+n+"<\/span>"}var u,r,f;typeof t=="string"&&(t=[t]);i.innerHTML=i.innerHTML.replace(/\(.*)\<\/span\>/ig,"$1");for(u in t)r=t[u],typeof r!="string"&&(r=String(r)),r=r.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&").replace(/&/g,"&").replace(//g,"<"),f=new RegExp(r+"(?!([^<]+)?>)","gi"),i.innerHTML=i.innerHTML.replace(f,e)})};n.fn.w2tag=function(t,i){if(n.isPlainObject(i)||(i={}),n.isPlainObject(i.css)||(i.css={}),typeof i["class"]=="undefined"&&(i["class"]=""),n(this).length===0){n(".w2ui-tag").each(function(t,i){var r=n(i).data("options");r==null&&(r={});n(n(i).data("taged-el")).removeClass(r["class"]);clearInterval(n(i).data("timer"));n(i).remove()});return}return n(this).each(function(r,u){var h=u.id,f=w2utils.escapeId(u.id),s,o;if(t===""||t==null)n("#w2ui-tag-"+f).css("opacity",0),setTimeout(function(){clearInterval(n("#w2ui-tag-"+f).data("timer"));n("#w2ui-tag-"+f).remove()},300);else{clearInterval(n("#w2ui-tag-"+f).data("timer"));n("#w2ui-tag-"+f).remove();n("body").append('
        0?"w2ui-tag-popup":"")+'" style=""><\/div>');s=setInterval(function(){if(n(u).length===0||n(u).offset().left===0&&n(u).offset().top===0){clearInterval(n("#w2ui-tag-"+f).data("timer"));e();return}n("#w2ui-tag-"+f).data("position")!==n(u).offset().left+u.offsetWidth+"x"+n(u).offset().top&&n("#w2ui-tag-"+f).css({"-webkit-transition":".2s","-moz-transition":".2s","-ms-transition":".2s","-o-transition":".2s",left:n(u).offset().left+u.offsetWidth+"px",top:n(u).offset().top+"px"}).data("position",n(u).offset().left+u.offsetWidth+"x"+n(u).offset().top)},100);setTimeout(function(){n(u).offset()&&(n("#w2ui-tag-"+f).css({opacity:"1",left:n(u).offset().left+u.offsetWidth+"px",top:n(u).offset().top+"px"}).html('
        '+t+"<\/div> <\/div>").data("text",t).data("taged-el",u).data("options",i).data("position",n(u).offset().left+u.offsetWidth+"x"+n(u).offset().top).data("timer",s),n(u).off("keypress",e).on("keypress",e).off("change",e).on("change",e).css(i.css).addClass(i["class"]),typeof i.onShow=="function"&&i.onShow())},1);o="";n(u).length>0&&(o=n(u)[0].style.cssText);function e(){($tag=n("#w2ui-tag-"+f),$tag.length<=0)||(clearInterval($tag.data("timer")),$tag.remove(),n(u).off("keypress",e).removeClass(i["class"]),n(u).length>0&&(n(u)[0].style.cssText=o),typeof i.onHide=="function"&&i.onHide())}}})};n.fn.w2overlay=function(t,i){function l(){var t=n("#w2ui-overlay"+r),i;t.data("element")===u[0]&&t.length!==0&&(i=n(u).offset().left+"x"+n(u).offset().top,t.data("position")!==i?s():setTimeout(l,250))}function s(){var t=n("#w2ui-overlay"+r),u;if(t.data("keepOpen")===!0){t.removeData("keepOpen");return}(typeof i.onHide=="function"&&(u=i.onHide()),u!==!1)&&(t.remove(),n(document).off("click",s),clearInterval(t.data("timer")))}function h(){var o=n("#w2ui-overlay"+r),t=o.find(" > div"),e,l;if(o.length>0){t.height("auto").width("auto");var a=!1,s=t.height(),f=t.width();i.width&&i.widtht.find("div.menu > table").height()&&t.find("div.menu").css("overflow-y","hidden")},1),setTimeout(function(){t.find("div.menu").css("overflow-y","auto")},10));i.tmp.contentWidth&&(f=i.tmp.contentWidth,t.width(f),setTimeout(function(){t.width()>t.find("div.menu > table").width()&&t.find("div.menu").css("overflow-x","hidden")},1),setTimeout(function(){t.find("div.menu").css("overflow-y","auto")},10));switch(i.align){case"both":i.left=17;i.width===0&&(i.width=w2utils.getSize(n(u),"width"));break;case"left":i.left=17;break;case"right":i.tipLeft=f-45;i.left=w2utils.getSize(n(u),"width")-f+10}var v=(f-17)/2,p=i.left,y=i.width,c=i.tipLeft;y=f!==30||y?i.width?i.width:"auto":30;v<25&&(p=25-v,c=Math.floor(v));o.css({top:u.offset().top+w2utils.getSize(u,"height")+i.top+7+"px",left:(u.offset().left>25?u.offset().left:25)+p+"px","min-width":y,"min-height":i.height?i.height:"auto"});e=window.innerHeight+n(document).scrollTop()-t.offset().top-7;l=window.innerWidth+n(document).scrollLeft()-t.offset().left-7;e>-50&&e<210||i.openAbove===!0?(e=t.offset().top-n(document).scrollTop()-7,i.maxHeight&&e>i.maxHeight&&(e=i.maxHeight),s>e&&(a=!0,t.height(e).width(f).css({"overflow-y":"auto"}),s=e),o.css("top",n(u).offset().top-s-24+i.top+"px"),o.find(">style").html("#w2ui-overlay"+r+":before { display: none; margin-left: "+parseInt(c)+"px; }#w2ui-overlay"+r+":after { display: block; margin-left: "+parseInt(c)+"px; }")):(i.maxHeight&&e>i.maxHeight&&(e=i.maxHeight),s>e&&(a=!0,t.height(e).width(f).css({"overflow-y":"auto"})),o.find(">style").html("#w2ui-overlay"+r+":before { display: block; margin-left: "+parseInt(c)+"px; }#w2ui-overlay"+r+":after { display: none; margin-left: "+parseInt(c)+"px; }"));f=t.width();l=window.innerWidth+n(document).scrollLeft()-t.offset().left-7;i.maxWidth&&l>i.maxWidth&&(l=i.maxWidth);f>l&&i.align!=="both"&&(i.align="right",setTimeout(function(){h()},1));a&&!1&&t.width(f+w2utils.scrollBarSize()+2)}}var u=this,r="",f,e,c,o;if(arguments.length==1&&(i=typeof t=="object"?t:{html:t}),arguments.length==2&&(i.html=t),n.isPlainObject(i)||(i={}),i=n.extend({},{name:null,html:"",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:{}},i),i.name&&(r="-"+i.name),this.length===0||i.html===""||i.html==null)return n("#w2ui-overlay"+r).length>0?(f=n("#w2ui-overlay"+r)[0].hide,typeof f=="function"&&f()):n("#w2ui-overlay"+r).remove(),n(this);n("#w2ui-overlay"+r).length>0&&(f=n("#w2ui-overlay"+r)[0].hide,n(document).off("click",f),typeof f=="function"&&f());n("body").append('