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('