// Production steps of ECMA-262, Edition 5, 15.4.4.14 // Reference: http://es5.github.io/#x15.4.4.14 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (searchElement, fromIndex) { var k; // 1. Let o be the result of calling ToObject passing // the this value as the argument. if (this == null) { throw new TypeError("\"this\" is null or not defined"); } var o = Object(this); // 2. Let lenValue be the result of calling the Get // internal method of o with the argument "length". // 3. Let len be ToUint32(lenValue). var len = o.length >>> 0; // 4. If len is 0, return -1. if (len === 0) { return -1; } // 5. If argument fromIndex was passed let n be // ToInteger(fromIndex); else let n be 0. var n = fromIndex | 0; // 6. If n >= len, return -1. if (n >= len) { return -1; } // 7. If n >= 0, then Let k be n. // 8. Else, n<0, Let k be len - abs(n). // If k is less than 0, then let k be 0. k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); // 9. Repeat, while k < len while (k < len) { // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the // HasProperty internal method of o with argument Pk. // This step can be combined with c // c. If kPresent is true, then // i. Let elementK be the result of calling the Get // internal method of o with the argument ToString(k). // ii. Let same be the result of applying the // Strict Equality Comparison Algorithm to // searchElement and elementK. // iii. If same is true, return k. if (k in o && o[k] === searchElement) { return k; } k++; } return -1; }; } if (!Array.prototype.lastIndexOf) { Array.prototype.lastIndexOf = function (searchElement /* , fromIndex*/) { "use strict"; if (this === void 0 || this === null) { throw new TypeError(); } var n, k, t = Object(this), len = t.length >>> 0; if (len === 0) { return -1; } n = len - 1; if (arguments.length > 1) { n = Number(arguments[1]); if (n != n) { n = 0; } else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } } for (k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k >= 0; k--) { if (k in t && t[k] === searchElement) { return k; } } return -1; }; } /** * 特殊情况 * Created by wang on 15/6/23. */ // 解决console未定义问题 guy window.console = window.console || (function () { var c = {}; c.log = c.warn = c.debug = c.info = c.error = c.time = c.dir = c.profile = c.clear = c.exception = c.trace = c.assert = function () { }; return c; })(); /* * 前端缓存 */ window.localStorage || (window.localStorage = { items: {}, setItem: function (k, v) { BI.Cache.addCookie(k, v); }, getItem: function (k) { return BI.Cache.getCookie(k); }, removeItem: function (k) { BI.Cache.deleteCookie(k); }, key: function () { }, clear: function () { this.items = {}; } });if (typeof Set !== "undefined" && Set.toString().match(/native code/)) { } else { Set = function () { this.set = {}; }; Set.prototype.has = function (key) { return this.set[key] !== undefined; }; Set.prototype.add = function (key) { this.set[key] = 1; }; Set.prototype.clear = function () { this.set = {}; }; }// 修复ie9下sort方法的bug !function (window) { var ua = window.navigator.userAgent.toLowerCase(), reg = /msie|applewebkit.+safari/; if (reg.test(ua)) { var _sort = Array.prototype.sort; Array.prototype.sort = function (fn) { if (!!fn && typeof fn === "function") { if (this.length < 2) { return this; } var i = 0, j = i + 1, l = this.length, tmp, r = false, t = 0; for (; i < l; i++) { for (j = i + 1; j < l; j++) { t = fn.call(this, this[i], this[j]); r = (typeof t === "number" ? t : t ? 1 : 0) > 0; if (r === true) { tmp = this[i]; this[i] = this[j]; this[j] = tmp; } } } return this; } return _sort.call(this); }; } }(window);/*! * jQuery JavaScript Library v1.9.1 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2013-2-4 */ (function( window, undefined ) { // Can't do this because several apps including ASP.NET trace // the stack via arguments.caller.callee and Firefox dies if // you try to trace through "use strict" call chains. (#13335) // Support: Firefox 18+ //"use strict"; var // The deferred used on DOM ready readyList, // A central reference to the root jQuery(document) rootjQuery, // Support: IE<9 // For `typeof node.method` instead of `node.method !== undefined` core_strundefined = typeof undefined, // Use the correct document accordingly with window argument (sandbox) document = window.document, location = window.location, // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, // [[Class]] -> type pairs class2type = {}, // List of deleted data cache ids, so we can reuse them core_deletedIds = [], core_version = "1.9.1", // Save a reference to some core methods core_concat = core_deletedIds.concat, core_push = core_deletedIds.push, core_slice = core_deletedIds.slice, core_indexOf = core_deletedIds.indexOf, core_toString = class2type.toString, core_hasOwn = class2type.hasOwnProperty, core_trim = core_version.trim, // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); }, // Used for matching numbers core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, // Used for splitting on whitespace core_rnotwhite = /\S+/g, // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, // Match a standalone tag rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, // JSON RegExp rvalidchars = /^[\],:{}\s]*$/, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, // Matches dashed string for camelizing rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, // Used by jQuery.camelCase as callback to replace() fcamelCase = function( all, letter ) { return letter.toUpperCase(); }, // The ready event handler completed = function( event ) { // readyState === "complete" is good enough for us to call the dom ready in oldIE if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { detach(); jQuery.ready(); } }, // Clean-up method for dom ready events detach = function() { if ( document.addEventListener ) { document.removeEventListener( "DOMContentLoaded", completed, false ); window.removeEventListener( "load", completed, false ); } else { document.detachEvent( "onreadystatechange", completed ); window.detachEvent( "onload", completed ); } }; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: core_version, constructor: jQuery, init: function( selector, context, rootjQuery ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Handle HTML strings if ( typeof selector === "string" ) { if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } // Match html or make sure no context is specified for #id if ( match && (match[1] || !context) ) { // HANDLE: $(html) -> $(array) if ( match[1] ) { context = context instanceof jQuery ? context[0] : context; // scripts is true for back-compat jQuery.merge( this, jQuery.parseHTML( match[1], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( jQuery.isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById( match[2] ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } // Otherwise, we inject the element directly into the jQuery object this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); } if ( selector.selector !== undefined ) { this.selector = selector.selector; this.context = selector.context; } return jQuery.makeArray( selector, this ); }, // Start with an empty selector selector: "", // The default length of a jQuery object is 0 length: 0, // The number of elements contained in the matched element set size: function() { return this.length; }, toArray: function() { return core_slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { return num == null ? // Return a 'clean' array this.toArray() : // Return just the object ( num < 0 ? this[ this.length + num ] : this[ num ] ); }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; ret.context = this.context; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. // (You can seed the arguments with an array of args, but this is // only used internally.) each: function( callback, args ) { return jQuery.each( this, callback, args ); }, ready: function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; }, slice: function() { return this.pushStack( core_slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); }, map: function( callback ) { return this.pushStack( jQuery.map(this, function( elem, i ) { return callback.call( elem, i, elem ); })); }, end: function() { return this.prevObject || this.constructor(null); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: core_push, sort: [].sort, splice: [].splice }; // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend({ noConflict: function( deep ) { if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; }, // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Hold (or release) the ready event holdReady: function( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready ); } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); // Trigger any bound ready events if ( jQuery.fn.trigger ) { jQuery( document ).trigger("ready").off("ready"); } }, // See test/unit/core.js for details concerning isFunction. // Since version 1.3, DOM methods and functions like alert // aren't supported. They return false on IE (#2968). isFunction: function( obj ) { return jQuery.type(obj) === "function"; }, isArray: Array.isArray || function( obj ) { return jQuery.type(obj) === "array"; }, isWindow: function( obj ) { return obj != null && obj == obj.window; }, isNumeric: function( obj ) { return !isNaN( parseFloat(obj) ) && isFinite( obj ); }, type: function( obj ) { if ( obj == null ) { return String( obj ); } return typeof obj === "object" || typeof obj === "function" ? class2type[ core_toString.call(obj) ] || "object" : typeof obj; }, isPlainObject: function( obj ) { // Must be an Object. // Because of IE, we also have to check the presence of the constructor property. // Make sure that DOM nodes and window objects don't pass through, as well if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { return false; } try { // Not own constructor property must be Object if ( obj.constructor && !core_hasOwn.call(obj, "constructor") && !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } } catch ( e ) { // IE8,9 Will throw exceptions on certain host objects #9897 return false; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; for ( key in obj ) {} return key === undefined || core_hasOwn.call( obj, key ); }, isEmptyObject: function( obj ) { var name; for ( name in obj ) { return false; } return true; }, error: function( msg ) { throw new Error( msg ); }, // data: string of html // context (optional): If specified, the fragment will be created in this context, defaults to document // keepScripts (optional): If true, will include scripts passed in the html string parseHTML: function( data, context, keepScripts ) { if ( !data || typeof data !== "string" ) { return null; } if ( typeof context === "boolean" ) { keepScripts = context; context = false; } context = context || document; var parsed = rsingleTag.exec( data ), scripts = !keepScripts && []; // Single tag if ( parsed ) { return [ context.createElement( parsed[1] ) ]; } parsed = jQuery.buildFragment( [ data ], context, scripts ); if ( scripts ) { jQuery( scripts ).remove(); } return jQuery.merge( [], parsed.childNodes ); }, parseJSON: function( data ) { // Attempt to parse using the native JSON parser first if ( window.JSON && window.JSON.parse ) { return window.JSON.parse( data ); } if ( data === null ) { return data; } if ( typeof data === "string" ) { // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); if ( data ) { // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js if ( rvalidchars.test( data.replace( rvalidescape, "@" ) .replace( rvalidtokens, "]" ) .replace( rvalidbraces, "")) ) { return ( new Function( "return " + data ) )(); } } } jQuery.error( "Invalid JSON: " + data ); }, // Cross-browser xml parsing parseXML: function( data ) { var xml, tmp; if ( !data || typeof data !== "string" ) { return null; } try { if ( window.DOMParser ) { // Standard tmp = new DOMParser(); xml = tmp.parseFromString( data , "text/xml" ); } else { // IE xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = "false"; xml.loadXML( data ); } } catch( e ) { xml = undefined; } if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; }, noop: function() {}, // Evaluates a script in a global context // Workarounds based on findings by Jim Driscoll // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context globalEval: function( data ) { if ( data && jQuery.trim( data ) ) { // We use execScript on Internet Explorer // We use an anonymous function so that context is window // rather than jQuery in Firefox ( window.execScript || function( data ) { window[ "eval" ].call( window, data ); } )( data ); } }, // Convert dashed to camelCase; used by the css and data modules // Microsoft forgot to hump their vendor prefix (#9572) camelCase: function( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); }, nodeName: function( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, // args is for internal usage only each: function( obj, callback, args ) { var value, i = 0, length = obj.length, isArray = isArraylike( obj ); if ( args ) { if ( isArray ) { for ( ; i < length; i++ ) { value = callback.apply( obj[ i ], args ); if ( value === false ) { break; } } } else { for ( i in obj ) { value = callback.apply( obj[ i ], args ); if ( value === false ) { break; } } } // A special, fast, case for the most common use of each } else { if ( isArray ) { for ( ; i < length; i++ ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } else { for ( i in obj ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } } return obj; }, // Use native String.trim function wherever possible trim: core_trim && !core_trim.call("\uFEFF\xA0") ? function( text ) { return text == null ? "" : core_trim.call( text ); } : // Otherwise use our own trimming functionality function( text ) { return text == null ? "" : ( text + "" ).replace( rtrim, "" ); }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArraylike( Object(arr) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { core_push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { var len; if ( arr ) { if ( core_indexOf ) { return core_indexOf.call( arr, elem, i ); } len = arr.length; i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; for ( ; i < len; i++ ) { // Skip accessing in sparse arrays if ( i in arr && arr[ i ] === elem ) { return i; } } } return -1; }, merge: function( first, second ) { var l = second.length, i = first.length, j = 0; if ( typeof l === "number" ) { for ( ; j < l; j++ ) { first[ i++ ] = second[ j ]; } } else { while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ]; } } first.length = i; return first; }, grep: function( elems, callback, inv ) { var retVal, ret = [], i = 0, length = elems.length; inv = !!inv; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { retVal = !!callback( elems[ i ], i ); if ( inv !== retVal ) { ret.push( elems[ i ] ); } } return ret; }, // arg is for internal usage only map: function( elems, callback, arg ) { var value, i = 0, length = elems.length, isArray = isArraylike( elems ), ret = []; // Go through the array, translating each of the items to their if ( isArray ) { for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } } } // Flatten any nested arrays return core_concat.apply( [], ret ); }, // A global GUID counter for objects guid: 1, // Bind a function to a context, optionally partially applying any // arguments. proxy: function( fn, context ) { var args, proxy, tmp; if ( typeof context === "string" ) { tmp = fn[ context ]; context = fn; fn = tmp; } // Quick check to determine if target is callable, in the spec // this throws a TypeError, but we will just return undefined. if ( !jQuery.isFunction( fn ) ) { return undefined; } // Simulated bind args = core_slice.call( arguments, 2 ); proxy = function() { return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); }; // Set the guid of unique handler to the same of original handler, so it can be removed proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; }, // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function access: function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, length = elems.length, bulk = key == null; // Sets many values if ( jQuery.type( key ) === "object" ) { chainable = true; for ( i in key ) { jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( !jQuery.isFunction( value ) ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < length; i++ ) { fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); } } } return chainable ? elems : // Gets bulk ? fn.call( elems ) : length ? fn( elems[0], key ) : emptyGet; }, now: function() { return ( new Date() ).getTime(); } }); jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called after the browser event has already occurred. // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready ); // Standards-based browsers support DOMContentLoaded } else if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed, false ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed, false ); // If IE event model is used } else { // Ensure firing before onload, maybe late but safe also for iframes document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work window.attachEvent( "onload", completed ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } // detach all dom ready events detach(); // and execute any waiting functions jQuery.ready(); } })(); } } } return readyList.promise( obj ); }; // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); }); function isArraylike( obj ) { var length = obj.length, type = jQuery.type( obj ); if ( jQuery.isWindow( obj ) ) { return false; } if ( obj.nodeType === 1 && length ) { return true; } return type === "array" || type !== "function" && ( length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj ); } // All jQuery objects should point back to these rootjQuery = jQuery(document); // String to Object options format cache var optionsCache = {}; // Convert String-formatted options into Object-formatted ones and store in cache function createOptions( options ) { var object = optionsCache[ options ] = {}; jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { object[ flag ] = true; }); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? ( optionsCache[ options ] || createOptions( options ) ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value (for non-forgettable lists) memory, // Flag to know if list was already fired fired, // End of the loop when firing firingLength, // Index of currently firing callback (modified by remove if needed) firingIndex, // First callback to fire (used internally by add and fireWith) firingStart, // Actual callback list list = [], // Stack of fire calls for repeatable lists stack = !options.once && [], // Fire callbacks fire = function( data ) { memory = options.memory && data; fired = true; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; firing = true; for ( ; list && firingIndex < firingLength; firingIndex++ ) { if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { memory = false; // To prevent further calls using add break; } } firing = false; if ( list ) { if ( stack ) { if ( stack.length ) { fire( stack.shift() ); } } else if ( memory ) { list = []; } else { self.disable(); } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // First, we save the current length var start = list.length; (function add( args ) { jQuery.each( args, function( _, arg ) { var type = jQuery.type( arg ); if ( type === "function" ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && type !== "string" ) { // Inspect recursively add( arg ); } }); })( arguments ); // Do we need to add the callbacks to the // current firing batch? if ( firing ) { firingLength = list.length; // With memory, if we're not firing then // we should call right away } else if ( memory ) { firingStart = start; fire( memory ); } } return this; }, // Remove a callback from the list remove: function() { if ( list ) { jQuery.each( arguments, function( _, arg ) { var index; while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( firing ) { if ( index <= firingLength ) { firingLength--; } if ( index <= firingIndex ) { firingIndex--; } } } }); } return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); }, // Remove all callbacks from the list empty: function() { list = []; return this; }, // Have the list do nothing anymore disable: function() { list = stack = memory = undefined; return this; }, // Is it disabled? disabled: function() { return !list; }, // Lock the list in its current state lock: function() { stack = undefined; if ( !memory ) { self.disable(); } return this; }, // Is it locked? locked: function() { return !stack; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; if ( list && ( !fired || stack ) ) { if ( firing ) { stack.push( args ); } else { fire( args ); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; jQuery.extend({ Deferred: function( func ) { var tuples = [ // action, add listener, listener list, final state [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var action = tuple[ 0 ], fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() .done( newDefer.resolve ) .fail( newDefer.reject ) .progress( newDefer.notify ); } else { newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); } }); }); fns = null; }).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Keep pipe for back-compat promise.pipe = promise.then; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 3 ]; // promise[ done | fail | progress ] = list.add promise[ tuple[1] ] = list.add; // Handle state if ( stateString ) { list.add(function() { // state = [ resolved | rejected ] state = stateString; // [ reject_list | resolve_list ].disable; progress_list.lock }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); } // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; }); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( subordinate /* , ..., subordinateN */ ) { var i = 0, resolveValues = core_slice.call( arguments ), length = resolveValues.length, // the count of uncompleted subordinates remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, // the master Deferred. If resolveValues consist of only a single Deferred, just use that. deferred = remaining === 1 ? subordinate : jQuery.Deferred(), // Update function for both resolve and progress values updateFunc = function( i, contexts, values ) { return function( value ) { contexts[ i ] = this; values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; if( values === progressValues ) { deferred.notifyWith( contexts, values ); } else if ( !( --remaining ) ) { deferred.resolveWith( contexts, values ); } }; }, progressValues, progressContexts, resolveContexts; // add listeners to Deferred subordinates; treat others as resolved if ( length > 1 ) { progressValues = new Array( length ); progressContexts = new Array( length ); resolveContexts = new Array( length ); for ( ; i < length; i++ ) { if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { resolveValues[ i ].promise() .done( updateFunc( i, resolveContexts, resolveValues ) ) .fail( deferred.reject ) .progress( updateFunc( i, progressContexts, progressValues ) ); } else { --remaining; } } } // if we're not waiting on anything, resolve the master if ( !remaining ) { deferred.resolveWith( resolveContexts, resolveValues ); } return deferred.promise(); } }); jQuery.support = (function() { var support, all, a, input, select, fragment, opt, eventName, isSupported, i, div = document.createElement("div"); // Setup div.setAttribute( "className", "t" ); div.innerHTML = "
a"; // Support tests won't run in some limited or non-browser environments all = div.getElementsByTagName("*"); a = div.getElementsByTagName("a")[ 0 ]; if ( !all || !a || !all.length ) { return {}; } // First batch of tests select = document.createElement("select"); opt = select.appendChild( document.createElement("option") ); input = div.getElementsByTagName("input")[ 0 ]; a.style.cssText = "top:1px;float:left;opacity:.5"; support = { // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", // IE strips leading whitespace when .innerHTML is used leadingWhitespace: div.firstChild.nodeType === 3, // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute // (IE uses .cssText instead) style: /top/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) hrefNormalized: a.getAttribute("href") === "/a", // Make sure that element opacity exists // (IE uses filter instead) // Use a regex to work around a WebKit issue. See #5145 opacity: /^0.5/.test( a.style.opacity ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) checkOn: !!input.value, // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, // Tests for enctype support on a form (#6743) enctype: !!document.createElement("form").enctype, // Makes sure cloning an html5 element does not cause problems // Where outerHTML is undefined, this still works html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode boxModel: document.compatMode === "CSS1Compat", // Will be defined later deleteExpando: true, noCloneEvent: true, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableMarginRight: true, boxSizingReliable: true, pixelPosition: false }; // Make sure checked status is properly cloned input.checked = true; support.noCloneChecked = input.cloneNode( true ).checked; // Make sure that the options inside disabled selects aren't marked as disabled // (WebKit marks them as disabled) select.disabled = true; support.optDisabled = !opt.disabled; // Support: IE<9 try { delete div.test; } catch( e ) { support.deleteExpando = false; } // Check if we can trust getAttribute("value") input = document.createElement("input"); input.setAttribute( "value", "" ); support.input = input.getAttribute( "value" ) === ""; // Check if an input maintains its value after becoming a radio input.value = "t"; input.setAttribute( "type", "radio" ); support.radioValue = input.value === "t"; // #11217 - WebKit loses check when the name is after the checked attribute input.setAttribute( "checked", "t" ); input.setAttribute( "name", "t" ); fragment = document.createDocumentFragment(); fragment.appendChild( input ); // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked; // WebKit doesn't clone checked state correctly in fragments support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; // Support: IE<9 // Opera does not clone events (and typeof div.attachEvent === undefined). // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() if ( div.attachEvent ) { div.attachEvent( "onclick", function() { support.noCloneEvent = false; }); div.cloneNode( true ).click(); } // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php for ( i in { submit: true, change: true, focusin: true }) { div.setAttribute( eventName = "on" + i, "t" ); support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; } div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; // Run tests that need a body at doc ready jQuery(function() { var container, marginDiv, tds, divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", body = document.getElementsByTagName("body")[0]; if ( !body ) { // Return for frameset docs that don't have a body return; } container = document.createElement("div"); container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; body.appendChild( container ).appendChild( div ); // Support: IE8 // Check if table cells still have offsetWidth/Height when they are set // to display:none and there are still other visible table cells in a // table row; if so, offsetWidth/Height are not reliable for use when // determining if an element has been hidden directly using // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). div.innerHTML = "
t
"; tds = div.getElementsByTagName("td"); tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; isSupported = ( tds[ 0 ].offsetHeight === 0 ); tds[ 0 ].style.display = ""; tds[ 1 ].style.display = "none"; // Support: IE8 // Check if empty table cells still have offsetWidth/Height support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); // Check box-sizing and margin behavior div.innerHTML = ""; div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; support.boxSizing = ( div.offsetWidth === 4 ); support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); // Use window.getComputedStyle because jsdom on node.js will break without it. if ( window.getComputedStyle ) { support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; // Check if div with explicit width and no margin-right incorrectly // gets computed margin-right based on width of container. (#3333) // Fails in WebKit before Feb 2011 nightlies // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right marginDiv = div.appendChild( document.createElement("div") ); marginDiv.style.cssText = div.style.cssText = divReset; marginDiv.style.marginRight = marginDiv.style.width = "0"; div.style.width = "1px"; support.reliableMarginRight = !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); } if ( typeof div.style.zoom !== core_strundefined ) { // Support: IE<8 // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout div.innerHTML = ""; div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); // Support: IE6 // Check if elements with layout shrink-wrap their children div.style.display = "block"; div.innerHTML = "
"; div.firstChild.style.width = "5px"; support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); if ( support.inlineBlockNeedsLayout ) { // Prevent IE 6 from affecting layout for positioned elements #11048 // Prevent IE from shrinking the body in IE 7 mode #12869 // Support: IE<8 body.style.zoom = 1; } } body.removeChild( container ); // Null elements to avoid leaks in IE container = div = tds = marginDiv = null; }); // Null elements to avoid leaks in IE all = select = fragment = opt = a = input = null; return support; })(); var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; function internalData( elem, name, data, pvt /* Internal Use Only */ ){ if ( !jQuery.acceptData( elem ) ) { return; } var thisCache, ret, internalKey = jQuery.expando, getByName = typeof name === "string", // We have to handle DOM nodes and JS objects differently because IE6-7 // can't GC object references properly across the DOM-JS boundary isNode = elem.nodeType, // Only DOM nodes need the global jQuery cache; JS object data is // attached directly to the object so GC can occur automatically cache = isNode ? jQuery.cache : elem, // Only defining an ID for JS objects if its cache already exists allows // the code to shortcut on the same path as a DOM node with no cache id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; // Avoid doing any more work than we need to when trying to get data on an // object that has no data at all if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { return; } if ( !id ) { // Only DOM nodes need a new unique ID for each element since their data // ends up in the global cache if ( isNode ) { elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++; } else { id = internalKey; } } if ( !cache[ id ] ) { cache[ id ] = {}; // Avoids exposing jQuery metadata on plain JS objects when the object // is serialized using JSON.stringify if ( !isNode ) { cache[ id ].toJSON = jQuery.noop; } } // An object can be passed to jQuery.data instead of a key/value pair; this gets // shallow copied over onto the existing cache if ( typeof name === "object" || typeof name === "function" ) { if ( pvt ) { cache[ id ] = jQuery.extend( cache[ id ], name ); } else { cache[ id ].data = jQuery.extend( cache[ id ].data, name ); } } thisCache = cache[ id ]; // jQuery data() is stored in a separate object inside the object's internal data // cache in order to avoid key collisions between internal data and user-defined // data. if ( !pvt ) { if ( !thisCache.data ) { thisCache.data = {}; } thisCache = thisCache.data; } if ( data !== undefined ) { thisCache[ jQuery.camelCase( name ) ] = data; } // Check for both converted-to-camel and non-converted data property names // If a data property was specified if ( getByName ) { // First Try to find as-is property data ret = thisCache[ name ]; // Test for null|undefined property data if ( ret == null ) { // Try to find the camelCased property ret = thisCache[ jQuery.camelCase( name ) ]; } } else { ret = thisCache; } return ret; } function internalRemoveData( elem, name, pvt ) { if ( !jQuery.acceptData( elem ) ) { return; } var i, l, thisCache, isNode = elem.nodeType, // See jQuery.data for more information cache = isNode ? jQuery.cache : elem, id = isNode ? elem[ jQuery.expando ] : jQuery.expando; // If there is already no cache entry for this object, there is no // purpose in continuing if ( !cache[ id ] ) { return; } if ( name ) { thisCache = pvt ? cache[ id ] : cache[ id ].data; if ( thisCache ) { // Support array or space separated string names for data keys if ( !jQuery.isArray( name ) ) { // try the string as a key before any manipulation if ( name in thisCache ) { name = [ name ]; } else { // split the camel cased version by spaces unless a key with the spaces exists name = jQuery.camelCase( name ); if ( name in thisCache ) { name = [ name ]; } else { name = name.split(" "); } } } else { // If "name" is an array of keys... // When data is initially created, via ("key", "val") signature, // keys will be converted to camelCase. // Since there is no way to tell _how_ a key was added, remove // both plain key and camelCase key. #12786 // This will only penalize the array argument path. name = name.concat( jQuery.map( name, jQuery.camelCase ) ); } for ( i = 0, l = name.length; i < l; i++ ) { delete thisCache[ name[i] ]; } // If there is no data left in the cache, we want to continue // and let the cache object itself get destroyed if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { return; } } } // See jQuery.data for more information if ( !pvt ) { delete cache[ id ].data; // Don't destroy the parent cache unless the internal data object // had been the only thing left in it if ( !isEmptyDataObject( cache[ id ] ) ) { return; } } // Destroy the cache if ( isNode ) { jQuery.cleanData( [ elem ], true ); // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) } else if ( jQuery.support.deleteExpando || cache != cache.window ) { delete cache[ id ]; // When all else fails, null } else { cache[ id ] = null; } } jQuery.extend({ cache: {}, // Unique for each copy of jQuery on the page // Non-digits removed to match rinlinejQuery expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { "embed": true, // Ban all objects except for Flash (which handle expandos) "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", "applet": true }, hasData: function( elem ) { elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; return !!elem && !isEmptyDataObject( elem ); }, data: function( elem, name, data ) { return internalData( elem, name, data ); }, removeData: function( elem, name ) { return internalRemoveData( elem, name ); }, // For internal use only. _data: function( elem, name, data ) { return internalData( elem, name, data, true ); }, _removeData: function( elem, name ) { return internalRemoveData( elem, name, true ); }, // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { // Do not set data on non-element because it will not be cleared (#8335). if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { return false; } var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; // nodes accept data unless otherwise specified; rejection can be conditional return !noData || noData !== true && elem.getAttribute("classid") === noData; } }); jQuery.fn.extend({ data: function( key, value ) { var attrs, name, elem = this[0], i = 0, data = null; // Gets all values if ( key === undefined ) { if ( this.length ) { data = jQuery.data( elem ); if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { attrs = elem.attributes; for ( ; i < attrs.length; i++ ) { name = attrs[i].name; if ( !name.indexOf( "data-" ) ) { name = jQuery.camelCase( name.slice(5) ); dataAttr( elem, name, data[ name ] ); } } jQuery._data( elem, "parsedAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each(function() { jQuery.data( this, key ); }); } return jQuery.access( this, function( value ) { if ( value === undefined ) { // Try to fetch any internally stored data first return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; } this.each(function() { jQuery.data( this, key, value ); }); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each(function() { jQuery.removeData( this, key ); }); } }); function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = data === "true" ? true : data === "false" ? false : data === "null" ? null : // Only convert to a number if it doesn't change the string +data + "" === data ? +data : rbrace.test( data ) ? jQuery.parseJSON( data ) : data; } catch( e ) {} // Make sure we set the data so it isn't changed later jQuery.data( elem, key, data ); } else { data = undefined; } } return data; } // checks a cache object for emptiness function isEmptyDataObject( obj ) { var name; for ( name in obj ) { // if the public data object is empty, the private is still empty if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { continue; } if ( name !== "toJSON" ) { return false; } } return true; } jQuery.extend({ queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = jQuery._data( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || jQuery.isArray(data) ) { queue = jQuery._data( elem, type, jQuery.makeArray(data) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } hooks.cur = fn; if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // not intended for public consumption - generates a queueHooks object, or returns the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return jQuery._data( elem, key ) || jQuery._data( elem, key, { empty: jQuery.Callbacks("once memory").add(function() { jQuery._removeData( elem, type + "queue" ); jQuery._removeData( elem, key ); }) }); } }); jQuery.fn.extend({ queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[0], type ); } return data === undefined ? this : this.each(function() { var queue = jQuery.queue( this, type, data ); // ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[0] !== "inprogress" ) { jQuery.dequeue( this, type ); } }); }, dequeue: function( type ) { return this.each(function() { jQuery.dequeue( this, type ); }); }, // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = setTimeout( next, time ); hooks.stop = function() { clearTimeout( timeout ); }; }); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while( i-- ) { tmp = jQuery._data( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } }); var nodeHook, boolHook, rclass = /[\t\r\n]/g, rreturn = /\r/g, rfocusable = /^(?:input|select|textarea|button|object)$/i, rclickable = /^(?:a|area)$/i, rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i, ruseDefault = /^(?:checked|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute, getSetInput = jQuery.support.input; jQuery.fn.extend({ attr: function( name, value ) { return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each(function() { jQuery.removeAttr( this, name ); }); }, prop: function( name, value ) { return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { name = jQuery.propFix[ name ] || name; return this.each(function() { // try/catch handles cases where IE balks (such as removing a property on window) try { this[ name ] = undefined; delete this[ name ]; } catch( e ) {} }); }, addClass: function( value ) { var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = typeof value === "string" && value; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).addClass( value.call( this, j, this.className ) ); }); } if ( proceed ) { // The disjunction here is for better compressibility (see removeClass) classes = ( value || "" ).match( core_rnotwhite ) || []; for ( ; i < len; i++ ) { elem = this[ i ]; cur = elem.nodeType === 1 && ( elem.className ? ( " " + elem.className + " " ).replace( rclass, " " ) : " " ); if ( cur ) { j = 0; while ( (clazz = classes[j++]) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } elem.className = jQuery.trim( cur ); } } } return this; }, removeClass: function( value ) { var classes, elem, cur, clazz, j, i = 0, len = this.length, proceed = arguments.length === 0 || typeof value === "string" && value; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { jQuery( this ).removeClass( value.call( this, j, this.className ) ); }); } if ( proceed ) { classes = ( value || "" ).match( core_rnotwhite ) || []; for ( ; i < len; i++ ) { elem = this[ i ]; // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && ( elem.className ? ( " " + elem.className + " " ).replace( rclass, " " ) : "" ); if ( cur ) { j = 0; while ( (clazz = classes[j++]) ) { // Remove *all* instances while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { cur = cur.replace( " " + clazz + " ", " " ); } } elem.className = value ? jQuery.trim( cur ) : ""; } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isBool = typeof stateVal === "boolean"; if ( jQuery.isFunction( value ) ) { return this.each(function( i ) { jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); }); } return this.each(function() { if ( type === "string" ) { // toggle individual class names var className, i = 0, self = jQuery( this ), state = stateVal, classNames = value.match( core_rnotwhite ) || []; while ( (className = classNames[ i++ ]) ) { // check each className given, space separated list state = isBool ? state : !self.hasClass( className ); self[ state ? "addClass" : "removeClass" ]( className ); } // Toggle whole class name } else if ( type === core_strundefined || type === "boolean" ) { if ( this.className ) { // store className if set jQuery._data( this, "__className__", this.className ); } // If the element has a class name or if we're passed "false", // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; } }); }, hasClass: function( selector ) { var className = " " + selector + " ", i = 0, l = this.length; for ( ; i < l; i++ ) { if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { return true; } } return false; }, val: function( value ) { var ret, hooks, isFunction, elem = this[0]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { return ret; } ret = elem.value; return typeof ret === "string" ? // handle most common string cases ret.replace(rreturn, "") : // handle cases where value is null/undef or number ret == null ? "" : ret; } return; } isFunction = jQuery.isFunction( value ); return this.each(function( i ) { var val, self = jQuery(this); if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { val = value.call( this, i, self.val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( jQuery.isArray( val ) ) { val = jQuery.map(val, function ( value ) { return value == null ? "" : value + ""; }); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } }); } }); jQuery.extend({ valHooks: { option: { get: function( elem ) { // attributes.value is undefined in Blackberry 4.7 but // uses .value. See #6932 var val = elem.attributes.value; return !val || val.specified ? elem.value : elem.text; } }, select: { get: function( elem ) { var value, option, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one" || index < 0, values = one ? null : [], max = one ? index + 1 : options.length, i = index < 0 ? max : one ? index : 0; // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; // oldIE doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var values = jQuery.makeArray( value ); jQuery(elem).find("option").each(function() { this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; }); if ( !values.length ) { elem.selectedIndex = -1; } return values; } } }, attr: function( elem, name, value ) { var hooks, notxml, ret, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === core_strundefined ) { return jQuery.prop( elem, name, value ); } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { elem.setAttribute( name, value + "" ); return value; } } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { // In IE9+, Flash objects don't have .getAttribute (#12945) // Support: IE9+ if ( typeof elem.getAttribute !== core_strundefined ) { ret = elem.getAttribute( name ); } // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; } }, removeAttr: function( elem, value ) { var name, propName, i = 0, attrNames = value && value.match( core_rnotwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( (name = attrNames[i++]) ) { propName = jQuery.propFix[ name ] || name; // Boolean attributes get special treatment (#10870) if ( rboolean.test( name ) ) { // Set corresponding property to false for boolean attributes // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 if ( !getSetAttribute && ruseDefault.test( name ) ) { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ propName ] = false; } else { elem[ propName ] = false; } // See #9699 for explanation of this approach (setting first, then removal) } else { jQuery.attr( elem, name, "" ); } elem.removeAttribute( getSetAttribute ? name : propName ); } } }, attrHooks: { type: { set: function( elem, value ) { if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { // Setting the type on a radio button after the value resets the value in IE6-9 // Reset value to default in case type is set after value during creation var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, propFix: { tabindex: "tabIndex", readonly: "readOnly", "for": "htmlFor", "class": "className", maxlength: "maxLength", cellspacing: "cellSpacing", cellpadding: "cellPadding", rowspan: "rowSpan", colspan: "colSpan", usemap: "useMap", frameborder: "frameBorder", contenteditable: "contentEditable" }, prop: function( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set properties on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); if ( notxml ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return elem[ name ]; } } }, propHooks: { tabIndex: { get: function( elem ) { // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ var attributeNode = elem.getAttributeNode("tabindex"); return attributeNode && attributeNode.specified ? parseInt( attributeNode.value, 10 ) : rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 0 : undefined; } } } }); // Hook for boolean attributes boolHook = { get: function( elem, name ) { var // Use .prop to determine if this attribute is understood as boolean prop = jQuery.prop( elem, name ), // Fetch it accordingly attr = typeof prop === "boolean" && elem.getAttribute( name ), detail = typeof prop === "boolean" ? getSetInput && getSetAttribute ? attr != null : // oldIE fabricates an empty string for missing boolean attributes // and conflates checked/selected into attroperties ruseDefault.test( name ) ? elem[ jQuery.camelCase( "default-" + name ) ] : !!attr : // fetch an attribute node for properties not recognized as boolean elem.getAttributeNode( name ); return detail && detail.value !== false ? name.toLowerCase() : undefined; }, set: function( elem, value, name ) { if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { // IE<8 needs the *property* name elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); // Use defaultChecked and defaultSelected for oldIE } else { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; } return name; } }; // fix oldIE value attroperty if ( !getSetInput || !getSetAttribute ) { jQuery.attrHooks.value = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return jQuery.nodeName( elem, "input" ) ? // Ignore the value *property* by using defaultValue elem.defaultValue : ret && ret.specified ? ret.value : undefined; }, set: function( elem, value, name ) { if ( jQuery.nodeName( elem, "input" ) ) { // Does not return so that setAttribute is also used elem.defaultValue = value; } else { // Use nodeHook if defined (#1954); otherwise setAttribute is fine return nodeHook && nodeHook.set( elem, value, name ); } } }; } // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !getSetAttribute ) { // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? ret.value : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { elem.setAttributeNode( (ret = elem.ownerDocument.createAttribute( name )) ); } ret.value = value += ""; // Break association with cloned elements by also using setAttribute (#9646) return name === "value" || value === elem.getAttribute( name ) ? value : undefined; } }; // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, set: function( elem, value, name ) { nodeHook.set( elem, value === "" ? false : value, name ); } }; // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each([ "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { set: function( elem, value ) { if ( value === "" ) { elem.setAttribute( name, "auto" ); return value; } } }); }); } // Some attributes require a special call on IE // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !jQuery.support.hrefNormalized ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret == null ? undefined : ret; } }); }); // href/src property should get the full normalized URL (#10299/#12915) jQuery.each([ "href", "src" ], function( i, name ) { jQuery.propHooks[ name ] = { get: function( elem ) { return elem.getAttribute( name, 4 ); } }; }); } if ( !jQuery.support.style ) { jQuery.attrHooks.style = { get: function( elem ) { // Return undefined in the case of empty string // Note: IE uppercases css property names, but if we were to .toLowerCase() // .cssText, that would destroy case senstitivity in URL's, like in "background" return elem.style.cssText || undefined; }, set: function( elem, value ) { return ( elem.style.cssText = value + "" ); } }; } // Safari mis-reports the default selected property of an option // Accessing the parent's selectedIndex property fixes it if ( !jQuery.support.optSelected ) { jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { get: function( elem ) { var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; // Make sure that it also works with optgroups, see #5701 if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } return null; } }); } // IE6/7 call enctype encoding if ( !jQuery.support.enctype ) { jQuery.propFix.enctype = "encoding"; } // Radios and checkboxes getter/setter if ( !jQuery.support.checkOn ) { jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { get: function( elem ) { // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified return elem.getAttribute("value") === null ? "on" : elem.value; } }; }); } jQuery.each([ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { set: function( elem, value ) { if ( jQuery.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); } } }); }); var rformElems = /^(?:input|select|textarea)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; function returnTrue() { return true; } function returnFalse() { return false; } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { var tmp, events, t, handleObjIn, special, eventHandle, handleObj, handlers, type, namespaces, origType, elemData = jQuery._data( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !(events = elemData.events) ) { events = elemData.events = {}; } if ( !(eventHandle = elemData.handle) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : undefined; }; // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events eventHandle.elem = elem; } // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); types = ( types || "" ).match( core_rnotwhite ) || [""]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[t] ) || []; type = origType = tmp[1]; namespaces = ( tmp[2] || "" ).split( "." ).sort(); // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend({ type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join(".") }, handleObjIn ); // Init the event handler queue if we're the first if ( !(handlers = events[ type ]) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener/attachEvent if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { // Bind the global event handler to the element if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle, false ); } else if ( elem.attachEvent ) { elem.attachEvent( "on" + type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } // Nullify elem to prevent memory leaks in IE elem = null; }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, handleObj, tmp, origCount, t, events, special, handlers, type, namespaces, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( core_rnotwhite ) || [""]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[t] ) || []; type = origType = tmp[1]; namespaces = ( tmp[2] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { delete elemData.handle; // removeData also checks for emptiness and clears the expando if empty // so use it instead of delete jQuery._removeData( elem, "events" ); } }, trigger: function( event, data, elem, onlyHandlers ) { var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [ elem || document ], type = core_hasOwn.call( event, "type" ) ? event.type : event, namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; cur = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf(".") >= 0 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split("."); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf(":") < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); event.isTrigger = true; event.namespace = namespaces.join("."); event.namespace_re = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === (elem.ownerDocument || document) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { event.preventDefault(); } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { // Call a native DOM method on the target with the same name name as the event. // Can't use an .isFunction() check here because IE6/7 fails that test. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; try { elem[ type ](); } catch ( e ) { // IE<9 dies on focus/blur to hidden element (#1486,#12518) // only reproducible on winXP IE8 native, not IE9 in IE8 mode } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, dispatch: function( event ) { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event ); var i, ret, handleObj, matched, j, handlerQueue = [], args = core_slice.call( arguments ), handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; var obj = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ); if(obj.apply){ ret = obj.apply( matched.elem, args ); } if ( ret !== undefined ) { if ( (event.result = ret) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var sel, handleObj, matches, i, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers // Black-hole SVG instance trees (#13180) // Avoid non-left-click bubbling in Firefox (#3861) if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { for ( ; cur != this; cur = cur.parentNode || this ) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { matches = []; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if ( matches[ sel ] === undefined ) { matches[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) >= 0 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matches[ sel ] ) { matches.push( handleObj ); } } if ( matches.length ) { handlerQueue.push({ elem: cur, handlers: matches }); } } } } // Add the remaining (directly-bound) handlers if ( delegateCount < handlers.length ) { handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); } return handlerQueue; }, fix: function( event ) { if ( event[ jQuery.expando ] ) { return event; } // Create a writable copy of the event object and normalize some properties var i, prop, copy, type = event.type, originalEvent = event, fixHook = this.fixHooks[ type ]; if ( !fixHook ) { this.fixHooks[ type ] = fixHook = rmouseEvent.test( type ) ? this.mouseHooks : rkeyEvent.test( type ) ? this.keyHooks : {}; } copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; event = new jQuery.Event( originalEvent ); i = copy.length; while ( i-- ) { prop = copy[ i ]; event[ prop ] = originalEvent[ prop ]; } // Support: IE<9 // Fix target property (#1925) if ( !event.target ) { event.target = originalEvent.srcElement || document; } // Support: Chrome 23+, Safari? // Target should not be a text node (#504, #13143) if ( event.target.nodeType === 3 ) { event.target = event.target.parentNode; } // Support: IE<9 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) event.metaKey = !!event.metaKey; return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; }, // Includes some event props shared by KeyEvent and MouseEvent props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), fixHooks: {}, keyHooks: { props: "char charCode key keyCode".split(" "), filter: function( event, original ) { // Add which for key events if ( event.which == null ) { event.which = original.charCode != null ? original.charCode : original.keyCode; } return event; } }, mouseHooks: { props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function( event, original ) { var body, eventDoc, doc, button = original.button, fromElement = original.fromElement; // Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && original.clientX != null ) { eventDoc = event.target.ownerDocument || document; doc = eventDoc.documentElement; body = eventDoc.body; event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); } // Add relatedTarget, if necessary if ( !event.relatedTarget && fromElement ) { event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; } // Add which for click: 1 === left; 2 === middle; 3 === right // Note: button is not normalized, so don't use it if ( !event.which && button !== undefined ) { event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); } return event; } }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, click: { // For checkbox, fire native event so checked state will be right trigger: function() { if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { this.click(); return false; } } }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function() { if ( this !== document.activeElement && this.focus ) { try { this.focus(); return false; } catch ( e ) { // Support: IE<9 // If we error on focus to hidden element (#1486, #12518), // let .trigger() run the handlers } } }, delegateType: "focusin" }, blur: { trigger: function() { if ( this === document.activeElement && this.blur ) { this.blur(); return false; } }, delegateType: "focusout" }, beforeunload: { postDispatch: function( event ) { // Even when returnValue equals to undefined Firefox will still show alert if ( event.result !== undefined ) { event.originalEvent.returnValue = event.result; } } } }, simulate: function( type, elem, event, bubble ) { // Piggyback on a donor event to simulate a different one. // Fake originalEvent to avoid donor's stopPropagation, but if the // simulated event prevents default then we do the same on the donor. var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true, originalEvent: {} } ); if ( bubble ) { jQuery.event.trigger( e, null, elem ); } else { jQuery.event.dispatch.call( elem, e ); } if ( e.isDefaultPrevented() ) { event.preventDefault(); } } }; jQuery.removeEvent = document.removeEventListener ? function( elem, type, handle ) { if ( elem.removeEventListener ) { elem.removeEventListener( type, handle, false ); } } : function( elem, type, handle ) { var name = "on" + type; if ( elem.detachEvent ) { // #8545, #7054, preventing memory leaks for custom events in IE6-8 // detachEvent needed property on element, by name of that event, to properly expose it to GC if ( typeof elem[ name ] === core_strundefined ) { elem[ name ] = null; } elem.detachEvent( name, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !(this instanceof jQuery.Event) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || jQuery.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( !e ) { return; } // If preventDefault exists, run it on the original event if ( e.preventDefault ) { e.preventDefault(); // Support: IE // Otherwise set the returnValue property of the original event to false } else { e.returnValue = false; } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( !e ) { return; } // If stopPropagation exists, run it on the original event if ( e.stopPropagation ) { e.stopPropagation(); } // Support: IE // Set the cancelBubble property of the original event to true e.cancelBubble = true; }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); } }; // Create mouseenter/leave events using mouseover/out and event-time checks jQuery.each({ mouseenter: "mouseover", mouseleave: "mouseout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mousenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || (related !== target && !jQuery.contains( target, related )) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; }); // IE submit delegation if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Lazy-add a submit handler when a descendant form may potentially be submitted jQuery.event.add( this, "click._submit keypress._submit", function( e ) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; if ( form && !jQuery._data( form, "submitBubbles" ) ) { jQuery.event.add( form, "submit._submit", function( event ) { event._submit_bubble = true; }); jQuery._data( form, "submitBubbles", true ); } }); // return undefined since we don't need an event listener }, postDispatch: function( event ) { // If form was submitted by the user, bubble the event up the tree if ( event._submit_bubble ) { delete event._submit_bubble; if ( this.parentNode && !event.isTrigger ) { jQuery.event.simulate( "submit", this.parentNode, event, true ); } } }, teardown: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Remove delegated handlers; cleanData eventually reaps submit handlers attached above jQuery.event.remove( this, "._submit" ); } }; } // IE change delegation and checkbox/radio fix if ( !jQuery.support.changeBubbles ) { jQuery.event.special.change = { setup: function() { if ( rformElems.test( this.nodeName ) ) { // IE doesn't fire change on a check/radio until blur; trigger it on click // after a propertychange. Eat the blur-change in special.change.handle. // This still fires onchange a second time for check/radio after blur. if ( this.type === "checkbox" || this.type === "radio" ) { jQuery.event.add( this, "propertychange._change", function( event ) { if ( event.originalEvent.propertyName === "checked" ) { this._just_changed = true; } }); jQuery.event.add( this, "click._change", function( event ) { if ( this._just_changed && !event.isTrigger ) { this._just_changed = false; } // Allow triggered, simulated change events (#11500) jQuery.event.simulate( "change", this, event, true ); }); } return false; } // Delegated event; lazy-add a change handler on descendant inputs jQuery.event.add( this, "beforeactivate._change", function( e ) { var elem = e.target; if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); jQuery._data( elem, "changeBubbles", true ); } }); }, handle: function( event ) { var elem = event.target; // Swallow native change events from checkbox/radio, we already triggered them above if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { return event.handleObj.handler.apply( this, arguments ); } }, teardown: function() { jQuery.event.remove( this, "._change" ); return !rformElems.test( this.nodeName ); } }; } // Create "bubbling" focus and blur events if ( !jQuery.support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler while someone wants focusin/focusout var attaches = 0, handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); }; jQuery.event.special[ fix ] = { setup: function() { if ( attaches++ === 0 ) { document.addEventListener( orig, handler, true ); } }, teardown: function() { if ( --attaches === 0 ) { document.removeEventListener( orig, handler, true ); } } }; }); } jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) { var type, origFn; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { this.on( type, selector, data, types[ type ], one ); } return this; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return this; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return this.each( function() { jQuery.event.add( this, types, fn, data, selector ); }); }, one: function( types, selector, data, fn ) { return this.on( types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each(function() { jQuery.event.remove( this, types, fn, selector ); }); }, bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); }, trigger: function( type, data ) { return this.each(function() { jQuery.event.trigger( type, data, this ); }); }, triggerHandler: function( type, data ) { var elem = this[0]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } }); /*! * Sizzle CSS Selector Engine * Copyright 2012 jQuery Foundation and other contributors * Released under the MIT license * http://sizzlejs.com/ */ (function( window, undefined ) { var i, cachedruns, Expr, getText, isXML, compile, hasDuplicate, outermostContext, // Local document vars setDocument, document, docElem, documentIsXML, rbuggyQSA, rbuggyMatches, matches, contains, sortOrder, // Instance-specific data expando = "sizzle" + -(new Date()), preferredDoc = window.document, support = {}, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), // General-purpose constants strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, // Array methods arr = [], pop = arr.pop, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf if we can't use a native one indexOf = arr.indexOf || function( elem ) { var i = 0, len = this.length; for ( ; i < len; i++ ) { if ( this[i] === elem ) { return i; } } return -1; }, // Regular expressions // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/css3-syntax/#characters characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", // Loosely modeled on CSS identifier characters // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = characterEncoding.replace( "w", "w#" ), // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors operators = "([*^$|!~]?=)", attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", // Prefer arguments quoted, // then not containing pseudos/brackets, // then attribute selectors/non-parenthetical expressions, // then anything else // These preferences are here to reduce the number of selectors // needing tokenize in the PSEUDO preFilter pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + characterEncoding + ")" ), "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rsibling = /[\x20\t\r\n\f]*[+~]/, rnative = /^[^{]+\{\s*\[native code/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rescape = /'|\\/g, rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, funescape = function( _, escaped ) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint return high !== high ? escaped : // BMP codepoint high < 0 ? String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }; // Use a stripped-down slice if we can't use a native one try { slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType; } catch ( e ) { slice = function( i ) { var elem, results = []; while ( (elem = this[i++]) ) { results.push( elem ); } return results; }; } /** * For feature detection * @param {Function} fn The function to test for native support */ function isNative( fn ) { return rnative.test( fn + "" ); } /** * Create key-value caches of limited size * @returns {Function(string, Object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var cache, keys = []; return (cache = function( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key += " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key ] = value); }); } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ expando ] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created div and expects a boolean result */ function assert( fn ) { var div = document.createElement("div"); try { return fn( div ); } catch (e) { return false; } finally { // release memory in IE div = null; } } function Sizzle( selector, context, results, seed ) { var match, elem, m, nodeType, // QSA vars i, groups, old, nid, newContext, newSelector; if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); } context = context || document; results = results || []; if ( !selector || typeof selector !== "string" ) { return results; } if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { return []; } if ( !documentIsXML && !seed ) { // Shortcuts if ( (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Speed-up: Sizzle("TAG") } else if ( match[2] ) { push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); return results; // Speed-up: Sizzle(".CLASS") } else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) { push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); return results; } } // QSA path if ( support.qsa && !rbuggyQSA.test(selector) ) { old = true; nid = expando; newContext = context; newSelector = nodeType === 9 && selector; // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { groups = tokenize( selector ); if ( (old = context.getAttribute("id")) ) { nid = old.replace( rescape, "\\$&" ); } else { context.setAttribute( "id", nid ); } nid = "[id='" + nid + "'] "; i = groups.length; while ( i-- ) { groups[i] = nid + toSelector( groups[i] ); } newContext = rsibling.test( selector ) && context.parentNode || context; newSelector = groups.join(","); } if ( newSelector ) { try { push.apply( results, slice.call( newContext.querySelectorAll( newSelector ), 0 ) ); return results; } catch(qsaError) { } finally { if ( !old ) { context.removeAttribute("id"); } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Detect xml * @param {Element|Object} elem An element or a document */ isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { var doc = node ? node.ownerDocument || node : preferredDoc; // If no document and documentElement is available, return if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } // Set our document document = doc; docElem = doc.documentElement; // Support tests documentIsXML = isXML( doc ); // Check if getElementsByTagName("*") returns only elements support.tagNameNoComments = assert(function( div ) { div.appendChild( doc.createComment("") ); return !div.getElementsByTagName("*").length; }); // Check if attributes should be retrieved by attribute nodes support.attributes = assert(function( div ) { div.innerHTML = ""; var type = typeof div.lastChild.getAttribute("multiple"); // IE8 returns a string for some attributes even when not present return type !== "boolean" && type !== "string"; }); // Check if getElementsByClassName can be trusted support.getByClassName = assert(function( div ) { // Opera can't find a second classname (in 9.6) div.innerHTML = ""; if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { return false; } // Safari 3.2 caches class attributes and doesn't catch changes div.lastChild.className = "e"; return div.getElementsByClassName("e").length === 2; }); // Check if getElementById returns elements by name // Check if getElementsByName privileges form controls or returns elements by ID support.getByName = assert(function( div ) { // Inject content div.id = expando + 0; div.innerHTML = "
"; docElem.insertBefore( div, docElem.firstChild ); // Test var pass = doc.getElementsByName && // buggy browsers will return fewer than the correct 2 doc.getElementsByName( expando ).length === 2 + // buggy browsers will return more than the correct 0 doc.getElementsByName( expando + 0 ).length; support.getIdNotName = !doc.getElementById( expando ); // Cleanup docElem.removeChild( div ); return pass; }); // IE6/7 return modified attributes Expr.attrHandle = assert(function( div ) { div.innerHTML = ""; return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && div.firstChild.getAttribute("href") === "#"; }) ? {} : { "href": function( elem ) { return elem.getAttribute( "href", 2 ); }, "type": function( elem ) { return elem.getAttribute("type"); } }; // ID find and filter if ( support.getIdNotName ) { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== strundefined && !documentIsXML ) { var m = context.getElementById( id ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 return m && m.parentNode ? [m] : []; } }; Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute("id") === attrId; }; }; } else { Expr.find["ID"] = function( id, context ) { if ( typeof context.getElementById !== strundefined && !documentIsXML ) { var m = context.getElementById( id ); return m ? m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? [m] : undefined : []; } }; Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; } // Tag Expr.find["TAG"] = support.tagNameNoComments ? function( tag, context ) { if ( typeof context.getElementsByTagName !== strundefined ) { return context.getElementsByTagName( tag ); } } : function( tag, context ) { var elem, tmp = [], i = 0, results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { while ( (elem = results[i++]) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; }; // Name Expr.find["NAME"] = support.getByName && function( tag, context ) { if ( typeof context.getElementsByName !== strundefined ) { return context.getElementsByName( name ); } }; // Class Expr.find["CLASS"] = support.getByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) { return context.getElementsByClassName( className ); } }; // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21), // no need to also add to buggyMatches since matches checks buggyQSA // A support test would require too much code (would include document ready) rbuggyQSA = [ ":focus" ]; if ( (support.qsa = isNative(doc.querySelectorAll)) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function( div ) { // Select is set to empty string on purpose // This is to test IE's treatment of not explictly // setting a boolean content attribute, // since its presence should be enough // http://bugs.jquery.com/ticket/12359 div.innerHTML = ""; // IE8 - Some boolean attributes are not treated correctly if ( !div.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } }); assert(function( div ) { // Opera 10-12/IE8 - ^= $= *= and empty values // Should not select anything div.innerHTML = ""; if ( div.querySelectorAll("[i^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":enabled").length ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Opera 10-11 does not throw on post-comma invalid pseudos div.querySelectorAll("*,:x"); rbuggyQSA.push(",.*:"); }); } if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector || docElem.mozMatchesSelector || docElem.webkitMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector) )) ) { assert(function( div ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( div, "div" ); // This should fail with an exception // Gecko does not error, returns false instead matches.call( div, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); }); } rbuggyQSA = new RegExp( rbuggyQSA.join("|") ); rbuggyMatches = new RegExp( rbuggyMatches.join("|") ); // Element contains another // Purposefully does not implement inclusive descendent // As in, an element does not contain itself contains = isNative(docElem.contains) || docElem.compareDocumentPosition ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 )); } : function( a, b ) { if ( b ) { while ( (b = b.parentNode) ) { if ( b === a ) { return true; } } } return false; }; // Document order sorting sortOrder = docElem.compareDocumentPosition ? function( a, b ) { var compare; if ( a === b ) { hasDuplicate = true; return 0; } if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) { if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) { if ( a === doc || contains( preferredDoc, a ) ) { return -1; } if ( b === doc || contains( preferredDoc, b ) ) { return 1; } return 0; } return compare & 4 ? -1 : 1; } return a.compareDocumentPosition ? -1 : 1; } : function( a, b ) { var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; // Parentless nodes are either documents or disconnected } else if ( !aup || !bup ) { return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : 0; // If the nodes are siblings, we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); } // Otherwise we need full lists of their ancestors for comparison cur = a; while ( (cur = cur.parentNode) ) { ap.unshift( cur ); } cur = b; while ( (cur = cur.parentNode) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy while ( ap[i] === bp[i] ) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck( ap[i], bp[i] ) : // Otherwise nodes in our document sort first ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; // Always assume the presence of duplicates if sort doesn't // pass them to our comparison function (as in Google Chrome). hasDuplicate = false; [0, 0].sort( sortOrder ); support.detectDuplicates = hasDuplicate; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } // Make sure that attribute selectors are quoted expr = expr.replace( rattributeQuotes, "='$1']" ); // rbuggyQSA always contains :focus, so no need for an existence check if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch(e) {} } return Sizzle( expr, document, null, [elem] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed if ( ( context.ownerDocument || context ) !== document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { var val; // Set document vars if needed if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } if ( !documentIsXML ) { name = name.toLowerCase(); } if ( (val = Expr.attrHandle[ name ]) ) { return val( elem ); } if ( documentIsXML || support.attributes ) { return elem.getAttribute( name ); } return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ? name : val && val.specified ? val.value : null; }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; // Document sorting and removing duplicates Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], i = 1, j = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; results.sort( sortOrder ); if ( hasDuplicate ) { for ( ; (elem = results[i]); i++ ) { if ( elem === results[ i - 1 ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } return results; }; function siblingCheck( a, b ) { var cur = b && a, diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE ); // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } // Check if b follows a if ( cur ) { while ( (cur = cur.nextSibling) ) { if ( cur === b ) { return -1; } } } return a ? 1 : -1; } // Returns a function to use in pseudos for input types function createInputPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } // Returns a function to use in pseudos for buttons function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; } // Returns a function to use in pseudos for positionals function createPositionalPseudo( fn ) { return markFunction(function( argument ) { argument = +argument; return markFunction(function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ (j = matchIndexes[i]) ] ) { seed[j] = !(matches[j] = seed[j]); } } }); }); } /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array for ( ; (node = elem[i]); i++ ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (see #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[1] = match[1].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); if ( match[2] === "~=" ) { match[3] = " " + match[3] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[1] = match[1].toLowerCase(); if ( match[1].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[3] ) { Sizzle.error( match[0] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); // other types prohibit arguments } else if ( match[3] ) { Sizzle.error( match[0] ); } return match; }, "PSEUDO": function( match ) { var excess, unquoted = !match[5] && match[2]; if ( matchExpr["CHILD"].test( match[0] ) ) { return null; } // Accept quoted arguments as-is if ( match[4] ) { match[2] = match[4]; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) (excess = tokenize( unquoted, true )) && // advance to the next closing parenthesis (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { // excess is a negative index match[0] = match[0].slice( 0, excess ); match[2] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }, filter: { "TAG": function( nodeName ) { if ( nodeName === "*" ) { return function() { return true; }; } nodeName = nodeName.replace( runescape, funescape ).toLowerCase(); return function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className + " " ]; return pattern || (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && classCache( className, function( elem ) { return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); }); }, "ATTR": function( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; }; }, "CHILD": function( type, what, argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, context, xml ) { var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( (node = node[ dir ]) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index outerCache = parent[ expando ] || (parent[ expando ] = {}); cache = outerCache[ type ] || []; nodeIndex = cache[0] === dirruns && cache[1]; diff = cache[0] === dirruns && cache[2]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( (node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start (diff = nodeIndex = 0) || start.pop()) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { outerCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } // Use previously-cached element index if available } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { diff = cache[1]; // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) } else { // Use the same loop as above to seek `elem` from the start while ( (node = ++nodeIndex && node && node[ dir ] || (diff = nodeIndex = 0) || start.pop()) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || Sizzle.error( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if ( fn[ expando ] ) { return fn( argument ); } // But maintain support for old signatures if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? markFunction(function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { idx = indexOf.call( seed, matched[i] ); seed[ idx ] = !( matches[ idx ] = matched[i] ); } }) : function( elem ) { return fn( elem, 0, args ); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction(function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? markFunction(function( seed, matches, context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( (elem = unmatched[i]) ) { seed[i] = !(matches[i] = elem); } } }) : function( elem, context, xml ) { input[0] = elem; matcher( input, null, xml, results ); return !results.pop(); }; }), "has": markFunction(function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; }), "contains": markFunction(function( text ) { return function( elem ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; }), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifider if ( !ridentifier.test(lang || "") ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( (elemLang = documentIsXML ? elem.getAttribute("xml:lang") || elem.getAttribute("lang") : elem.lang) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); return false; }; }), // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( elem ) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, // Boolean properties "enabled": function( elem ) { return elem.disabled === false; }, "disabled": function( elem ) { return elem.disabled === true; }, "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), // not comment, processing instructions, or others // Thanks to Diego Perini for the nodeName shortcut // Greater than "@" means alpha characters (specifically not starting with "#" or "?") for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { return false; } } return true; }, "parent": function( elem ) { return !Expr.pseudos["empty"]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( elem ) { var attr; // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) // use getAttribute instead to test this case return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); }, // Position-in-collection "first": createPositionalPseudo(function() { return [ 0 ]; }), "last": createPositionalPseudo(function( matchIndexes, length ) { return [ length - 1 ]; }), "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; }), "even": createPositionalPseudo(function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "odd": createPositionalPseudo(function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; }), "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; }), "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; }) } }; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { Expr.pseudos[ i ] = createButtonPseudo( i ); } function tokenize( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = Expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || (match = rcomma.exec( soFar )) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[0].length ) || soFar; } groups.push( tokens = [] ); } matched = false; // Combinators if ( (match = rcombinators.exec( soFar )) ) { matched = match.shift(); tokens.push( { value: matched, // Cast descendant combinators to space type: match[0].replace( rtrim, " " ) } ); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { matched = match.shift(); tokens.push( { value: matched, type: type, matches: match } ); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); } function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[i].value; } return selector; } function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, checkNonElements = base && dir === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var data, cache, outerCache, dirkey = dirruns + " " + doneName; // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching if ( xml ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { if ( (data = cache[1]) === true || data === cachedruns ) { return data === true; } } else { cache = outerCache[ dir ] = [ dirkey ]; cache[1] = matcher( elem, context, xml ) || cachedruns; if ( cache[1] === true ) { return true; } } } } } }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[i]( elem, context, xml ) ) { return false; } } return true; } : matchers[0]; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( (elem = unmatched[i]) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction(function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if ( matcher ) { matcher( matcherIn, matcherOut, context, xml ); } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( (elem = temp[i]) ) { matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) ) { // Restore matcherIn since elem is not yet a final match temp.push( (matcherIn[i] = elem) ); } } postFinder( null, (matcherOut = []), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) && (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { seed[temp] = !(results[temp] = elem); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } }); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[ tokens[0].type ], implicitRelative = leadingRelative || Expr.relative[" "], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf.call( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( (checkContext = context).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); } ]; for ( ; i < len; i++ ) { if ( (matcher = Expr.relative[ tokens[i].type ]) ) { matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; } else { matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( Expr.relative[ tokens[j].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { // A counter to specify which element is currently being matched var matcherCachedRuns = 0, bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, expandContext ) { var elem, j, matcher, setMatched = [], matchedCount = 0, i = "0", unmatched = seed && [], outermost = expandContext != null, contextBackup = outermostContext, // We must always have either seed elements or context elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); if ( outermost ) { outermostContext = context !== document && context; cachedruns = matcherCachedRuns; } // Add elements passing elementMatchers directly to results // Keep `i` a string if there are no elements so `matchedCount` will be "00" below for ( ; (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; while ( (matcher = elementMatchers[j++]) ) { if ( matcher( elem, context, xml ) ) { results.push( elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; cachedruns = ++matcherCachedRuns; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( (elem = !matcher && elem) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // Apply set filters to unmatched elements matchedCount += i; if ( bySet && i !== matchedCount ) { j = 0; while ( (matcher = setMatchers[j++]) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !(unmatched[i] || setMatched[i]) ) { setMatched[i] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { Sizzle.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !group ) { group = tokenize( selector ); } i = group.length; while ( i-- ) { cached = matcherFromTokens( group[i] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); } return cached; }; function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[i], results ); } return results; } function select( selector, context, results, seed ) { var i, tokens, token, type, find, match = tokenize( selector ); if ( !seed ) { // Try to minimize operations if there is only one group if ( match.length === 1 ) { // Take a shortcut and set the context if the root selector is an ID tokens = match[0] = match[0].slice( 0 ); if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && !documentIsXML && Expr.relative[ tokens[1].type ] ) { context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0]; if ( !context ) { return results; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[i]; // Abort if we hit a combinator if ( Expr.relative[ (type = token.type) ] ) { break; } if ( (find = Expr.find[ type ]) ) { // Search, expanding context for leading sibling combinators if ( (seed = find( token.matches[0].replace( runescape, funescape ), rsibling.test( tokens[0].type ) && context.parentNode || context )) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, slice.call( seed, 0 ) ); return results; } break; } } } } } // Compile and execute a filtering function // Provide `match` to avoid retokenization if we modified the selector above compile( selector, match )( seed, context, documentIsXML, results, rsibling.test( selector ) ); return results; } // Deprecated Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Easy API for creating new setFilters function setFilters() {} Expr.filters = setFilters.prototype = Expr.pseudos; Expr.setFilters = new setFilters(); // Initialize with the default document setDocument(); // Override sizzle attribute retrieval Sizzle.attr = jQuery.attr; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.pseudos; jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; })( window ); var runtil = /Until$/, rparentsprev = /^(?:parents|prev(?:Until|All))/, isSimple = /^.[^:#\[\.,]*$/, rneedsContext = jQuery.expr.match.needsContext, // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend({ find: function( selector ) { var i, ret, self, len = this.length; if ( typeof selector !== "string" ) { self = this; return this.pushStack( jQuery( selector ).filter(function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }) ); } ret = []; for ( i = 0; i < len; i++ ) { jQuery.find( selector, this[ i ], ret ); } // Needed because $( selector, context ) becomes $( context ).find( selector ) ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; return ret; }, has: function( target ) { var i, targets = jQuery( target, this ), len = targets.length; return this.filter(function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { return true; } } }); }, not: function( selector ) { return this.pushStack( winnow(this, selector, false) ); }, filter: function( selector ) { return this.pushStack( winnow(this, selector, true) ); }, is: function( selector ) { return !!selector && ( typeof selector === "string" ? // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". rneedsContext.test( selector ) ? jQuery( selector, this.context ).index( this[0] ) >= 0 : jQuery.filter( selector, this ).length > 0 : this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, ret = [], pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? jQuery( selectors, context || this.context ) : 0; for ( ; i < l; i++ ) { cur = this[i]; while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; } cur = cur.parentNode; } } return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); }, // Determine the position of an element within // the matched set of elements index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; } // index in selector if ( typeof elem === "string" ) { return jQuery.inArray( this[0], jQuery( elem ) ); } // Locate the position of the desired element return jQuery.inArray( // If it receives a jQuery object, the first element is used elem.jquery ? elem[0] : elem, this ); }, add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( jQuery.unique(all) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter(selector) ); } }); jQuery.fn.andSelf = jQuery.fn.addBack; function sibling( cur, dir ) { do { cur = cur[ dir ]; } while ( cur && cur.nodeType !== 1 ); return cur; } jQuery.each({ parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return jQuery.dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { return jQuery.dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return jQuery.dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return jQuery.dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { return jQuery.dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { return jQuery.dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return jQuery.sibling( elem.firstChild ); }, contents: function( elem ) { return jQuery.nodeName( elem, "iframe" ) ? elem.contentDocument || elem.contentWindow.document : jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var ret = jQuery.map( this, fn, until ); if ( !runtil.test( name ) ) { selector = until; } if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); } ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse(); } return this.pushStack( ret ); }; }); jQuery.extend({ filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } return elems.length === 1 ? jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : jQuery.find.matches(expr, elems); }, dir: function( elem, dir, until ) { var matched = [], cur = elem[ dir ]; while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { if ( cur.nodeType === 1 ) { matched.push( cur ); } cur = cur[dir]; } return matched; }, sibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { r.push( n ); } } return r; } }); // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { // Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier || 0; if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem ) { return ( elem === qualifier ) === keep; }); } else if ( typeof qualifier === "string" ) { var filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); if ( isSimple.test( qualifier ) ) { return jQuery.filter(qualifier, filtered, !keep); } else { qualifier = jQuery.filter( qualifier, filtered ); } } return jQuery.grep(elements, function( elem ) { return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; }); } function createSafeFragment( document ) { var list = nodeNames.split( "|" ), safeFrag = document.createDocumentFragment(); if ( safeFrag.createElement ) { while ( list.length ) { safeFrag.createElement( list.pop() ); } } return safeFrag; } var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, rtagName = /<([\w:]+)/, rtbody = /\s*$/g, // We have to close these tags to support XHTML (#13200) wrapMap = { option: [ 1, "" ], legend: [ 1, "
", "
" ], area: [ 1, "", "" ], param: [ 1, "", "" ], thead: [ 1, "", "
" ], tr: [ 2, "", "
" ], col: [ 2, "", "
" ], td: [ 3, "", "
" ], // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] }, safeFragment = createSafeFragment( document ), fragmentDiv = safeFragment.appendChild( document.createElement("div") ); wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; jQuery.fn.extend({ text: function( value ) { return jQuery.access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); }, null, value, arguments.length ); }, wrapAll: function( html ) { if ( jQuery.isFunction( html ) ) { return this.each(function(i) { jQuery(this).wrapAll( html.call(this, i) ); }); } if ( this[0] ) { // The elements to wrap the target around var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); if ( this[0].parentNode ) { wrap.insertBefore( this[0] ); } wrap.map(function() { var elem = this; while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { elem = elem.firstChild; } return elem; }).append( this ); } return this; }, wrapInner: function( html ) { if ( jQuery.isFunction( html ) ) { return this.each(function(i) { jQuery(this).wrapInner( html.call(this, i) ); }); } return this.each(function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } }); }, wrap: function( html ) { var isFunction = jQuery.isFunction( html ); return this.each(function(i) { jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); }); }, unwrap: function() { return this.parent().each(function() { if ( !jQuery.nodeName( this, "body" ) ) { jQuery( this ).replaceWith( this.childNodes ); } }).end(); }, append: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.appendChild( elem ); } }); }, prepend: function() { return this.domManip(arguments, true, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.insertBefore( elem, this.firstChild ); } }); }, before: function() { return this.domManip( arguments, false, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } }); }, after: function() { return this.domManip( arguments, false, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } }); }, // keepData is for internal use only--do not document remove: function( selector, keepData ) { var elem, i = 0; for ( ; (elem = this[i]) != null; i++ ) { if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) { if ( !keepData && elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem ) ); } if ( elem.parentNode ) { if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { setGlobalEval( getAll( elem, "script" ) ); } elem.parentNode.removeChild( elem ); } } } return this; }, empty: function() { var elem, i = 0; for ( ; (elem = this[i]) != null; i++ ) { // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); } // Remove any remaining nodes while ( elem.firstChild ) { elem.removeChild( elem.firstChild ); } // If this is a select, ensure that it displays empty (#12336) // Support: IE<9 if ( elem.options && jQuery.nodeName( elem, "select" ) ) { elem.options.length = 0; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function () { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); }); }, html: function( value ) { return jQuery.access( this, function( value ) { var elem = this[0] || {}, i = 0, l = this.length; if ( value === undefined ) { return elem.nodeType === 1 ? elem.innerHTML.replace( rinlinejQuery, "" ) : undefined; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { value = value.replace( rxhtmlTag, "<$1>" ); try { for (; i < l; i++ ) { // Remove element nodes and prevent memory leaks elem = this[i] || {}; if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch(e) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function( value ) { var isFunc = jQuery.isFunction( value ); // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( !isFunc && typeof value !== "string" ) { value = jQuery( value ).not( this ).detach(); } return this.domManip( [ value ], true, function( elem ) { var next = this.nextSibling, parent = this.parentNode; if ( parent ) { jQuery( this ).remove(); parent.insertBefore( elem, next ); } }); }, detach: function( selector ) { return this.remove( selector, true ); }, domManip: function( args, table, callback ) { // Flatten any nested arrays args = core_concat.apply( [], args ); var first, node, hasScripts, scripts, doc, fragment, i = 0, l = this.length, set = this, iNoClone = l - 1, value = args[0], isFunction = jQuery.isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { return this.each(function( index ) { var self = set.eq( index ); if ( isFunction ) { args[0] = value.call( this, index, table ? self.html() : undefined ); } self.domManip( args, table, callback ); }); } if ( l ) { fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } if ( first ) { table = table && jQuery.nodeName( first, "tr" ); scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( table && jQuery.nodeName( this[i], "table" ) ? findOrAppend( this[i], "tbody" ) : this[i], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Reenable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src ) { // Hope ajax is available... jQuery.ajax({ url: node.src, type: "GET", dataType: "script", async: false, global: false, "throws": true }); } else { jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); } } } } // Fix #11809: Avoid leaking memory fragment = first = null; } } return this; } }); function findOrAppend( elem, tag ) { return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { var attr = elem.getAttributeNode("type"); elem.type = ( attr && attr.specified ) + "/" + elem.type; return elem; } function restoreScript( elem ) { var match = rscriptTypeMasked.exec( elem.type ); if ( match ) { elem.type = match[1]; } else { elem.removeAttribute("type"); } return elem; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var elem, i = 0; for ( ; (elem = elems[i]) != null; i++ ) { jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); } } function cloneCopyEvent( src, dest ) { if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { return; } var type, i, l, oldData = jQuery._data( src ), curData = jQuery._data( dest, oldData ), events = oldData.events; if ( events ) { delete curData.handle; curData.events = {}; for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } // make the cloned public data object a copy from the original if ( curData.data ) { curData.data = jQuery.extend( {}, curData.data ); } } function fixCloneNodeIssues( src, dest ) { var nodeName, e, data; // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { return; } nodeName = dest.nodeName.toLowerCase(); // IE6-8 copies events bound via attachEvent when using cloneNode. if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { data = jQuery._data( dest ); for ( e in data.events ) { jQuery.removeEvent( dest, e, data.handle ); } // Event data gets referenced instead of copied if the expando gets copied too dest.removeAttribute( jQuery.expando ); } // IE blanks contents when cloning scripts, and tries to evaluate newly-set text if ( nodeName === "script" && dest.text !== src.text ) { disableScript( dest ).text = src.text; restoreScript( dest ); // IE6-10 improperly clones children of object elements using classid. // IE10 throws NoModificationAllowedError if parent is null, #12132. } else if ( nodeName === "object" ) { if ( dest.parentNode ) { dest.outerHTML = src.outerHTML; } // This path appears unavoidable for IE9. When cloning an object // element in IE9, the outerHTML strategy above is not sufficient. // If the src has innerHTML and the destination does not, // copy the src.innerHTML into the dest.innerHTML. #10324 if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { dest.innerHTML = src.innerHTML; } } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set dest.defaultChecked = dest.checked = src.checked; // IE6-7 get confused and end up setting the value of a cloned // checkbox/radio button to an empty string instead of "on" if ( dest.value !== src.value ) { dest.value = src.value; } // IE6-8 fails to return the selected option to the default selected // state when cloning options } else if ( nodeName === "option" ) { dest.defaultSelected = dest.selected = src.defaultSelected; // IE6-8 fails to set the defaultValue to the correct value when // cloning other types of input fields } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } jQuery.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, i = 0, ret = [], insert = jQuery( selector ), last = insert.length - 1; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone(true); jQuery( insert[i] )[ original ]( elems ); // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() core_push.apply( ret, elems.get() ); } return this.pushStack( ret ); }; }); function getAll( context, tag ) { var elems, elem, i = 0, found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : undefined; if ( !found ) { for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { if ( !tag || jQuery.nodeName( elem, tag ) ) { found.push( elem ); } else { jQuery.merge( found, getAll( elem, tag ) ); } } } return tag === undefined || tag && jQuery.nodeName( context, tag ) ? jQuery.merge( [ context ], found ) : found; } // Used in buildFragment, fixes the defaultChecked property function fixDefaultChecked( elem ) { if ( manipulation_rcheckableType.test( elem.type ) ) { elem.defaultChecked = elem.checked; } } jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var destElements, node, clone, i, srcElements, inPage = jQuery.contains( elem.ownerDocument, elem ); if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { clone = elem.cloneNode( true ); // IE<=8 does not properly clone detached, unknown element nodes } else { fragmentDiv.innerHTML = elem.outerHTML; fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); } if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); // Fix all IE cloning issues for ( i = 0; (node = srcElements[i]) != null; ++i ) { // Ensure that the destination node is not null; Fixes #9587 if ( destElements[i] ) { fixCloneNodeIssues( node, destElements[i] ); } } } // Copy the events from the original to the clone if ( dataAndEvents ) { if ( deepDataAndEvents ) { srcElements = srcElements || getAll( elem ); destElements = destElements || getAll( clone ); for ( i = 0; (node = srcElements[i]) != null; i++ ) { cloneCopyEvent( node, destElements[i] ); } } else { cloneCopyEvent( elem, clone ); } } // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } destElements = srcElements = node = null; // Return the cloned set return clone; }, buildFragment: function( elems, context, scripts, selection ) { var j, elem, contains, tmp, tag, tbody, wrap, l = elems.length, // Ensure a safe fragment safe = createSafeFragment( context ), nodes = [], i = 0; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( jQuery.type( elem ) === "object" ) { jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || safe.appendChild( context.createElement("div") ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; // Descend through wrappers to the right content j = wrap[0]; while ( j-- ) { tmp = tmp.lastChild; } // Manually add leading whitespace removed by IE if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); } // Remove IE's autoinserted from table fragments if ( !jQuery.support.tbody ) { // String was a , *may* have spurious elem = tag === "table" && !rtbody.test( elem ) ? tmp.firstChild : // String was a bare or wrap[1] === "
" && !rtbody.test( elem ) ? tmp : 0; j = elem && elem.childNodes.length; while ( j-- ) { if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { elem.removeChild( tbody ); } } } jQuery.merge( nodes, tmp.childNodes ); // Fix #12392 for WebKit and IE > 9 tmp.textContent = ""; // Fix #12392 for oldIE while ( tmp.firstChild ) { tmp.removeChild( tmp.firstChild ); } // Remember the top-level container for proper cleanup tmp = safe.lastChild; } } } // Fix #11356: Clear elements from fragment if ( tmp ) { safe.removeChild( tmp ); } // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); } i = 0; while ( (elem = nodes[ i++ ]) ) { // #4087 - If origin and destination elements are the same, and this is // that element, do not do anything if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { continue; } contains = jQuery.contains( elem.ownerDocument, elem ); // Append to fragment tmp = getAll( safe.appendChild( elem ), "script" ); // Preserve script evaluation history if ( contains ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( (elem = tmp[ j++ ]) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } tmp = null; return safe; }, cleanData: function( elems, /* internal */ acceptData ) { var elem, type, id, data, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, deleteExpando = jQuery.support.deleteExpando, special = jQuery.event.special; for ( ; (elem = elems[i]) != null; i++ ) { if ( acceptData || jQuery.acceptData( elem ) ) { id = elem[ internalKey ]; data = id && cache[ id ]; if ( data ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Remove cache only if it was not already removed by jQuery.event.remove if ( cache[ id ] ) { delete cache[ id ]; // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases if ( deleteExpando ) { delete elem[ internalKey ]; } else if ( typeof elem.removeAttribute !== core_strundefined ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } core_deletedIds.push( id ); } } } } } }); var iframe, getStyles, curCSS, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity\s*=\s*([^)]*)/, rposition = /^(top|right|bottom|left)$/, // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rmargin = /^margin/, rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), elemdisplay = { BODY: "block" }, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: 0, fontWeight: 400 }, cssExpand = [ "Top", "Right", "Bottom", "Left" ], cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; // return a css property mapped to a potentially vendor prefixed property function vendorPropName( style, name ) { // shortcut for names that are not vendor prefixed if ( name in style ) { return name; } // check for vendor prefixed names var capName = name.charAt(0).toUpperCase() + name.slice(1), origName = name, i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in style ) { return name; } } return origName; } function isHidden( elem, el ) { // isHidden might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); } function showHide( elements, show ) { var display, elem, hidden, values = [], index = 0, length = elements.length; for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } values[ index ] = jQuery._data( elem, "olddisplay" ); display = elem.style.display; if ( show ) { // Reset the inline display of this element to learn if it is // being hidden by cascaded rules or not if ( !values[ index ] && display === "none" ) { elem.style.display = ""; } // Set elements which have been overridden with display: none // in a stylesheet to whatever the default browser style is // for such an element if ( elem.style.display === "" && isHidden( elem ) ) { values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); } } else { if ( !values[ index ] ) { hidden = isHidden( elem ); if ( display && display !== "none" || !hidden ) { jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); } } } } // Set the display of most of the elements in a second loop // to avoid the constant reflow for ( index = 0; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } if ( !show || elem.style.display === "none" || elem.style.display === "" ) { elem.style.display = show ? values[ index ] || "" : "none"; } } return elements; } jQuery.fn.extend({ css: function( name, value ) { return jQuery.access( this, function( elem, name, value ) { var len, styles, map = {}, i = 0; if ( jQuery.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); }, show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { var bool = typeof state === "boolean"; return this.each(function() { if ( bool ? state : isHidden( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } }); } }); jQuery.extend({ // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Exclude the following css properties to add px cssNumber: { "columnCount": true, "fillOpacity": true, "fontWeight": true, "lineHeight": true, "opacity": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: { // normalize float css property "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" }, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = jQuery.camelCase( name ), style = elem.style; name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // convert relative number strings (+= or -=) to relative numbers. #7345 if ( type === "string" && (ret = rrelNum.exec( value )) ) { value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); // Fixes bug #9237 type = "number"; } // Make sure that NaN and null values aren't set. See: #7116 if ( value == null || type === "number" && isNaN( value ) ) { return; } // If a number was passed in, add 'px' to the (except for certain CSS properties) if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, // but it would mean to define eight (for every problematic property) identical functions if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { // Wrapped to prevent IE from throwing errors when 'invalid' values are provided // Fixes bug #5509 try { style[ name ] = value; } catch(e) {} } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var num, val, hooks, origName = jQuery.camelCase( name ); // Make sure that we're working with the right name name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } //convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Return, converting to number if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; } return val; }, // A method for quickly swapping in/out CSS properties to get correct calculations swap: function( elem, options, callback, args ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.apply( elem, args || [] ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; } }); // NOTE: we've included the "window" in window.getComputedStyle // because jsdom on node.js will break without it. if ( window.getComputedStyle ) { getStyles = function( elem ) { return window.getComputedStyle( elem, null ); }; curCSS = function( elem, name, _computed ) { var width, minWidth, maxWidth, computed = _computed || getStyles( elem ), // getPropertyValue is only needed for .css('filter') in IE9, see #12537 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, style = elem.style; if ( computed ) { if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret; }; } else if ( document.documentElement.currentStyle ) { getStyles = function( elem ) { return elem.currentStyle; }; curCSS = function( elem, name, _computed ) { var left, rs, rsLeft, computed = _computed || getStyles( elem ), ret = computed ? computed[ name ] : undefined, style = elem.style; // Avoid setting ret to empty string here // so we don't default to auto if ( ret == null && style && style[ name ] ) { ret = style[ name ]; } // From the awesome hack by Dean Edwards // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels // but not position css attributes, as those are proportional to the parent element instead // and we can't measure the parent instead because it might trigger a "stacking dolls" problem if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { // Remember the original values left = style.left; rs = elem.runtimeStyle; rsLeft = rs && rs.left; // Put in the new values to get a computed value out if ( rsLeft ) { rs.left = elem.currentStyle.left; } style.left = name === "fontSize" ? "1em" : ret; ret = style.pixelLeft + "px"; // Revert the changed values style.left = left; if ( rsLeft ) { rs.left = rsLeft; } } return ret === "" ? "auto" : ret; }; } function setPositiveNumber( elem, value, subtract ) { var matches = rnumsplit.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : value; } function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { var i = extra === ( isBorderBox ? "border" : "content" ) ? // If we already have the right measurement, avoid augmentation 4 : // Otherwise initialize for horizontal or vertical properties name === "width" ? 1 : 0, val = 0; for ( ; i < 4; i += 2 ) { // both box models exclude margin, so add it if we want it if ( extra === "margin" ) { val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); } if ( isBorderBox ) { // border-box includes padding, so remove it if we want content if ( extra === "content" ) { val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // at this point, extra isn't border nor margin, so remove border if ( extra !== "margin" ) { val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } else { // at this point, extra isn't content, so add padding val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // at this point, extra isn't content nor padding, so add border if ( extra !== "padding" ) { val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } return val; } function getWidthOrHeight( elem, name, extra ) { // Start with offset property, which is equivalent to the border-box value var valueIsBorderBox = true, val = name === "width" ? elem.offsetWidth : elem.offsetHeight, styles = getStyles( elem ), isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 if ( val <= 0 || val == null ) { // Fall back to computed then uncomputed css if necessary val = curCSS( elem, name, styles ); if ( val < 0 || val == null ) { val = elem.style[ name ]; } // Computed unit is not pixels. Stop here and return. if ( rnumnonpx.test(val) ) { return val; } // we need the check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); // Normalize "", auto, and prepare for extra val = parseFloat( val ) || 0; } // use the active box-sizing model to add/subtract irrelevant styles return ( val + augmentWidthOrHeight( elem, name, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles ) ) + "px"; } // Try to determine the default display value of an element function css_defaultDisplay( nodeName ) { var doc = document, display = elemdisplay[ nodeName ]; if ( !display ) { display = actualDisplay( nodeName, doc ); // If the simple way fails, read from inside an iframe if ( display === "none" || !display ) { // Use the already-created iframe if possible iframe = ( iframe || jQuery("")); } catch (e) { var form = document.createElement("form"), iframe = handler.iframe || (handler.iframe = document.createElement("iframe")); form.setAttribute("enctype", "multipart/form-data"); iframe.setAttribute("name", iframe.id = target); iframe.setAttribute("src", url); } iframe.style.position = "absolute"; iframe.style.left = iframe.style.top = "-10000px"; iframe.onload = onload; iframe.onerror = function (event) { if (isFunction(handler.onerror)) { handler.onerror(rpe, event || window.event); } }; iframe.onreadystatechange = function () { if (/loaded|complete/i.test(iframe.readyState)) { onload(); // wei : todo,将附件信息放到handler.attach } else if (isFunction(handler.onloadprogress)) { if (rpe.loaded < rpe.total) { ++rpe.loaded; } handler.onloadprogress(rpe, { readyState: { loading: 2, interactive: 3, loaded: 4, complete: 4 }[iframe.readyState] || 1 }); } }; form.setAttribute("action", handler.url); form.setAttribute("target", iframe.id); form.setAttribute("method", "post"); form.appendChild(handler.file); form.style.display = "none"; if (isFunction(handler.onloadstart)) { handler.onloadstart(rpe, {}); } with (document.body || document.documentElement) { appendChild(iframe); appendChild(form); form.submit(); } return handler; }; } xhr = null; return sendFile; })(Object.prototype.toString); var sendFiles = function (handler, maxSize, width, height) { var length = handler.files.length, i = 0, onload = handler.onload, onloadstart = handler.onloadstart; handler.current = 0; handler.total = 0; handler.sent = 0; while (handler.current < length) { handler.total += (handler.files[handler.current].fileSize || handler.files[handler.current].size); handler.current++; } handler.current = 0; if (length && handler.files[0].fileSize !== -1) { handler.file = handler.files[handler.current]; sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { handler.onloadstart = null; handler.sent += (handler.files[handler.current].fileSize || handler.files[handler.current].size); if (++handler.current < length) { handler.file = handler.files[handler.current]; sendFile(handler, maxSize, width, height).onload = arguments.callee; } else if (onload) { handler.onloadstart = onloadstart; handler.onload = onload; handler.onload(rpe, xhr); } }; } else if (length) { handler.total = length * 100; handler.file = handler.files[handler.current]; sendFile(handler, maxSize, width, height).onload = function (rpe, xhr) { var callee = arguments.callee; handler.onloadstart = null; handler.sent += 100; if (++handler.current < length) { if (/\b(chrome|safari)\b/i.test(navigator.userAgent)) { handler.iframe.parentNode.removeChild(handler.iframe); handler.iframe = null; } setTimeout(function () { handler.file = handler.files[handler.current]; sendFile(handler, maxSize, width, height).onload = callee; }, 15); } else if (onload) { setTimeout(function () { handler.iframe.parentNode.removeChild(handler.iframe); handler.iframe = null; handler.onloadstart = onloadstart; handler.onload = onload; handler.onload(rpe, xhr); }, 15); } }; } return handler; }; BI.File = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.File.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-file display-block", element: "", name: "", url: "", multiple: true, accept: "", /** '*.jpg; *.zip'**/ maxSize: -1 // 1024 * 1024 }); }, _init: function () { var self = this, o = this.options; BI.File.superclass._init.apply(this, arguments); if (o.multiple === true) { this.element.attr("multiple", "multiple"); } this.element.attr("name", o.name || this.getName()); }, mounted: function () { var self = this, o = this.options; // create the noswfupload.wrap Object // wrap.maxSize 文件大小限制 // wrap.maxlength 文件个数限制 var _wrap = this.wrap = this._wrap(this.element[0], o.maxSize); // fileType could contain whatever text but filter checks *.{extension} // if present // handlers _wrap.onloadstart = function (rpe, xhr) { // BI.Msg.toast("loadstart"); self.fireEvent(BI.File.EVENT_UPLOADSTART, arguments); }; _wrap.onprogress = function (rpe, xhr) { // BI.Msg.toast("onprogress"); // percent for each bar // fileSize is -1 only if browser does not support file info access // this if splits recent browsers from others if (this.file.fileSize !== -1) { // simulation property indicates when the progress event is fake if (rpe.simulation) { } else { } } else { // if fileSIze is -1 browser is using an iframe because it does // not support // files sent via Ajax (XMLHttpRequest) // We can still show some information } self.fireEvent(BI.File.EVENT_PROGRESS, { file: this.file, total: rpe.total, loaded: rpe.loaded, simulation: rpe.simulation }); }; // generated if there is something wrong during upload _wrap.onerror = function () { // just inform the user something was wrong self.fireEvent(BI.File.EVENT_ERROR); }; // generated when every file has been sent (one or more, it does not // matter) _wrap.onload = function (rpe, xhr) { var self_ = this; // just show everything is fine ... // ... and after a second reset the component setTimeout(function () { self_.clean(); // remove files from list self_.hide(); // hide progress bars and enable input file // BI.Msg.toast("onload"); self.fireEvent(BI.File.EVENT_UPLOADED); // enable again the submit button/element }, 1000); }; _wrap.url = o.url ? o.url : BI.servletURL + "?op=fr_attach&cmd=ah_upload"; _wrap.fileType = o.accept; // 文件类型限制 _wrap.attach_array = []; _wrap.attach_names = []; _wrap.attachNum = 0; }, _events: function (wrap) { var self = this; event.add(wrap.dom.input, "change", function () { event.del(wrap.dom.input, "change", arguments.callee); for (var input = wrap.dom.input.cloneNode(true), i = 0, files = F(wrap.dom.input); i < files.length; i++) { var item = files.item(i); var tempFile = item.value || item.name; var value = item.fileName || (item.fileName = tempFile.split("\\").pop()), ext = -1 !== value.indexOf(".") ? value.split(".").pop().toLowerCase() : "unknown", size = item.fileSize || item.size; if (wrap.fileType && -1 === wrap.fileType.indexOf("*." + ext)) { // 文件类型不支持 BI.Msg.toast(BI.i18nText("BI-Upload_File_Type_Error")); self.fireEvent(BI.File.EVENT_ERROR, { errorType: 0, file: item }); } else if (wrap.maxSize !== -1 && size && wrap.maxSize < size) { // 文件大小不支持 BI.Msg.toast(BI.i18nText("BI-Upload_File_Size_Error")); self.fireEvent(BI.File.EVENT_ERROR, { errorType: 1, file: item }); } else { wrap.files.unshift(item); // BI.Msg.toast(value); self.fireEvent(BI.File.EVENT_CHANGE, { file: item }); } } input.value = ""; wrap.dom.input.parentNode.replaceChild(input, wrap.dom.input); wrap.dom.input = input; event.add(wrap.dom.input, "change", arguments.callee); }); return wrap; }, _wrap: function () { var self = this, o = this.options; // be sure input accept multiple files var input = this.element[0]; if (o.multiple === true) { this.element.attr("multiple", "multiple"); } input.value = ""; // wrap Object return this._events({ // DOM namespace dom: { input: input, // input file disabled: false // internal use, checks input file state }, name: input.name, // name to send for each file ($_FILES[{name}] in the server) // maxSize is the maximum amount of bytes for each file maxSize: o.maxSize ? o.maxSize >> 0 : -1, files: [], // file list // remove every file from the noswfupload component clean: function () { this.files = []; }, // upload one file a time (which make progress possible rather than all files in one shot) // the handler is an object injected into the wrap one, could be the wrap itself or // something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...} upload: function (handler) { if (handler) { for (var key in handler) { this[key] = handler[key]; } } sendFiles(this, this.maxSize); return this; }, // hide progress bar (total + current) and enable files selection hide: function () { if (this.dom.disabled) { this.dom.disabled = false; this.dom.input.removeAttribute("disabled"); } }, // show progress bar and disable file selection (used during upload) // total and current are pixels used to style bars // totalProp and currentProp are properties to change, "height" by default show: function (total, current, totalProp, currentProp) { if (!this.dom.disabled) { this.dom.disabled = true; this.dom.input.setAttribute("disabled", "disabled"); } } }); }, select: function () { $(this.wrap.dom.input).click(); }, upload: function (handler) { this.wrap.upload(handler); }, getValue: function () { return this.wrap.attach_array; }, reset: function () { this.wrap.attach_array = []; this.wrap.attach_names = []; this.wrap.attachNum = 0; }, _setEnable: function (enable) { BI.File.superclass._setEnable.apply(this, arguments); if (enable === true) { this.element.attr("disabled", "disabled"); } else { this.element.removeAttr("disabled"); } } }); BI.File.EVENT_CHANGE = "BI.File.EVENT_CHANGE"; BI.File.EVENT_UPLOADSTART = "EVENT_UPLOADSTART"; BI.File.EVENT_ERROR = "EVENT_ERROR"; BI.File.EVENT_PROGRESS = "EVENT_PROGRESS"; BI.File.EVENT_UPLOADED = "EVENT_UPLOADED"; BI.shortcut("bi.file", BI.File); })();/** * guy * @class BI.Input 一个button和一行数 组成的一行listitem * @extends BI.Single * @type {*|void|Object} */ BI.Input = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.Input.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-input display-block", element: "", validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, // 按确定键能否退出编辑 allowBlank: false }); }, _init: function () { BI.Input.superclass._init.apply(this, arguments); var self = this; var ctrlKey = false; var inputEventValid = false; var _keydown = BI.debounce(function (keyCode) { self.onKeyDown(keyCode, ctrlKey); self._keydown_ = false; }, 300); var _clk = BI.debounce(BI.bind(this._click, this), BI.EVENT_RESPONSE_TIME, true); this._blurDebounce = BI.debounce(BI.bind(this._blur, this), BI.EVENT_RESPONSE_TIME, true); this.element .keydown(function (e) { inputEventValid = false; ctrlKey = e.ctrlKey; self.fireEvent(BI.Input.EVENT_QUICK_DOWN); }) .keyup(function (e) { if (!(inputEventValid && e.keyCode === BI.KeyCode.ENTER)) { self._keydown_ = true; _keydown(e.keyCode); } }) .on("input propertychange", function (e) { // 这个事件在input的属性发生改变的时候就会触发(class的变化也算) if(BI.isNotNull(e.keyCode)) { inputEventValid = true; self._keydown_ = true; _keydown(e.keyCode); } }) .click(function (e) { e.stopPropagation(); _clk(); }) .mousedown(function (e) { self.element.val(self.element.val()); }) .focusout(function (e) { self._blurDebounce(); }); if (BI.isKey(this.options.value) || BI.isEmptyString(this.options.value)) { this.setValue(this.options.value); } }, _focus: function () { this.element.addClass("bi-input-focus"); this._checkValidationOnValueChange(); this._isEditing = true; if (this.getValue() == "") { this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); this.fireEvent(BI.Input.EVENT_EMPTY); } this.fireEvent(BI.Input.EVENT_FOCUS); }, _blur: function () { var self = this; if (self._keydown_ === true) { BI.delay(blur, 300); } else { blur(); } function blur () { if (!self.isValid() && self.options.quitChecker.apply(self, [BI.trim(self.getValue())]) !== false) { self.element.val(self._lastValidValue ? self._lastValidValue : ""); self._checkValidationOnValueChange(); self._defaultState(); } self.element.removeClass("bi-input-focus"); self._isEditing = false; self._start = false; if (self.isValid()) { self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CONFIRM, self.getValue(), self); self.fireEvent(BI.Input.EVENT_CONFIRM); } self.fireEvent(BI.Input.EVENT_BLUR); } }, _click: function () { if (this._isEditing !== true) { this._focus(); this.selectAll(); this.fireEvent(BI.Input.EVENT_CLICK); } }, onClick: function () { this._click(); }, onKeyDown: function (keyCode, ctrlKey) { if (!this.isValid() || BI.trim(this._lastValidValue) !== BI.trim(this.getValue())) { this._checkValidationOnValueChange(); } if (this.isValid() && BI.trim(this.getValue()) !== "") { if (BI.trim(this.getValue()) !== this._lastValue && (!this._start || this._lastValue == null || this._lastValue === "") || (this._pause === true && !/(\s|\u00A0)$/.test(this.getValue()))) { this._start = true; this._pause = false; this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STARTEDIT, this.getValue(), this); this.fireEvent(BI.Input.EVENT_START); } } if (ctrlKey === true && keyCode === 86) {// ctrlKey+V this._valueChange(); } else { if (keyCode == BI.KeyCode.ENTER) { if (this.isValid() || this.options.quitChecker.apply(this, [BI.trim(this.getValue())]) !== false) { this.blur(); this.fireEvent(BI.Input.EVENT_ENTER); } else { this.fireEvent(BI.Input.EVENT_RESTRICT); } } if (keyCode == BI.KeyCode.SPACE) { this.fireEvent(BI.Input.EVENT_SPACE); } if (keyCode == BI.KeyCode.BACKSPACE && this._lastValue == "") { this.fireEvent(BI.Input.EVENT_REMOVE); } if (keyCode == BI.KeyCode.BACKSPACE || keyCode == BI.KeyCode.DELETE) { this.fireEvent(BI.Input.EVENT_BACKSPACE); } } this.fireEvent(BI.Input.EVENT_KEY_DOWN); if (BI.isEndWithBlank(this.getValue())) { this._pause = true; this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.PAUSE, "", this); this.fireEvent(BI.Input.EVENT_PAUSE); this._defaultState(); } else if ((keyCode === BI.KeyCode.BACKSPACE || keyCode === BI.KeyCode.DELETE) && BI.trim(this.getValue()) === "" && (this._lastValue !== null && BI.trim(this._lastValue) !== "")) { this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT, this.getValue(), this); this.fireEvent(BI.Input.EVENT_STOP); this._valueChange(); } else { this._valueChange(); } }, // 初始状态 _defaultState: function () { if (this.getValue() == "") { this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); this.fireEvent(BI.Input.EVENT_EMPTY); } this._lastValue = this.getValue(); this._lastSubmitValue = null; }, _valueChange: function () { if (this.isValid() && BI.trim(this.getValue()) !== this._lastSubmitValue) { this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, this.getValue(), this); this.fireEvent(BI.Input.EVENT_CHANGE); this._lastSubmitValue = BI.trim(this.getValue()); } if (this.getValue() == "") { this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EMPTY, this.getValue(), this); this.fireEvent(BI.Input.EVENT_EMPTY); } this._lastValue = this.getValue(); }, _checkValidationOnValueChange: function () { var o = this.options; var v = this.getValue(); this.setValid( (o.allowBlank === true && BI.trim(v) == "") || (BI.isNotEmptyString(BI.trim(v)) && (v === this._lastValidValue || o.validationChecker.apply(this, [BI.trim(v)]) !== false)) ); }, focus: function () { if (!this.element.is(":visible")) { throw new Error("input输入框在不可见下不能focus"); } if (!this._isEditing === true) { this.element.focus(); this._focus(); this.selectAll(); } }, blur: function () { if (!this.element.is(":visible")) { throw new Error("input输入框在不可见下不能blur"); } if (this._isEditing === true) { this.element.blur(); this._blurDebounce(); } }, selectAll: function () { if (!this.element.is(":visible")) { throw new Error("input输入框在不可见下不能select"); } this.element.select(); this._isEditing = true; }, setValue: function (textValue) { this.element.val(textValue); BI.nextTick(BI.bind(function () { this._checkValidationOnValueChange(); this._defaultState(); if (this.isValid()) { this._lastSubmitValue = this.getValue(); } }, this)); }, getValue: function () { return this.element.val() || ""; }, isEditing: function () { return this._isEditing; }, getLastValidValue: function () { return this._lastValidValue; }, _setValid: function () { BI.Input.superclass._setValid.apply(this, arguments); if (this.isValid()) { this._lastValidValue = this.getValue(); this.element.removeClass("bi-input-error"); this.fireEvent(BI.Input.EVENT_VALID, BI.trim(this.getValue()), this); } else { if (this._lastValidValue === this.getValue()) { this._lastValidValue = null; } this.element.addClass("bi-input-error"); this.fireEvent(BI.Input.EVENT_ERROR, BI.trim(this.getValue()), this); } }, _setEnable: function (b) { BI.Input.superclass._setEnable.apply(this, [b]); this.element[0].disabled = !b; } }); BI.Input.EVENT_CHANGE = "EVENT_CHANGE"; BI.Input.EVENT_FOCUS = "EVENT_FOCUS"; BI.Input.EVENT_CLICK = "EVENT_CLICK"; BI.Input.EVENT_BLUR = "EVENT_BLUR"; BI.Input.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.Input.EVENT_QUICK_DOWN = "EVENT_QUICK_DOWN"; BI.Input.EVENT_SPACE = "EVENT_SPACE"; BI.Input.EVENT_BACKSPACE = "EVENT_BACKSPACE"; BI.Input.EVENT_START = "EVENT_START"; BI.Input.EVENT_PAUSE = "EVENT_PAUSE"; BI.Input.EVENT_STOP = "EVENT_STOP"; BI.Input.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.Input.EVENT_REMOVE = "EVENT_REMOVE"; BI.Input.EVENT_EMPTY = "EVENT_EMPTY"; BI.Input.EVENT_VALID = "EVENT_VALID"; BI.Input.EVENT_ERROR = "EVENT_ERROR"; BI.Input.EVENT_ENTER = "EVENT_ENTER"; BI.Input.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.shortcut("bi.input", BI.Input);/** * guy * @extends BI.Single * @type {*|void|Object} */ BI.Radio = BI.inherit(BI.IconButton, { _defaultConfig: function () { var conf = BI.Radio.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-radio radio-icon", selected: false, handler: BI.emptyFn, width: 16, height: 16, iconWidth: 16, iconHeight: 16 }); }, _init: function () { BI.Radio.superclass._init.apply(this, arguments); }, doClick: function () { BI.Radio.superclass.doClick.apply(this, arguments); if(this.isValid()) { this.fireEvent(BI.Radio.EVENT_CHANGE); } } }); BI.Radio.EVENT_CHANGE = "Radio.EVENT_CHANGE"; BI.shortcut("bi.radio", BI.Radio);/** * Created by GUY on 2015/6/26. */ BI.Label = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.Label.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-label", textAlign: "center", whiteSpace: "nowrap", // normal or nowrap forceCenter: false, // 是否无论如何都要居中, 不考虑超出边界的情况, 在未知宽度和高度时有效 textWidth: null, textHeight: null, hgap: 0, vgap: 0, lgap: 0, rgap: 0, tgap: 0, bgap: 0, text: "", py: "", keyword: "" }); }, _createJson: function () { var o = this.options; return { type: "bi.text", textAlign: o.textAlign, whiteSpace: o.whiteSpace, lineHeight: o.textHeight, text: o.text, value: o.value, py: o.py, keyword: o.keyword }; }, _init: function () { BI.Label.superclass._init.apply(this, arguments); if (this.options.textAlign === "center") { this._createCenterEl(); } else { this._createNotCenterEl(); } }, _createCenterEl: function () { var o = this.options; var json = this._createJson(); if (BI.isNumber(o.width) && o.width > 0) { if (BI.isNumber(o.textWidth) && o.textWidth > 0) { if (BI.isNumber(o.height) && o.height > 0) { var gap = (o.width - o.textWidth) / 2; BI.createWidget({ type: "bi.adaptive", height: o.height, scrollable: o.whiteSpace === "normal", element: this, items: [ { el: (this.text = BI.createWidget(json)), left: gap + o.hgap + o.lgap, right: gap + o.hgap + o.rgap, top: o.vgap + o.tgap, bottom: o.vgap + o.bgap } ] }); this.element.css({"line-height": o.height + "px"}); return; } json.width = o.textWidth; BI.createWidget({ type: "bi.center_adapt", scrollable: o.whiteSpace === "normal", element: this, items: [ { el: (this.text = BI.createWidget(json)) } ] }); return; } if (o.whiteSpace == "normal") { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.center_adapt", scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, element: this, items: [this.text] }); return; } if (BI.isNumber(o.height) && o.height > 0) { this.element.css({ "line-height": o.height + "px" }); BI.createWidget({ type: "bi.absolute", scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), left: o.hgap + o.lgap, right: o.hgap + o.rgap, top: o.vgap + o.tgap, bottom: o.vgap + o.bgap }] }); return; } json.width = o.width - 2 * o.hgap; BI.createWidget({ type: "bi.center_adapt", scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)) }] }); return; } if (BI.isNumber(o.textWidth) && o.textWidth > 0) { json.width = o.textWidth; BI.createWidget({ type: "bi.center_adapt", scrollable: o.whiteSpace === "normal", element: this, items: [ { el: (this.text = BI.createWidget(json)) } ] }); return; } if (o.whiteSpace == "normal") { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.center_adapt", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, scrollable: o.whiteSpace === "normal", element: this, items: [this.text] }); return; } if (BI.isNumber(o.height) && o.height > 0) { if (BI.isNumber(o.textHeight) && o.textHeight > 0) { this.element.css({ "line-height": o.height + "px" }); BI.createWidget({ type: "bi.adaptive", height: o.height, scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), left: o.hgap + o.lgap, right: o.hgap + o.rgap, top: o.vgap + o.tgap, bottom: o.vgap + o.bgap }] }); return; } BI.extend(json, { hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap }); this.element.css({ "line-height": o.height + "px" }); this.text = BI.createWidget(BI.extend(json, { element: this })); BI.createWidget({ type: "bi.layout", element: this.text, scrollable: o.whiteSpace === "normal" }); return; } BI.extend(json, { hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap }); if (o.forceCenter) { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.center_adapt", element: this, items: [this.text] }); return; } this.text = BI.createWidget(BI.extend(json, { element: this })); BI.createWidget({ type: "bi.layout", element: this.text, scrollable: o.whiteSpace === "normal" }); }, _createNotCenterEl: function () { var o = this.options; var json = this._createJson(); if (BI.isNumber(o.width) && o.width > 0) { if (BI.isNumber(o.textWidth) && o.textWidth > 0) { if (BI.isNumber(o.height) && o.height > 0) { BI.createWidget({ type: "bi.adaptive", height: o.height, scrollable: o.whiteSpace === "normal", element: this, items: [ { el: (this.text = BI.createWidget(json)), left: o.hgap + o.lgap, right: o.hgap + o.rgap, top: o.vgap + o.tgap, bottom: o.vgap + o.bgap } ] }); this.element.css({"line-height": o.height + "px"}); return; } json.width = o.textWidth; BI.createWidget({ type: "bi.vertical_adapt", scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, element: this, items: [ { el: (this.text = BI.createWidget(json)) } ] }); return; } if (o.whiteSpace == "normal") { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.vertical_adapt", scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, element: this, items: [this.text] }); return; } if (BI.isNumber(o.height) && o.height > 0) { this.element.css({ "line-height": o.height + "px" }); BI.createWidget({ type: "bi.absolute", scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), left: o.hgap + o.lgap, right: o.hgap + o.rgap, top: o.vgap + o.tgap, bottom: o.vgap + o.bgap }] }); return; } json.width = o.width - 2 * o.hgap - o.lgap - o.rgap; BI.createWidget({ type: "bi.vertical_adapt", scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, element: this, items: [{ el: (this.text = BI.createWidget(json)) }] }); return; } if (BI.isNumber(o.textWidth) && o.textWidth > 0) { json.width = o.textWidth; BI.createWidget({ type: "bi.vertical_adapt", scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, element: this, items: [ { el: (this.text = BI.createWidget(json)) } ] }); return; } if (o.whiteSpace == "normal") { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.vertical_adapt", scrollable: o.whiteSpace === "normal", hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, element: this, items: [this.text] }); return; } if (BI.isNumber(o.height) && o.height > 0) { if (BI.isNumber(o.textHeight) && o.textHeight > 0) { this.element.css({ "line-height": o.height + "px" }); BI.createWidget({ type: "bi.adaptive", height: o.height, scrollable: o.whiteSpace === "normal", element: this, items: [{ el: (this.text = BI.createWidget(json)), left: o.hgap + o.lgap, right: o.hgap + o.rgap, top: o.vgap + o.tgap, bottom: o.vgap + o.bgap }] }); return; } BI.extend(json, { hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap }); this.element.css({ "line-height": o.height + "px" }); this.text = BI.createWidget(BI.extend(json, { element: this })); BI.createWidget({ type: "bi.layout", element: this.text, scrollable: o.whiteSpace === "normal" }); return; } BI.extend(json, { hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap }); if (o.forceCenter) { this.text = BI.createWidget(json); BI.createWidget({ type: "bi.vertical_adapt", element: this, items: [this.text] }); return; } this.text = BI.createWidget(BI.extend(json, { element: this })); BI.createWidget({ type: "bi.layout", element: this.text, scrollable: o.whiteSpace === "normal" }); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, setText: function (v) { this.options.text = v; this.text.setText(v); }, getText: function () { return this.options.text; }, setStyle: function (css) { this.text.setStyle(css); }, setValue: function (v) { BI.Label.superclass.setValue.apply(this, arguments); if (!this.isReadOnly()) { this.text.setValue(v); } }, populate: function () { BI.Label.superclass.populate.apply(this, arguments); } }); BI.shortcut("bi.label", BI.Label);/** * guy a元素 * @class BI.Link * @extends BI.Text */ BI.Link = BI.inherit(BI.Label, { _defaultConfig: function () { var conf = BI.Link.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-link", href: "", target: "_blank" }); }, _createJson: function () { var o = this.options; return { type: "bi.a", textAlign: o.textAlign, whiteSpace: o.whiteSpace, lineHeight: o.textHeight, text: o.text, keyword: o.keyword, value: o.value, py: o.py, href: o.href, target: o.target }; }, _init: function () { BI.Link.superclass._init.apply(this, arguments); } }); BI.shortcut("bi.link", BI.Link);/** * guy * 气泡提示 * @class BI.Bubble * @extends BI.Tip * @type {*|void|Object} */ BI.Bubble = BI.inherit(BI.Tip, { _defaultConfig: function () { return BI.extend(BI.Bubble.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-bubble", direction: "top", text: "", height: 35 }); }, _init: function () { BI.Bubble.superclass._init.apply(this, arguments); var fn = function (e) { e.stopPropagation(); e.stopEvent(); return false; }; this.element.bind({click: fn, mousedown: fn, mouseup: fn, mouseover: fn, mouseenter: fn, mouseleave: fn, mousemove: fn}); BI.createWidget({ type: "bi.left", element: this, items: [this["_" + this.options.direction]()] }); }, _createBubbleText: function () { return (this.text = BI.createWidget({ type: "bi.label", cls: "bubble-text", text: this.options.text, hgap: 10, height: 30 })); }, _top: function () { return BI.createWidget({ type: "bi.vertical", items: [{ el: this._createBubbleText(), height: 30 }, { el: { type: "bi.layout" }, height: 3 }] }); }, _bottom: function () { return BI.createWidget({ type: "bi.vertical", items: [{ el: { type: "bi.layout" }, height: 3 }, { el: this._createBubbleText(), height: 30 }] }); }, _left: function () { return BI.createWidget({ type: "bi.right", items: [{ el: { type: "bi.layout", width: 3, height: 30 } }, { el: this._createBubbleText() }] }); }, _right: function () { return BI.createWidget({ type: "bi.left", items: [{ el: { type: "bi.layout", width: 3, height: 30 } }, { el: this._createBubbleText() }] }); }, setText: function (text) { this.text.setText(text); } }); BI.shortcut("bi.bubble", BI.Bubble);/** * toast提示 * * Created by GUY on 2015/9/7. * @class BI.Toast * @extends BI.Tip */ BI.Toast = BI.inherit(BI.Tip, { _const: { minWidth: 200, hgap: 20 }, _defaultConfig: function () { return BI.extend(BI.Toast.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-toast", text: "", level: "success", // success或warning height: 30 }); }, _init: function () { BI.Toast.superclass._init.apply(this, arguments); var o = this.options; this.element.css({ minWidth: this._const.minWidth + "px" }); this.element.addClass("toast-" + o.level); var fn = function (e) { e.stopPropagation(); e.stopEvent(); return false; }; this.element.bind({click: fn, mousedown: fn, mouseup: fn, mouseover: fn, mouseenter: fn, mouseleave: fn, mousemove: fn}); this.text = BI.createWidget({ type: "bi.label", element: this, text: o.text, height: 30, hgap: this._const.hgap }); }, setWidth: function (width) { this.element.width(width); }, setText: function (text) { this.text.setText(text); } }); BI.shortcut("bi.toast", BI.Toast);/** * toast提示 * * Created by GUY on 2015/9/7. * @class BI.Tooltip * @extends BI.Tip */ BI.Tooltip = BI.inherit(BI.Tip, { _const: { hgap: 10 }, _defaultConfig: function () { return BI.extend(BI.Tooltip.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-tooltip", text: "", level: "success", // success或warning stopEvent: false, stopPropagation: false, height: 20 }); }, _init: function () { BI.Tooltip.superclass._init.apply(this, arguments); var self = this, o = this.options; this.element.addClass("tooltip-" + o.level); var fn = function (e) { o.stopPropagation && e.stopPropagation(); o.stopEvent && e.stopEvent(); }; this.element.bind({ click: fn, mousedown: fn, mouseup: fn, mouseover: fn, mouseenter: fn, mouseleave: fn, mousemove: fn }); var texts = (o.text + "").split("\n"); if (texts.length > 1) { BI.createWidget({ type: "bi.vertical", element: this, hgap: this._const.hgap, items: BI.map(texts, function (i, text) { return { type: "bi.label", textAlign: "left", whiteSpace: "normal", text: text, textHeight: 16 }; }) }); } else { this.text = BI.createWidget({ type: "bi.label", element: this, textAlign: "left", whiteSpace: "normal", text: o.text, textHeight: 20, hgap: this._const.hgap }); } }, setWidth: function (width) { this.element.width(width - 2 * this._const.hgap); }, setText: function (text) { this.text && this.text.setText(text); }, setLevel: function (level) { this.element.removeClass("tooltip-success").removeClass("tooltip-warning"); this.element.addClass("tooltip-" + level); } }); BI.shortcut("bi.tooltip", BI.Tooltip);/** * 下拉 * @class BI.Trigger * @extends BI.Single * @abstract */ BI.Trigger = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.Trigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-trigger cursor-pointer", height: 24 }); }, _init: function () { BI.Trigger.superclass._init.apply(this, arguments); }, setKey: function () { }, getKey: function () { } });// CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: http://codemirror.net/LICENSE (function (mod) { mod(CodeMirror); })(function (CodeMirror) { var tables; var defaultTable; var keywords; var identifierQuote; var CONS = { QUERY_DIV: ";", ALIAS_KEYWORD: "AS" }; var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos; function isArray (val) { return Object.prototype.toString.call(val) == "[object Array]"; } function getKeywords (editor) { var mode = editor.doc.modeOption; if (mode === "sql") mode = "text/x-sql"; return CodeMirror.resolveMode(mode).keywords; } function getIdentifierQuote (editor) { var mode = editor.doc.modeOption; if (mode === "sql") mode = "text/x-sql"; return CodeMirror.resolveMode(mode).identifierQuote || "`"; } function getText (item) { return typeof item === "string" ? item : item.text; } function wrapTable (name, value) { if (isArray(value)) value = {columns: value}; if (!value.text) value.text = name; return value; } function parseTables (input) { var result = {}; if (isArray(input)) { for (var i = input.length - 1; i >= 0; i--) { var item = input[i]; result[getText(item).toUpperCase()] = wrapTable(getText(item), item); } } else if (input) { for (var name in input) {result[name.toUpperCase()] = wrapTable(name, input[name]);} } return result; } function getTable (name) { return tables[name.toUpperCase()]; } function shallowClone (object) { var result = {}; for (var key in object) { if (object.hasOwnProperty(key)) {result[key] = object[key];} } return result; } function match (string, word) { if (BI.isNotEmptyString(string) && word.length !== string.length) { var len = string.length; var sub = getText(word).substr(0, len); return string.toUpperCase() === sub.toUpperCase(); } } function addMatches (result, search, wordlist, formatter) { if (isArray(wordlist)) { for (var i = 0; i < wordlist.length; i++) {if (match(search, wordlist[i])) result.push(formatter(wordlist[i], i));} } else { for (var word in wordlist) { if (wordlist.hasOwnProperty(word)) { var val = wordlist[word]; if (!val || val === true) {val = word;} else {val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text;} if (match(search, val)) result.push(formatter(val)); } } } } function cleanName (name) { // Get rid name from identifierQuote and preceding dot(.) if (name.charAt(0) == ".") { name = name.substr(1); } // replace doublicated identifierQuotes with single identifierQuotes // and remove single identifierQuotes var nameParts = name.split(identifierQuote + identifierQuote); for (var i = 0; i < nameParts.length; i++) {nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote, "g"), "");} return nameParts.join(identifierQuote); } function insertIdentifierQuotes (name) { var nameParts = getText(name).split("."); for (var i = 0; i < nameParts.length; i++) { nameParts[i] = identifierQuote + // doublicate identifierQuotes nameParts[i].replace(new RegExp(identifierQuote, "g"), identifierQuote + identifierQuote) + identifierQuote; } var escaped = nameParts.join("."); if (typeof name === "string") return escaped; name = shallowClone(name); name.text = escaped; return name; } function nameCompletion (cur, token, result, editor) { // Try to complete table, column names and return start position of completion var useIdentifierQuotes = false; var nameParts = []; var start = token.start; var cont = true; while (cont) { cont = (token.string.charAt(0) == "."); useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote); start = token.start; nameParts.unshift(cleanName(token.string)); token = editor.getTokenAt(Pos(cur.line, token.start)); if (token.string == ".") { cont = true; token = editor.getTokenAt(Pos(cur.line, token.start)); } } // Try to complete table names var string = nameParts.join("."); addMatches(result, string, tables, function (w) { return useIdentifierQuotes ? insertIdentifierQuotes(w) : w; }); // Try to complete columns from defaultTable addMatches(result, string, defaultTable, function (w) { return useIdentifierQuotes ? insertIdentifierQuotes(w) : w; }); // Try to complete columns string = nameParts.pop(); var table = nameParts.join("."); var alias = false; var aliasTable = table; // Check if table is available. If not, find table by Alias if (!getTable(table)) { var oldTable = table; table = findTableByAlias(table, editor); if (table !== oldTable) alias = true; } var columns = getTable(table); if (columns && columns.columns) {columns = columns.columns;} if (columns) { addMatches(result, string, columns, function (w) { var tableInsert = table; if (alias == true) tableInsert = aliasTable; if (typeof w === "string") { w = tableInsert + "." + w; } else { w = shallowClone(w); w.text = tableInsert + "." + w.text; } return useIdentifierQuotes ? insertIdentifierQuotes(w) : w; }); } return start; } function eachWord (lineText, f) { var words = lineText.split(/\s+/); for (var i = 0; i < words.length; i++) {if (words[i]) f(words[i].replace(/[,;]/g, ""));} } function findTableByAlias (alias, editor) { var doc = editor.doc; var fullQuery = doc.getValue(); var aliasUpperCase = alias.toUpperCase(); var previousWord = ""; var table = ""; var separator = []; var validRange = { start: Pos(0, 0), end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length) }; // add separator var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV); while(indexOfSeparator != -1) { separator.push(doc.posFromIndex(indexOfSeparator)); indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator + 1); } separator.unshift(Pos(0, 0)); separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length)); // find valid range var prevItem = null; var current = editor.getCursor(); for (var i = 0; i < separator.length; i++) { if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) { validRange = {start: prevItem, end: separator[i]}; break; } prevItem = separator[i]; } var query = doc.getRange(validRange.start, validRange.end, false); for (var i = 0; i < query.length; i++) { var lineText = query[i]; eachWord(lineText, function (word) { var wordUpperCase = word.toUpperCase(); if (wordUpperCase === aliasUpperCase && getTable(previousWord)) {table = previousWord;} if (wordUpperCase !== CONS.ALIAS_KEYWORD) {previousWord = word;} }); if (table) break; } return table; } CodeMirror.registerHelper("hint", "sql", function (editor, options) { tables = parseTables(options && options.tables); var defaultTableName = options && options.defaultTable; var disableKeywords = options && options.disableKeywords; defaultTable = defaultTableName && getTable(defaultTableName); keywords = getKeywords(editor); var keywordsCount = BI.size(keywords); var functions = []; var cur = editor.getCursor(); var token = editor.getTokenAt(cur); if(options.supportFunction){ BI.each(BI.FormulaCollections, function (idx, formula) { if(formula.lastIndexOf(token.string, 0) == 0 && !BI.contains(functions, formula)) { functions.push(formula); } }); keywords = BI.concat(BI.keys(keywords), functions); } identifierQuote = getIdentifierQuote(editor); if (defaultTableName && !defaultTable) {defaultTable = findTableByAlias(defaultTableName, editor);} defaultTable = defaultTable || []; if (defaultTable.columns) {defaultTable = defaultTable.columns;} var result = []; var start, end, search; if (token.end > cur.ch) { token.end = cur.ch; token.string = token.string.slice(0, cur.ch - token.start); } if (token.string.match(/^[.`"\w@]\w*$/)) { search = token.string; start = token.start; end = token.end; } else { start = end = cur.ch; search = ""; } if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) { start = nameCompletion(cur, token, result, editor); } else { addMatches(result, search, tables, function (w) {return w;}); addMatches(result, search, defaultTable, function (w) {return w;}); if (!disableKeywords) { addMatches(result, search, keywords, function (w, i) { var isKeyword = i < keywordsCount; return { isKeyword: isKeyword, text: w // description: desc[w] || "SQL关键字", // className: isKeyword ? "sql-keyword" : "sql-fr-function", // render: function (Element, self, data) { // var label = BI.createWidget({ // type: "bi.label", // element: Element, // text: data.displayText || getText(data) // }); // label.setTitle(data.description, { // container: "body" // }); // } }; }); } } return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)}; }); }); // CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: http://codemirror.net/LICENSE (function (mod) { mod(CodeMirror); })(function (CodeMirror) { "use strict"; CodeMirror.defineMode("sql", function (config, parserConfig) { "use strict"; var client = parserConfig.client || {}, atoms = parserConfig.atoms || {"false": true, "true": true, "null": true}, builtin = parserConfig.builtin || {}, keywords = parserConfig.keywords || {}, operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/, support = parserConfig.support || {}, hooks = parserConfig.hooks || {}, dateSQL = parserConfig.dateSQL || {date: true, time: true, timestamp: true}, functions = parserConfig.functions || {}; function tokenBase (stream, state) { var ch = stream.next(); // call hooks from the mime type if (hooks[ch]) { var result = hooks[ch](stream, state); if (result !== false) return result; } if (support.hexNumber && ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/)) || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) { // hex // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html return "number"; } else if (support.binaryNumber && (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/)) || (ch == "0" && stream.match(/^b[01]+/)))) { // bitstring // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html return "number"; } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) { // numbers // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html stream.match(/^[0-9]*(\.[0-9]+)?([eE][-+]?[0-9]+)?/); support.decimallessFloat && stream.match(/^\.(?!\.)/); return "number"; } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) { // placeholders return "variable-3"; } else if (ch == "'" || (ch == "\"" && support.doubleQuote)) { // strings // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html state.tokenize = tokenLiteral(ch); return state.tokenize(stream, state); } else if ((((support.nCharCast && (ch == "n" || ch == "N")) || (support.charsetCast && ch == "_" && stream.match(/[a-z][a-z0-9]*/i))) && (stream.peek() == "'" || stream.peek() == "\""))) { // charset casting: _utf8'str', N'str', n'str' // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html return "keyword"; } else if (/^[\(\),\;\[\]]/.test(ch)) { // no highlighting return null; } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) { // 1-line comment stream.skipToEnd(); return "comment"; } else if ((support.commentHash && ch == "#") || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) { // 1-line comments // ref: https://kb.askmonty.org/en/comment-syntax/ stream.skipToEnd(); return "comment"; } else if (ch == "/" && stream.eat("*")) { // multi-line comments // ref: https://kb.askmonty.org/en/comment-syntax/ state.tokenize = tokenComment(1); return state.tokenize(stream, state); } else if (ch == ".") { // .1 for 0.1 if (support.zerolessFloat && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) {return "number";} if (stream.match(/^\.+/)) {return null;} // .table_name (ODBC) // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html if (support.ODBCdotTable && stream.match(/^[\w\d_]+/)) {return "variable-2";} } else if (operatorChars.test(ch)) { // operators stream.eatWhile(operatorChars); return null; } else if (ch == "{" && (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) { // dates (weird ODBC syntax) // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html return "number"; } else { stream.eatWhile(/^[_\w\d]/); var word = stream.current().toLowerCase(); // dates (standard SQL syntax) // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/))) {return "number";} if (atoms.hasOwnProperty(word)) return "atom"; if (builtin.hasOwnProperty(word)) return "builtin"; if (functions.hasOwnProperty(word) && stream.peek() === "(") return "function"; if (keywords.hasOwnProperty(word)) return "keyword"; if (client.hasOwnProperty(word)) return "string-2"; return null; } } // 'string', with char specified in quote escaped by '\' function tokenLiteral (quote) { return function (stream, state) { var escaped = false, ch; while ((ch = stream.next()) != null) { if (ch == quote && !escaped) { state.tokenize = tokenBase; break; } escaped = !escaped && ch == "\\"; } return "string"; }; } function tokenComment (depth) { return function (stream, state) { var m = stream.match(/^.*?(\/\*|\*\/)/); if (!m) stream.skipToEnd(); else if (m[1] == "/*") state.tokenize = tokenComment(depth + 1); else if (depth > 1) state.tokenize = tokenComment(depth - 1); else state.tokenize = tokenBase; return "comment"; }; } function pushContext (stream, state, type) { state.context = { prev: state.context, indent: stream.indentation(), col: stream.column(), type: type }; } function popContext (state) { state.indent = state.context.indent; state.context = state.context.prev; } return { startState: function () { return {tokenize: tokenBase, context: null}; }, token: function (stream, state) { if (stream.sol()) { if (state.context && state.context.align == null) {state.context.align = false;} } if (state.tokenize == tokenBase && stream.eatSpace()) return null; var style = state.tokenize(stream, state); if (style == "comment") return style; if (state.context && state.context.align == null) {state.context.align = true;} var tok = stream.current(); if (tok == "(") {pushContext(stream, state, ")");} else if (tok == "[") {pushContext(stream, state, "]");} else if (state.context && state.context.type == tok) {popContext(state);} return style; }, indent: function (state, textAfter) { var cx = state.context; if (!cx) return CodeMirror.Pass; var closing = textAfter.charAt(0) == cx.type; if (cx.align) return cx.col + (closing ? 0 : 1); return cx.indent + (closing ? 0 : config.indentUnit); }, blockCommentStart: "/*", blockCommentEnd: "*/", lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : "--" }; }); (function () { "use strict"; // `identifier` function hookIdentifier (stream) { // MySQL/MariaDB identifiers // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html var ch; while ((ch = stream.next()) != null) { if (ch == "`" && !stream.eat("`")) return "variable-2"; } stream.backUp(stream.current().length - 1); return stream.eatWhile(/\w/) ? "variable-2" : null; } // "identifier" function hookIdentifierDoublequote (stream) { // Standard SQL /SQLite identifiers // ref: http://web.archive.org/web/20160813185132/http://savage.net.au/SQL/sql-99.bnf.html#delimited%20identifier // ref: http://sqlite.org/lang_keywords.html var ch; while ((ch = stream.next()) != null) { if (ch == "\"" && !stream.eat("\"")) return "variable-2"; } stream.backUp(stream.current().length - 1); return stream.eatWhile(/\w/) ? "variable-2" : null; } // variable token function hookVar (stream) { // variables // @@prefix.varName @varName // varName can be quoted with ` or ' or " // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html if (stream.eat("@")) { stream.match(/^session\./); stream.match(/^local\./); stream.match(/^global\./); } if (stream.eat("'")) { stream.match(/^.*'/); return "variable-2"; } else if (stream.eat("\"")) { stream.match(/^.*"/); return "variable-2"; } else if (stream.eat("`")) { stream.match(/^.*`/); return "variable-2"; } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) { return "variable-2"; } return null; } // short client keyword token function hookClient (stream) { // \N means NULL // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html if (stream.eat("N")) { return "atom"; } // \g, etc // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null; } // these keywords are used by all SQL dialects (however, a mode can still overwrite it) var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit "; // turn a space-separated list into an array function set (str) { var obj = {}, words = str.split(" "); for (var i = 0; i < words.length; ++i) obj[words[i]] = true; return obj; } // A generic SQL Mode. It's not a standard, it just try to support what is generally supported CodeMirror.defineMIME("text/x-sql", { name: "sql", keywords: set(sqlKeywords + "begin"), builtin: set("bool boolean bit blob enum long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision real date datetime year unsigned signed decimal numeric"), atoms: set("false true null unknown"), operatorChars: /^[*+\-%<>!=]/, dateSQL: set("date time timestamp"), support: set("ODBCdotTable doubleQuote binaryNumber hexNumber"), functions: BI.makeObject(BI.FormulaCollections, true) }); }()); }); /* How Properties of Mime Types are used by SQL Mode ================================================= keywords: A list of keywords you want to be highlighted. builtin: A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword"). operatorChars: All characters that must be handled as operators. client: Commands parsed and executed by the client (not the server). support: A list of supported syntaxes which are not common, but are supported by more than 1 DBMS. * ODBCdotTable: .tableName * zerolessFloat: .1 * doubleQuote * nCharCast: N'string' * charsetCast: _utf8'string' * commentHash: use # char for comments * commentSlashSlash: use // for comments * commentSpaceRequired: require a space after -- for comments atoms: Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others: UNKNOWN, INFINITY, UNDERFLOW, NaN... dateSQL: Used for date/time SQL standard syntax, because not all DBMS's support same temporal types. */ /** * Created by Windy on 2017/12/15. */ BI.SQLEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { return $.extend(BI.CodeEditor.superclass._defaultConfig.apply(), { baseCls: "bi-sql-editor", value: "", lineHeight: 2, showHint: true, supportFunction: false, supportParam: false }); }, _init: function () { BI.CodeEditor.superclass._init.apply(this, arguments); var o = this.options, self = this; this.editor = CodeMirror(this.element[0], { mode: "text/x-sql", textWrapping: true, lineWrapping: true, lineNumbers: false }); o.lineHeight === 1 ? this.element.addClass("codemirror-low-line-height") : this.element.addClass("codemirror-high-line-height"); this.editor.on("change", function (cm, change) { self._checkWaterMark(); if (o.showHint) { CodeMirror.showHint(cm, CodeMirror.sqlHint, { completeSingle: false, supportFunction: o.supportFunction }); } BI.nextTick(function () { self.fireEvent(BI.FormulaEditor.EVENT_CHANGE); }); }); this.editor.on("focus", function () { self._checkWaterMark(); self.fireEvent(BI.FormulaEditor.EVENT_FOCUS); }); this.editor.on("blur", function () { self.fireEvent(BI.FormulaEditor.EVENT_BLUR); }); // 水印 this.watermark = BI.createWidget({ type: "bi.label", text: BI.i18nText("Please_Enter_SQL"), cls: "bi-water-mark", whiteSpace: "nowrap", textAlign: "left" }); this.watermark.element.bind( "mousedown", function (e) { self.insertString(""); self.editor.focus(); e.stopEvent(); } ); this.watermark.element.bind("click", function (e) { self.editor.focus(); e.stopEvent(); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.watermark, top: 0, left: 5 }] }); if (BI.isKey(o.value)) { BI.nextTick(function () { self.setValue(o.value); }); } }, insertString: function (str) { this.editor.replaceSelection(str); this.editor.focus(); }, insertParam: function (param) { var value = param; var from = this.editor.getCursor(); this.editor.replaceSelection(param); var to = this.editor.getCursor(); var options = {className: "param", atomic: true}; options.value = value; this.editor.markText(from, to, options); this.editor.replaceSelection(" "); this.editor.focus(); }, _checkWaterMark: function () { var o = this.options; if (!this.disabledWaterMark && BI.isEmptyString(this.editor.getValue()) && BI.isKey(o.watermark)) { this.watermark && this.watermark.visible(); } else { this.watermark && this.watermark.invisible(); } }, _analyzeContent: function (v) { var regx = /\$[\{][^\}]*[\}]|[^\$\{]*[^\$\{]/g; return v.match(regx); }, getValue: function () { return this.editor.getValue("\n", function (line) { var rawText = line.text, value = line.text, num = 0; value.text = rawText; _.forEach(_.sortBy(line.markedSpans, "from"), function (i, ms) { switch (i.marker.className) { case "param": case "error-param": var fieldNameLength = i.to - i.from; value = value.substr(0, i.from + num) + "$\{" + i.marker.value + "\}" + value.substr(i.to + num, value.length); // 加上${}的偏移 num += 3; // 加上实际值和显示值的长度差的偏移 num += (i.marker.value.length - fieldNameLength); break; } }); return value; }); }, setValue: function (v) { var self = this, result, o = this.options; this.refresh(); self.editor.setValue(""); result = this._analyzeContent(v || ""); BI.each(result, function (i, item) { var fieldRegx = /\$[\{][^\}]*[\}]/; var str = item.match(fieldRegx); if (BI.isNotEmptyArray(str) && o.supportParam) { self.insertParam(str[0].substring(2, item.length - 1)); } else { self.insertString(item); } }); this._checkWaterMark(); }, refresh: function () { var self = this; BI.nextTick(function () { self.editor.refresh(); }); } }); BI.shortcut("bi.sql_editor", BI.SQLEditor);// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ┌────────────────────────────────────────────────────────────┐ \\ // │ Eve 0.4.2 - JavaScript Events Library │ \\ // ├────────────────────────────────────────────────────────────┤ \\ // │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\ // └────────────────────────────────────────────────────────────┘ \\ (function (glob, factory) { if (typeof define === "function" && define.amd) { define("eve", function() { return factory(); }); } else if (typeof exports === "object") { module.exports = factory(); } else { glob.eve = factory(); } }(this, function(){ var version = "0.4.2", has = "hasOwnProperty", separator = /[\.\/]/, wildcard = "*", fun = function () {}, numsort = function (a, b) { return a - b; }, current_event, stop, events = {n: {}}, /*\ * eve [ method ] * Fires event with given `name`, given scope and other parameters. > Arguments - name (string) name of the *event*, dot (`.`) or slash (`/`) separated - scope (object) context for the event handlers - varargs (...) the rest of arguments will be sent to event handlers = (object) array of returned values from the listeners \*/ eve = function (name, scope) { name = String(name); var e = events, oldstop = stop, args = Array.prototype.slice.call(arguments, 2), listeners = eve.listeners(name), z = 0, f = false, l, indexed = [], queue = {}, out = [], ce = current_event, errors = []; current_event = name; stop = 0; for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) { indexed.push(listeners[i].zIndex); if (listeners[i].zIndex < 0) { queue[listeners[i].zIndex] = listeners[i]; } } indexed.sort(numsort); while (indexed[z] < 0) { l = queue[indexed[z++]]; out.push(l.apply(scope, args)); if (stop) { stop = oldstop; return out; } } for (i = 0; i < ii; i++) { l = listeners[i]; if ("zIndex" in l) { if (l.zIndex == indexed[z]) { out.push(l.apply(scope, args)); if (stop) { break; } do { z++; l = queue[indexed[z]]; l && out.push(l.apply(scope, args)); if (stop) { break; } } while (l) } else { queue[l.zIndex] = l; } } else { out.push(l.apply(scope, args)); if (stop) { break; } } } stop = oldstop; current_event = ce; return out.length ? out : null; }; // Undocumented. Debug only. eve._events = events; /*\ * eve.listeners [ method ] * Internal method which gives you array of all event handlers that will be triggered by the given `name`. > Arguments - name (string) name of the event, dot (`.`) or slash (`/`) separated = (array) array of event handlers \*/ eve.listeners = function (name) { var names = name.split(separator), e = events, item, items, k, i, ii, j, jj, nes, es = [e], out = []; for (i = 0, ii = names.length; i < ii; i++) { nes = []; for (j = 0, jj = es.length; j < jj; j++) { e = es[j].n; items = [e[names[i]], e[wildcard]]; k = 2; while (k--) { item = items[k]; if (item) { nes.push(item); out = out.concat(item.f || []); } } } es = nes; } return out; }; /*\ * eve.on [ method ] ** * Binds given event handler with a given name. You can use wildcards “`*`” for the names: | eve.on("*.under.*", f); | eve("mouse.under.floor"); // triggers f * Use @eve to trigger the listener. ** > Arguments ** - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards - f (function) event handler function ** = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment. > Example: | eve.on("mouse", eatIt)(2); | eve.on("mouse", scream); | eve.on("mouse", catchIt)(1); * This will ensure that `catchIt()` function will be called before `eatIt()`. * * If you want to put your handler before non-indexed handlers, specify a negative value. * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”. \*/ eve.on = function (name, f) { name = String(name); if (typeof f != "function") { return function () {}; } var names = name.split(separator), e = events; for (var i = 0, ii = names.length; i < ii; i++) { e = e.n; e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}}); } e.f = e.f || []; for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) { return fun; } e.f.push(f); return function (zIndex) { if (+zIndex == +zIndex) { f.zIndex = +zIndex; } }; }; /*\ * eve.f [ method ] ** * Returns function that will fire given event with optional arguments. * Arguments that will be passed to the result function will be also * concated to the list of final arguments. | el.onclick = eve.f("click", 1, 2); | eve.on("click", function (a, b, c) { | console.log(a, b, c); // 1, 2, [event object] | }); > Arguments - event (string) event name - varargs (…) and any other arguments = (function) possible event handler function \*/ eve.f = function (event) { var attrs = [].slice.call(arguments, 1); return function () { eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0))); }; }; /*\ * eve.stop [ method ] ** * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing. \*/ eve.stop = function () { stop = 1; }; /*\ * eve.nt [ method ] ** * Could be used inside event handler to figure out actual name of the event. ** > Arguments ** - subname (string) #optional subname of the event ** = (string) name of the event, if `subname` is not specified * or = (boolean) `true`, if current event’s name contains `subname` \*/ eve.nt = function (subname) { if (subname) { return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event); } return current_event; }; /*\ * eve.nts [ method ] ** * Could be used inside event handler to figure out actual name of the event. ** ** = (array) names of the event \*/ eve.nts = function () { return current_event.split(separator); }; /*\ * eve.off [ method ] ** * Removes given function from the list of event listeners assigned to given name. * If no arguments specified all the events will be cleared. ** > Arguments ** - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards - f (function) event handler function \*/ /*\ * eve.unbind [ method ] ** * See @eve.off \*/ eve.off = eve.unbind = function (name, f) { if (!name) { eve._events = events = {n: {}}; return; } var names = name.split(separator), e, key, splice, i, ii, j, jj, cur = [events]; for (i = 0, ii = names.length; i < ii; i++) { for (j = 0; j < cur.length; j += splice.length - 2) { splice = [j, 1]; e = cur[j].n; if (names[i] != wildcard) { if (e[names[i]]) { splice.push(e[names[i]]); } } else { for (key in e) if (e[has](key)) { splice.push(e[key]); } } cur.splice.apply(cur, splice); } } for (i = 0, ii = cur.length; i < ii; i++) { e = cur[i]; while (e.n) { if (f) { if (e.f) { for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) { e.f.splice(j, 1); break; } !e.f.length && delete e.f; } for (key in e.n) if (e.n[has](key) && e.n[key].f) { var funcs = e.n[key].f; for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) { funcs.splice(j, 1); break; } !funcs.length && delete e.n[key].f; } } else { delete e.f; for (key in e.n) if (e.n[has](key) && e.n[key].f) { delete e.n[key].f; } } e = e.n; } } }; /*\ * eve.once [ method ] ** * Binds given event handler with a given name to only run once then unbind itself. | eve.once("login", f); | eve("login"); // triggers f | eve("login"); // no listeners * Use @eve to trigger the listener. ** > Arguments ** - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards - f (function) event handler function ** = (function) same return function as @eve.on \*/ eve.once = function (name, f) { var f2 = function () { eve.unbind(name, f2); return f.apply(this, arguments); }; return eve.on(name, f2); }; /*\ * eve.version [ property (string) ] ** * Current version of the library. \*/ eve.version = version; eve.toString = function () { return "You are running Eve " + version; }; return eve; })); // ┌────────────────────────────────────────────────────────────────────┐ \\ // │ Raphaël 2.1.4 - JavaScript Vector Library │ \\ // ├────────────────────────────────────────────────────────────────────┤ \\ // │ Core Module │ \\ // ├────────────────────────────────────────────────────────────────────┤ \\ // │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\ // └────────────────────────────────────────────────────────────────────┘ \\ (function (glob, factory) { if (typeof define === "function" && define.amd) { define("raphael.core", ["eve"], function(eve) { return factory(eve); }); } else if (typeof exports === "object") { module.exports = factory(require("eve")); } else { glob.Raphael = factory(glob.eve); } }(this, function (eve) { /*\ * Raphael [ method ] ** * Creates a canvas object on which to draw. * You must do this first, as all future calls to drawing methods * from this instance will be bound to this canvas. > Parameters ** - container (HTMLElement|string) DOM element or its ID which is going to be a parent for drawing surface - width (number) - height (number) - callback (function) #optional callback function which is going to be executed in the context of newly created paper * or - x (number) - y (number) - width (number) - height (number) - callback (function) #optional callback function which is going to be executed in the context of newly created paper * or - all (array) (first 3 or 4 elements in the array are equal to [containerID, width, height] or [x, y, width, height]. The rest are element descriptions in format {type: type, }). See @Paper.add. - callback (function) #optional callback function which is going to be executed in the context of newly created paper * or - onReadyCallback (function) function that is going to be called on DOM ready event. You can also subscribe to this event via Eve’s “DOMLoad” event. In this case method returns `undefined`. = (object) @Paper > Usage | // Each of the following examples create a canvas | // that is 320px wide by 200px high. | // Canvas is created at the viewport’s 10,50 coordinate. | var paper = Raphael(10, 50, 320, 200); | // Canvas is created at the top left corner of the #notepad element | // (or its top right corner in dir="rtl" elements) | var paper = Raphael(document.getElementById("notepad"), 320, 200); | // Same as above | var paper = Raphael("notepad", 320, 200); | // Image dump | var set = Raphael(["notepad", 320, 200, { | type: "rect", | x: 10, | y: 10, | width: 25, | height: 25, | stroke: "#f00" | }, { | type: "text", | x: 30, | y: 40, | text: "Dump" | }]); \*/ function R(first) { if (R.is(first, "function")) { return loaded ? first() : eve.on("raphael.DOMload", first); } else if (R.is(first, array)) { return R._engine.create[apply](R, first.splice(0, 3 + R.is(first[0], nu))).add(first); } else { var args = Array.prototype.slice.call(arguments, 0); if (R.is(args[args.length - 1], "function")) { var f = args.pop(); return loaded ? f.call(R._engine.create[apply](R, args)) : eve.on("raphael.DOMload", function () { f.call(R._engine.create[apply](R, args)); }); } else { return R._engine.create[apply](R, arguments); } } } R.version = "2.1.4"; R.eve = eve; var loaded, separator = /[, ]+/, elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1}, formatrg = /\{(\d+)\}/g, proto = "prototype", has = "hasOwnProperty", g = { doc: document, win: window }, oldRaphael = { was: Object.prototype[has].call(g.win, "Raphael"), is: g.win.Raphael }, Paper = function () { /*\ * Paper.ca [ property (object) ] ** * Shortcut for @Paper.customAttributes \*/ /*\ * Paper.customAttributes [ property (object) ] ** * If you have a set of attributes that you would like to represent * as a function of some number you can do it easily with custom attributes: > Usage | paper.customAttributes.hue = function (num) { | num = num % 1; | return {fill: "hsb(" + num + ", 0.75, 1)"}; | }; | // Custom attribute “hue” will change fill | // to be given hue with fixed saturation and brightness. | // Now you can use it like this: | var c = paper.circle(10, 10, 10).attr({hue: .45}); | // or even like this: | c.animate({hue: 1}, 1e3); | | // You could also create custom attribute | // with multiple parameters: | paper.customAttributes.hsb = function (h, s, b) { | return {fill: "hsb(" + [h, s, b].join(",") + ")"}; | }; | c.attr({hsb: "0.5 .8 1"}); | c.animate({hsb: [1, 0, 0.5]}, 1e3); \*/ this.ca = this.customAttributes = {}; }, paperproto, appendChild = "appendChild", apply = "apply", concat = "concat", supportsTouch = ('ontouchstart' in g.win) || g.win.DocumentTouch && g.doc instanceof DocumentTouch, //taken from Modernizr touch test E = "", S = " ", Str = String, split = "split", events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[split](S), touchMap = { mousedown: "touchstart", mousemove: "touchmove", mouseup: "touchend" }, lowerCase = Str.prototype.toLowerCase, math = Math, mmax = math.max, mmin = math.min, abs = math.abs, pow = math.pow, PI = math.PI, nu = "number", string = "string", array = "array", toString = "toString", fillString = "fill", objectToString = Object.prototype.toString, paper = {}, push = "push", ISURL = R._ISURL = /^url\(['"]?(.+?)['"]?\)$/i, colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i, isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1}, bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, round = math.round, setAttribute = "setAttribute", toFloat = parseFloat, toInt = parseInt, upperCase = Str.prototype.toUpperCase, availableAttrs = R._availableAttrs = { "arrow-end": "none", "arrow-start": "none", blur: 0, "clip-rect": "0 0 1e9 1e9", cursor: "default", cx: 0, cy: 0, fill: "#fff", "fill-opacity": 1, font: '10px "Arial"', "font-family": '"Arial"', "font-size": "10", "font-style": "normal", "font-weight": 400, gradient: 0, height: 0, href: "http://raphaeljs.com/", "letter-spacing": 0, opacity: 1, path: "M0,0", r: 0, rx: 0, ry: 0, src: "", stroke: "#000", "stroke-dasharray": "", "stroke-linecap": "butt", "stroke-linejoin": "butt", "stroke-miterlimit": 0, "stroke-opacity": 1, "stroke-width": 1, target: "_blank", "text-anchor": "middle", title: "Raphael", transform: "", width: 0, x: 0, y: 0 }, availableAnimAttrs = R._availableAnimAttrs = { blur: nu, "clip-rect": "csv", cx: nu, cy: nu, fill: "colour", "fill-opacity": nu, "font-size": nu, height: nu, opacity: nu, path: "path", r: nu, rx: nu, ry: nu, stroke: "colour", "stroke-opacity": nu, "stroke-width": nu, transform: "transform", width: nu, x: nu, y: nu }, whitespace = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]/g, commaSpaces = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/, hsrg = {hs: 1, rg: 1}, p2s = /,?([achlmqrstvxz]),?/gi, pathCommand = /([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig, tCommand = /([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig, pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/ig, radial_gradient = R._radial_gradient = /^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/, eldata = {}, sortByKey = function (a, b) { return a.key - b.key; }, sortByNumber = function (a, b) { return toFloat(a) - toFloat(b); }, fun = function () {}, pipe = function (x) { return x; }, rectPath = R._rectPath = function (x, y, w, h, r) { if (r) { return [["M", x + r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], ["a", r, r, 0, 0, 1, -r, r], ["l", r * 2 - w, 0], ["a", r, r, 0, 0, 1, -r, -r], ["l", 0, r * 2 - h], ["a", r, r, 0, 0, 1, r, -r], ["z"]]; } return [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]]; }, ellipsePath = function (x, y, rx, ry) { if (ry == null) { ry = rx; } return [["M", x, y], ["m", 0, -ry], ["a", rx, ry, 0, 1, 1, 0, 2 * ry], ["a", rx, ry, 0, 1, 1, 0, -2 * ry], ["z"]]; }, getPath = R._getPath = { path: function (el) { return el.attr("path"); }, circle: function (el) { var a = el.attrs; return ellipsePath(a.cx, a.cy, a.r); }, ellipse: function (el) { var a = el.attrs; return ellipsePath(a.cx, a.cy, a.rx, a.ry); }, rect: function (el) { var a = el.attrs; return rectPath(a.x, a.y, a.width, a.height, a.r); }, image: function (el) { var a = el.attrs; return rectPath(a.x, a.y, a.width, a.height); }, text: function (el) { var bbox = el._getBBox(); return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); }, set : function(el) { var bbox = el._getBBox(); return rectPath(bbox.x, bbox.y, bbox.width, bbox.height); } }, /*\ * Raphael.mapPath [ method ] ** * Transform the path string with given matrix. > Parameters - path (string) path string - matrix (object) see @Matrix = (string) transformed path string \*/ mapPath = R.mapPath = function (path, matrix) { if (!matrix) { return path; } var x, y, i, j, ii, jj, pathi; path = path2curve(path); for (i = 0, ii = path.length; i < ii; i++) { pathi = path[i]; for (j = 1, jj = pathi.length; j < jj; j += 2) { x = matrix.x(pathi[j], pathi[j + 1]); y = matrix.y(pathi[j], pathi[j + 1]); pathi[j] = x; pathi[j + 1] = y; } } return path; }; R._g = g; /*\ * Raphael.type [ property (string) ] ** * Can be “SVG”, “VML” or empty, depending on browser support. \*/ R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML"); if (R.type == "VML") { var d = g.doc.createElement("div"), b; d.innerHTML = ''; b = d.firstChild; b.style.behavior = "url(#default#VML)"; if (!(b && typeof b.adj == "object")) { return (R.type = E); } d = null; } /*\ * Raphael.svg [ property (boolean) ] ** * `true` if browser supports SVG. \*/ /*\ * Raphael.vml [ property (boolean) ] ** * `true` if browser supports VML. \*/ R.svg = !(R.vml = R.type == "VML"); R._Paper = Paper; /*\ * Raphael.fn [ property (object) ] ** * You can add your own method to the canvas. For example if you want to draw a pie chart, * you can create your own pie chart function and ship it as a Raphaël plugin. To do this * you need to extend the `Raphael.fn` object. You should modify the `fn` object before a * Raphaël instance is created, otherwise it will take no effect. Please note that the * ability for namespaced plugins was removed in Raphael 2.0. It is up to the plugin to * ensure any namespacing ensures proper context. > Usage | Raphael.fn.arrow = function (x1, y1, x2, y2, size) { | return this.path( ... ); | }; | // or create namespace | Raphael.fn.mystuff = { | arrow: function () {…}, | star: function () {…}, | // etc… | }; | var paper = Raphael(10, 10, 630, 480); | // then use it | paper.arrow(10, 10, 30, 30, 5).attr({fill: "#f00"}); | paper.mystuff.arrow(); | paper.mystuff.star(); \*/ R.fn = paperproto = Paper.prototype = R.prototype; R._id = 0; R._oid = 0; /*\ * Raphael.is [ method ] ** * Handful of replacements for `typeof` operator. > Parameters - o (…) any object or primitive - type (string) name of the type, i.e. “string”, “function”, “number”, etc. = (boolean) is given value is of given type \*/ R.is = function (o, type) { type = lowerCase.call(type); if (type == "finite") { return !isnan[has](+o); } if (type == "array") { return o instanceof Array; } return (type == "null" && o === null) || (type == typeof o && o !== null) || (type == "object" && o === Object(o)) || (type == "array" && Array.isArray && Array.isArray(o)) || objectToString.call(o).slice(8, -1).toLowerCase() == type; }; function clone(obj) { if (typeof obj == "function" || Object(obj) !== obj) { return obj; } var res = new obj.constructor; for (var key in obj) if (obj[has](key)) { res[key] = clone(obj[key]); } return res; } /*\ * Raphael.angle [ method ] ** * Returns angle between two or three points > Parameters - x1 (number) x coord of first point - y1 (number) y coord of first point - x2 (number) x coord of second point - y2 (number) y coord of second point - x3 (number) #optional x coord of third point - y3 (number) #optional y coord of third point = (number) angle in degrees. \*/ R.angle = function (x1, y1, x2, y2, x3, y3) { if (x3 == null) { var x = x1 - x2, y = y1 - y2; if (!x && !y) { return 0; } return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360; } else { return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3); } }; /*\ * Raphael.rad [ method ] ** * Transform angle to radians > Parameters - deg (number) angle in degrees = (number) angle in radians. \*/ R.rad = function (deg) { return deg % 360 * PI / 180; }; /*\ * Raphael.deg [ method ] ** * Transform angle to degrees > Parameters - rad (number) angle in radians = (number) angle in degrees. \*/ R.deg = function (rad) { return Math.round ((rad * 180 / PI% 360)* 1000) / 1000; }; /*\ * Raphael.snapTo [ method ] ** * Snaps given value to given grid. > Parameters - values (array|number) given array of values or step of the grid - value (number) value to adjust - tolerance (number) #optional tolerance for snapping. Default is `10`. = (number) adjusted value. \*/ R.snapTo = function (values, value, tolerance) { tolerance = R.is(tolerance, "finite") ? tolerance : 10; if (R.is(values, array)) { var i = values.length; while (i--) if (abs(values[i] - value) <= tolerance) { return values[i]; } } else { values = +values; var rem = value % values; if (rem < tolerance) { return value - rem; } if (rem > values - tolerance) { return value - rem + values; } } return value; }; /*\ * Raphael.createUUID [ method ] ** * Returns RFC4122, version 4 ID \*/ var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) { return function () { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(uuidRegEx, uuidReplacer).toUpperCase(); }; })(/[xy]/g, function (c) { var r = math.random() * 16 | 0, v = c == "x" ? r : (r & 3 | 8); return v.toString(16); }); /*\ * Raphael.setWindow [ method ] ** * Used when you need to draw in `<iframe>`. Switched window to the iframe one. > Parameters - newwin (window) new window object \*/ R.setWindow = function (newwin) { eve("raphael.setWindow", R, g.win, newwin); g.win = newwin; g.doc = g.win.document; if (R._engine.initWin) { R._engine.initWin(g.win); } }; var toHex = function (color) { if (R.vml) { // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/ var trim = /^\s+|\s+$/g; var bod; try { var docum = new ActiveXObject("htmlfile"); docum.write(""); docum.close(); bod = docum.body; } catch(e) { bod = createPopup().document.body; } var range = bod.createTextRange(); toHex = cacher(function (color) { try { bod.style.color = Str(color).replace(trim, E); var value = range.queryCommandValue("ForeColor"); value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16); return "#" + ("000000" + value.toString(16)).slice(-6); } catch(e) { return "none"; } }); } else { var i = g.doc.createElement("i"); i.title = "Rapha\xebl Colour Picker"; i.style.display = "none"; g.doc.body.appendChild(i); toHex = cacher(function (color) { i.style.color = color; return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color"); }); } return toHex(color); }, hsbtoString = function () { return "hsb(" + [this.h, this.s, this.b] + ")"; }, hsltoString = function () { return "hsl(" + [this.h, this.s, this.l] + ")"; }, rgbtoString = function () { return this.hex; }, prepareRGB = function (r, g, b) { if (g == null && R.is(r, "object") && "r" in r && "g" in r && "b" in r) { b = r.b; g = r.g; r = r.r; } if (g == null && R.is(r, string)) { var clr = R.getRGB(r); r = clr.r; g = clr.g; b = clr.b; } if (r > 1 || g > 1 || b > 1) { r /= 255; g /= 255; b /= 255; } return [r, g, b]; }, packageRGB = function (r, g, b, o) { r *= 255; g *= 255; b *= 255; var rgb = { r: r, g: g, b: b, hex: R.rgb(r, g, b), toString: rgbtoString }; R.is(o, "finite") && (rgb.opacity = o); return rgb; }; /*\ * Raphael.color [ method ] ** * Parses the color string and returns object with all values for the given color. > Parameters - clr (string) color string in one of the supported formats (see @Raphael.getRGB) = (object) Combined RGB & HSB object in format: o { o r (number) red, o g (number) green, o b (number) blue, o hex (string) color in HTML/CSS format: #••••••, o error (boolean) `true` if string can’t be parsed, o h (number) hue, o s (number) saturation, o v (number) value (brightness), o l (number) lightness o } \*/ R.color = function (clr) { var rgb; if (R.is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) { rgb = R.hsb2rgb(clr); clr.r = rgb.r; clr.g = rgb.g; clr.b = rgb.b; clr.hex = rgb.hex; } else if (R.is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) { rgb = R.hsl2rgb(clr); clr.r = rgb.r; clr.g = rgb.g; clr.b = rgb.b; clr.hex = rgb.hex; } else { if (R.is(clr, "string")) { clr = R.getRGB(clr); } if (R.is(clr, "object") && "r" in clr && "g" in clr && "b" in clr) { rgb = R.rgb2hsl(clr); clr.h = rgb.h; clr.s = rgb.s; clr.l = rgb.l; rgb = R.rgb2hsb(clr); clr.v = rgb.b; } else { clr = {hex: "none"}; clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1; } } clr.toString = rgbtoString; return clr; }; /*\ * Raphael.hsb2rgb [ method ] ** * Converts HSB values to RGB object. > Parameters - h (number) hue - s (number) saturation - v (number) value or brightness = (object) RGB object in format: o { o r (number) red, o g (number) green, o b (number) blue, o hex (string) color in HTML/CSS format: #•••••• o } \*/ R.hsb2rgb = function (h, s, v, o) { if (this.is(h, "object") && "h" in h && "s" in h && "b" in h) { v = h.b; s = h.s; o = h.o; h = h.h; } h *= 360; var R, G, B, X, C; h = (h % 360) / 60; C = v * s; X = C * (1 - abs(h % 2 - 1)); R = G = B = v - C; h = ~~h; R += [C, X, 0, 0, X, C][h]; G += [X, C, C, X, 0, 0][h]; B += [0, 0, X, C, C, X][h]; return packageRGB(R, G, B, o); }; /*\ * Raphael.hsl2rgb [ method ] ** * Converts HSL values to RGB object. > Parameters - h (number) hue - s (number) saturation - l (number) luminosity = (object) RGB object in format: o { o r (number) red, o g (number) green, o b (number) blue, o hex (string) color in HTML/CSS format: #•••••• o } \*/ R.hsl2rgb = function (h, s, l, o) { if (this.is(h, "object") && "h" in h && "s" in h && "l" in h) { l = h.l; s = h.s; h = h.h; } if (h > 1 || s > 1 || l > 1) { h /= 360; s /= 100; l /= 100; } h *= 360; var R, G, B, X, C; h = (h % 360) / 60; C = 2 * s * (l < .5 ? l : 1 - l); X = C * (1 - abs(h % 2 - 1)); R = G = B = l - C / 2; h = ~~h; R += [C, X, 0, 0, X, C][h]; G += [X, C, C, X, 0, 0][h]; B += [0, 0, X, C, C, X][h]; return packageRGB(R, G, B, o); }; /*\ * Raphael.rgb2hsb [ method ] ** * Converts RGB values to HSB object. > Parameters - r (number) red - g (number) green - b (number) blue = (object) HSB object in format: o { o h (number) hue o s (number) saturation o b (number) brightness o } \*/ R.rgb2hsb = function (r, g, b) { b = prepareRGB(r, g, b); r = b[0]; g = b[1]; b = b[2]; var H, S, V, C; V = mmax(r, g, b); C = V - mmin(r, g, b); H = (C == 0 ? null : V == r ? (g - b) / C : V == g ? (b - r) / C + 2 : (r - g) / C + 4 ); H = ((H + 360) % 6) * 60 / 360; S = C == 0 ? 0 : C / V; return {h: H, s: S, b: V, toString: hsbtoString}; }; /*\ * Raphael.rgb2hsl [ method ] ** * Converts RGB values to HSL object. > Parameters - r (number) red - g (number) green - b (number) blue = (object) HSL object in format: o { o h (number) hue o s (number) saturation o l (number) luminosity o } \*/ R.rgb2hsl = function (r, g, b) { b = prepareRGB(r, g, b); r = b[0]; g = b[1]; b = b[2]; var H, S, L, M, m, C; M = mmax(r, g, b); m = mmin(r, g, b); C = M - m; H = (C == 0 ? null : M == r ? (g - b) / C : M == g ? (b - r) / C + 2 : (r - g) / C + 4); H = ((H + 360) % 6) * 60 / 360; L = (M + m) / 2; S = (C == 0 ? 0 : L < .5 ? C / (2 * L) : C / (2 - 2 * L)); return {h: H, s: S, l: L, toString: hsltoString}; }; R._path2string = function () { return this.join(",").replace(p2s, "$1"); }; function repush(array, item) { for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) { return array.push(array.splice(i, 1)[0]); } } function cacher(f, scope, postprocessor) { function newf() { var arg = Array.prototype.slice.call(arguments, 0), args = arg.join("\u2400"), cache = newf.cache = newf.cache || {}, count = newf.count = newf.count || []; if (cache[has](args)) { repush(count, args); return postprocessor ? postprocessor(cache[args]) : cache[args]; } count.length >= 1e3 && delete cache[count.shift()]; count.push(args); cache[args] = f[apply](scope, arg); return postprocessor ? postprocessor(cache[args]) : cache[args]; } return newf; } var preload = R._preload = function (src, f) { var img = g.doc.createElement("img"); img.style.cssText = "position:absolute;left:-9999em;top:-9999em"; img.onload = function () { f.call(this); this.onload = null; g.doc.body.removeChild(this); }; img.onerror = function () { g.doc.body.removeChild(this); }; g.doc.body.appendChild(img); img.src = src; }; function clrToString() { return this.hex; } /*\ * Raphael.getRGB [ method ] ** * Parses colour string as RGB object > Parameters - colour (string) colour string in one of formats: #
    #
  • Colour name (“red”, “green”, “cornflowerblue”, etc)
  • #
  • #••• — shortened HTML colour: (“#000”, “#fc0”, etc)
  • #
  • #•••••• — full length HTML colour: (“#000000”, “#bd2300”)
  • #
  • rgb(•••, •••, •••) — red, green and blue channels’ values: (“rgb(200, 100, 0)”)
  • #
  • rgb(•••%, •••%, •••%) — same as above, but in %: (“rgb(100%, 175%, 0%)”)
  • #
  • hsb(•••, •••, •••) — hue, saturation and brightness values: (“hsb(0.5, 0.25, 1)”)
  • #
  • hsb(•••%, •••%, •••%) — same as above, but in %
  • #
  • hsl(•••, •••, •••) — same as hsb
  • #
  • hsl(•••%, •••%, •••%) — same as hsb
  • #
= (object) RGB object in format: o { o r (number) red, o g (number) green, o b (number) blue o hex (string) color in HTML/CSS format: #••••••, o error (boolean) true if string can’t be parsed o } \*/ R.getRGB = cacher(function (colour) { if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) { return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString}; } if (colour == "none") { return {r: -1, g: -1, b: -1, hex: "none", toString: clrToString}; } !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour)); var res, red, green, blue, opacity, t, values, rgb = colour.match(colourRegExp); if (rgb) { if (rgb[2]) { blue = toInt(rgb[2].substring(5), 16); green = toInt(rgb[2].substring(3, 5), 16); red = toInt(rgb[2].substring(1, 3), 16); } if (rgb[3]) { blue = toInt((t = rgb[3].charAt(3)) + t, 16); green = toInt((t = rgb[3].charAt(2)) + t, 16); red = toInt((t = rgb[3].charAt(1)) + t, 16); } if (rgb[4]) { values = rgb[4][split](commaSpaces); red = toFloat(values[0]); values[0].slice(-1) == "%" && (red *= 2.55); green = toFloat(values[1]); values[1].slice(-1) == "%" && (green *= 2.55); blue = toFloat(values[2]); values[2].slice(-1) == "%" && (blue *= 2.55); rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3])); values[3] && values[3].slice(-1) == "%" && (opacity /= 100); } if (rgb[5]) { values = rgb[5][split](commaSpaces); red = toFloat(values[0]); values[0].slice(-1) == "%" && (red *= 2.55); green = toFloat(values[1]); values[1].slice(-1) == "%" && (green *= 2.55); blue = toFloat(values[2]); values[2].slice(-1) == "%" && (blue *= 2.55); (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3])); values[3] && values[3].slice(-1) == "%" && (opacity /= 100); return R.hsb2rgb(red, green, blue, opacity); } if (rgb[6]) { values = rgb[6][split](commaSpaces); red = toFloat(values[0]); values[0].slice(-1) == "%" && (red *= 2.55); green = toFloat(values[1]); values[1].slice(-1) == "%" && (green *= 2.55); blue = toFloat(values[2]); values[2].slice(-1) == "%" && (blue *= 2.55); (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3])); values[3] && values[3].slice(-1) == "%" && (opacity /= 100); return R.hsl2rgb(red, green, blue, opacity); } rgb = {r: red, g: green, b: blue, toString: clrToString}; rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1); R.is(opacity, "finite") && (rgb.opacity = opacity); return rgb; } return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString}; }, R); /*\ * Raphael.hsb [ method ] ** * Converts HSB values to hex representation of the colour. > Parameters - h (number) hue - s (number) saturation - b (number) value or brightness = (string) hex representation of the colour. \*/ R.hsb = cacher(function (h, s, b) { return R.hsb2rgb(h, s, b).hex; }); /*\ * Raphael.hsl [ method ] ** * Converts HSL values to hex representation of the colour. > Parameters - h (number) hue - s (number) saturation - l (number) luminosity = (string) hex representation of the colour. \*/ R.hsl = cacher(function (h, s, l) { return R.hsl2rgb(h, s, l).hex; }); /*\ * Raphael.rgb [ method ] ** * Converts RGB values to hex representation of the colour. > Parameters - r (number) red - g (number) green - b (number) blue = (string) hex representation of the colour. \*/ R.rgb = cacher(function (r, g, b) { function round(x) { return (x + 0.5) | 0; } return "#" + (16777216 | round(b) | (round(g) << 8) | (round(r) << 16)).toString(16).slice(1); }); /*\ * Raphael.getColor [ method ] ** * On each call returns next colour in the spectrum. To reset it back to red call @Raphael.getColor.reset > Parameters - value (number) #optional brightness, default is `0.75` = (string) hex representation of the colour. \*/ R.getColor = function (value) { var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75}, rgb = this.hsb2rgb(start.h, start.s, start.b); start.h += .075; if (start.h > 1) { start.h = 0; start.s -= .2; start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b}); } return rgb.hex; }; /*\ * Raphael.getColor.reset [ method ] ** * Resets spectrum position for @Raphael.getColor back to red. \*/ R.getColor.reset = function () { delete this.start; }; // http://schepers.cc/getting-to-the-point function catmullRom2bezier(crp, z) { var d = []; for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { var p = [ {x: +crp[i - 2], y: +crp[i - 1]}, {x: +crp[i], y: +crp[i + 1]}, {x: +crp[i + 2], y: +crp[i + 3]}, {x: +crp[i + 4], y: +crp[i + 5]} ]; if (z) { if (!i) { p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; } else if (iLen - 4 == i) { p[3] = {x: +crp[0], y: +crp[1]}; } else if (iLen - 2 == i) { p[2] = {x: +crp[0], y: +crp[1]}; p[3] = {x: +crp[2], y: +crp[3]}; } } else { if (iLen - 4 == i) { p[3] = p[2]; } else if (!i) { p[0] = {x: +crp[i], y: +crp[i + 1]}; } } d.push(["C", (-p[0].x + 6 * p[1].x + p[2].x) / 6, (-p[0].y + 6 * p[1].y + p[2].y) / 6, (p[1].x + 6 * p[2].x - p[3].x) / 6, (p[1].y + 6*p[2].y - p[3].y) / 6, p[2].x, p[2].y ]); } return d; } /*\ * Raphael.parsePathString [ method ] ** * Utility method ** * Parses given path string into an array of arrays of path segments. > Parameters - pathString (string|array) path string or array of segments (in the last case it will be returned straight away) = (array) array of segments. \*/ R.parsePathString = function (pathString) { if (!pathString) { return null; } var pth = paths(pathString); if (pth.arr) { return pathClone(pth.arr); } var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0}, data = []; if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption data = pathClone(pathString); } if (!data.length) { Str(pathString).replace(pathCommand, function (a, b, c) { var params = [], name = b.toLowerCase(); c.replace(pathValues, function (a, b) { b && params.push(+b); }); if (name == "m" && params.length > 2) { data.push([b][concat](params.splice(0, 2))); name = "l"; b = b == "m" ? "l" : "L"; } if (name == "r") { data.push([b][concat](params)); } else while (params.length >= paramCounts[name]) { data.push([b][concat](params.splice(0, paramCounts[name]))); if (!paramCounts[name]) { break; } } }); } data.toString = R._path2string; pth.arr = pathClone(data); return data; }; /*\ * Raphael.parseTransformString [ method ] ** * Utility method ** * Parses given path string into an array of transformations. > Parameters - TString (string|array) transform string or array of transformations (in the last case it will be returned straight away) = (array) array of transformations. \*/ R.parseTransformString = cacher(function (TString) { if (!TString) { return null; } var paramCounts = {r: 3, s: 4, t: 2, m: 6}, data = []; if (R.is(TString, array) && R.is(TString[0], array)) { // rough assumption data = pathClone(TString); } if (!data.length) { Str(TString).replace(tCommand, function (a, b, c) { var params = [], name = lowerCase.call(b); c.replace(pathValues, function (a, b) { b && params.push(+b); }); data.push([b][concat](params)); }); } data.toString = R._path2string; return data; }); // PATHS var paths = function (ps) { var p = paths.ps = paths.ps || {}; if (p[ps]) { p[ps].sleep = 100; } else { p[ps] = { sleep: 100 }; } setTimeout(function () { for (var key in p) if (p[has](key) && key != ps) { p[key].sleep--; !p[key].sleep && delete p[key]; } }); return p[ps]; }; /*\ * Raphael.findDotsAtSegment [ method ] ** * Utility method ** * Find dot coordinates on the given cubic bezier curve at the given t. > Parameters - p1x (number) x of the first point of the curve - p1y (number) y of the first point of the curve - c1x (number) x of the first anchor of the curve - c1y (number) y of the first anchor of the curve - c2x (number) x of the second anchor of the curve - c2y (number) y of the second anchor of the curve - p2x (number) x of the second point of the curve - p2y (number) y of the second point of the curve - t (number) position on the curve (0..1) = (object) point information in format: o { o x: (number) x coordinate of the point o y: (number) y coordinate of the point o m: { o x: (number) x coordinate of the left anchor o y: (number) y coordinate of the left anchor o } o n: { o x: (number) x coordinate of the right anchor o y: (number) y coordinate of the right anchor o } o start: { o x: (number) x coordinate of the start of the curve o y: (number) y coordinate of the start of the curve o } o end: { o x: (number) x coordinate of the end of the curve o y: (number) y coordinate of the end of the curve o } o alpha: (number) angle of the curve derivative at the point o } \*/ R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { var t1 = 1 - t, t13 = pow(t1, 3), t12 = pow(t1, 2), t2 = t * t, t3 = t2 * t, x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x, y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y, mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x), my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y), nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x), ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y), ax = t1 * p1x + t * c1x, ay = t1 * p1y + t * c1y, cx = t1 * c2x + t * p2x, cy = t1 * c2y + t * p2y, alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI); (mx > nx || my < ny) && (alpha += 180); return { x: x, y: y, m: {x: mx, y: my}, n: {x: nx, y: ny}, start: {x: ax, y: ay}, end: {x: cx, y: cy}, alpha: alpha }; }; /*\ * Raphael.bezierBBox [ method ] ** * Utility method ** * Return bounding box of a given cubic bezier curve > Parameters - p1x (number) x of the first point of the curve - p1y (number) y of the first point of the curve - c1x (number) x of the first anchor of the curve - c1y (number) y of the first anchor of the curve - c2x (number) x of the second anchor of the curve - c2y (number) y of the second anchor of the curve - p2x (number) x of the second point of the curve - p2y (number) y of the second point of the curve * or - bez (array) array of six points for bezier curve = (object) point information in format: o { o min: { o x: (number) x coordinate of the left point o y: (number) y coordinate of the top point o } o max: { o x: (number) x coordinate of the right point o y: (number) y coordinate of the bottom point o } o } \*/ R.bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { if (!R.is(p1x, "array")) { p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]; } var bbox = curveDim.apply(null, p1x); return { x: bbox.min.x, y: bbox.min.y, x2: bbox.max.x, y2: bbox.max.y, width: bbox.max.x - bbox.min.x, height: bbox.max.y - bbox.min.y }; }; /*\ * Raphael.isPointInsideBBox [ method ] ** * Utility method ** * Returns `true` if given point is inside bounding boxes. > Parameters - bbox (string) bounding box - x (string) x coordinate of the point - y (string) y coordinate of the point = (boolean) `true` if point inside \*/ R.isPointInsideBBox = function (bbox, x, y) { return x >= bbox.x && x <= bbox.x2 && y >= bbox.y && y <= bbox.y2; }; /*\ * Raphael.isBBoxIntersect [ method ] ** * Utility method ** * Returns `true` if two bounding boxes intersect > Parameters - bbox1 (string) first bounding box - bbox2 (string) second bounding box = (boolean) `true` if they intersect \*/ R.isBBoxIntersect = function (bbox1, bbox2) { var i = R.isPointInsideBBox; return i(bbox2, bbox1.x, bbox1.y) || i(bbox2, bbox1.x2, bbox1.y) || i(bbox2, bbox1.x, bbox1.y2) || i(bbox2, bbox1.x2, bbox1.y2) || i(bbox1, bbox2.x, bbox2.y) || i(bbox1, bbox2.x2, bbox2.y) || i(bbox1, bbox2.x, bbox2.y2) || i(bbox1, bbox2.x2, bbox2.y2) || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y); }; function base3(t, p1, p2, p3, p4) { var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; return t * t2 - 3 * p1 + 3 * p2; } function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) { if (z == null) { z = 1; } z = z > 1 ? 1 : z < 0 ? 0 : z; var z2 = z / 2, n = 12, Tvalues = [-0.1252,0.1252,-0.3678,0.3678,-0.5873,0.5873,-0.7699,0.7699,-0.9041,0.9041,-0.9816,0.9816], Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472], sum = 0; for (var i = 0; i < n; i++) { var ct = z2 * Tvalues[i] + z2, xbase = base3(ct, x1, x2, x3, x4), ybase = base3(ct, y1, y2, y3, y4), comb = xbase * xbase + ybase * ybase; sum += Cvalues[i] * math.sqrt(comb); } return z2 * sum; } function getTatLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) { if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) { return; } var t = 1, step = t / 2, t2 = t - step, l, e = .01; l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); while (abs(l - ll) > e) { step /= 2; t2 += (l < ll ? 1 : -1) * step; l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); } return t2; } function intersect(x1, y1, x2, y2, x3, y3, x4, y4) { if ( mmax(x1, x2) < mmin(x3, x4) || mmin(x1, x2) > mmax(x3, x4) || mmax(y1, y2) < mmin(y3, y4) || mmin(y1, y2) > mmax(y3, y4) ) { return; } var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (!denominator) { return; } var px = nx / denominator, py = ny / denominator, px2 = +px.toFixed(2), py2 = +py.toFixed(2); if ( px2 < +mmin(x1, x2).toFixed(2) || px2 > +mmax(x1, x2).toFixed(2) || px2 < +mmin(x3, x4).toFixed(2) || px2 > +mmax(x3, x4).toFixed(2) || py2 < +mmin(y1, y2).toFixed(2) || py2 > +mmax(y1, y2).toFixed(2) || py2 < +mmin(y3, y4).toFixed(2) || py2 > +mmax(y3, y4).toFixed(2) ) { return; } return {x: px, y: py}; } function inter(bez1, bez2) { return interHelper(bez1, bez2); } function interCount(bez1, bez2) { return interHelper(bez1, bez2, 1); } function interHelper(bez1, bez2, justCount) { var bbox1 = R.bezierBBox(bez1), bbox2 = R.bezierBBox(bez2); if (!R.isBBoxIntersect(bbox1, bbox2)) { return justCount ? 0 : []; } var l1 = bezlen.apply(0, bez1), l2 = bezlen.apply(0, bez2), n1 = mmax(~~(l1 / 5), 1), n2 = mmax(~~(l2 / 5), 1), dots1 = [], dots2 = [], xy = {}, res = justCount ? 0 : []; for (var i = 0; i < n1 + 1; i++) { var p = R.findDotsAtSegment.apply(R, bez1.concat(i / n1)); dots1.push({x: p.x, y: p.y, t: i / n1}); } for (i = 0; i < n2 + 1; i++) { p = R.findDotsAtSegment.apply(R, bez2.concat(i / n2)); dots2.push({x: p.x, y: p.y, t: i / n2}); } for (i = 0; i < n1; i++) { for (var j = 0; j < n2; j++) { var di = dots1[i], di1 = dots1[i + 1], dj = dots2[j], dj1 = dots2[j + 1], ci = abs(di1.x - di.x) < .001 ? "y" : "x", cj = abs(dj1.x - dj.x) < .001 ? "y" : "x", is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y); if (is) { if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) { continue; } xy[is.x.toFixed(4)] = is.y.toFixed(4); var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t), t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t); if (t1 >= 0 && t1 <= 1.001 && t2 >= 0 && t2 <= 1.001) { if (justCount) { res++; } else { res.push({ x: is.x, y: is.y, t1: mmin(t1, 1), t2: mmin(t2, 1) }); } } } } } return res; } /*\ * Raphael.pathIntersection [ method ] ** * Utility method ** * Finds intersections of two paths > Parameters - path1 (string) path string - path2 (string) path string = (array) dots of intersection o [ o { o x: (number) x coordinate of the point o y: (number) y coordinate of the point o t1: (number) t value for segment of path1 o t2: (number) t value for segment of path2 o segment1: (number) order number for segment of path1 o segment2: (number) order number for segment of path2 o bez1: (array) eight coordinates representing beziér curve for the segment of path1 o bez2: (array) eight coordinates representing beziér curve for the segment of path2 o } o ] \*/ R.pathIntersection = function (path1, path2) { return interPathHelper(path1, path2); }; R.pathIntersectionNumber = function (path1, path2) { return interPathHelper(path1, path2, 1); }; function interPathHelper(path1, path2, justCount) { path1 = R._path2curve(path1); path2 = R._path2curve(path2); var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2, res = justCount ? 0 : []; for (var i = 0, ii = path1.length; i < ii; i++) { var pi = path1[i]; if (pi[0] == "M") { x1 = x1m = pi[1]; y1 = y1m = pi[2]; } else { if (pi[0] == "C") { bez1 = [x1, y1].concat(pi.slice(1)); x1 = bez1[6]; y1 = bez1[7]; } else { bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m]; x1 = x1m; y1 = y1m; } for (var j = 0, jj = path2.length; j < jj; j++) { var pj = path2[j]; if (pj[0] == "M") { x2 = x2m = pj[1]; y2 = y2m = pj[2]; } else { if (pj[0] == "C") { bez2 = [x2, y2].concat(pj.slice(1)); x2 = bez2[6]; y2 = bez2[7]; } else { bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m]; x2 = x2m; y2 = y2m; } var intr = interHelper(bez1, bez2, justCount); if (justCount) { res += intr; } else { for (var k = 0, kk = intr.length; k < kk; k++) { intr[k].segment1 = i; intr[k].segment2 = j; intr[k].bez1 = bez1; intr[k].bez2 = bez2; } res = res.concat(intr); } } } } } return res; } /*\ * Raphael.isPointInsidePath [ method ] ** * Utility method ** * Returns `true` if given point is inside a given closed path. > Parameters - path (string) path string - x (number) x of the point - y (number) y of the point = (boolean) true, if point is inside the path \*/ R.isPointInsidePath = function (path, x, y) { var bbox = R.pathBBox(path); return R.isPointInsideBBox(bbox, x, y) && interPathHelper(path, [["M", x, y], ["H", bbox.x2 + 10]], 1) % 2 == 1; }; R._removedFactory = function (methodname) { return function () { eve("raphael.log", null, "Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object", methodname); }; }; /*\ * Raphael.pathBBox [ method ] ** * Utility method ** * Return bounding box of a given path > Parameters - path (string) path string = (object) bounding box o { o x: (number) x coordinate of the left top point of the box o y: (number) y coordinate of the left top point of the box o x2: (number) x coordinate of the right bottom point of the box o y2: (number) y coordinate of the right bottom point of the box o width: (number) width of the box o height: (number) height of the box o cx: (number) x coordinate of the center of the box o cy: (number) y coordinate of the center of the box o } \*/ var pathDimensions = R.pathBBox = function (path) { var pth = paths(path); if (pth.bbox) { return clone(pth.bbox); } if (!path) { return {x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0}; } path = path2curve(path); var x = 0, y = 0, X = [], Y = [], p; for (var i = 0, ii = path.length; i < ii; i++) { p = path[i]; if (p[0] == "M") { x = p[1]; y = p[2]; X.push(x); Y.push(y); } else { var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); X = X[concat](dim.min.x, dim.max.x); Y = Y[concat](dim.min.y, dim.max.y); x = p[5]; y = p[6]; } } var xmin = mmin[apply](0, X), ymin = mmin[apply](0, Y), xmax = mmax[apply](0, X), ymax = mmax[apply](0, Y), width = xmax - xmin, height = ymax - ymin, bb = { x: xmin, y: ymin, x2: xmax, y2: ymax, width: width, height: height, cx: xmin + width / 2, cy: ymin + height / 2 }; pth.bbox = clone(bb); return bb; }, pathClone = function (pathArray) { var res = clone(pathArray); res.toString = R._path2string; return res; }, pathToRelative = R._pathToRelative = function (pathArray) { var pth = paths(pathArray); if (pth.rel) { return pathClone(pth.rel); } if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption pathArray = R.parsePathString(pathArray); } var res = [], x = 0, y = 0, mx = 0, my = 0, start = 0; if (pathArray[0][0] == "M") { x = pathArray[0][1]; y = pathArray[0][2]; mx = x; my = y; start++; res.push(["M", x, y]); } for (var i = start, ii = pathArray.length; i < ii; i++) { var r = res[i] = [], pa = pathArray[i]; if (pa[0] != lowerCase.call(pa[0])) { r[0] = lowerCase.call(pa[0]); switch (r[0]) { case "a": r[1] = pa[1]; r[2] = pa[2]; r[3] = pa[3]; r[4] = pa[4]; r[5] = pa[5]; r[6] = +(pa[6] - x).toFixed(3); r[7] = +(pa[7] - y).toFixed(3); break; case "v": r[1] = +(pa[1] - y).toFixed(3); break; case "m": mx = pa[1]; my = pa[2]; default: for (var j = 1, jj = pa.length; j < jj; j++) { r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); } } } else { r = res[i] = []; if (pa[0] == "m") { mx = pa[1] + x; my = pa[2] + y; } for (var k = 0, kk = pa.length; k < kk; k++) { res[i][k] = pa[k]; } } var len = res[i].length; switch (res[i][0]) { case "z": x = mx; y = my; break; case "h": x += +res[i][len - 1]; break; case "v": y += +res[i][len - 1]; break; default: x += +res[i][len - 2]; y += +res[i][len - 1]; } } res.toString = R._path2string; pth.rel = pathClone(res); return res; }, pathToAbsolute = R._pathToAbsolute = function (pathArray) { var pth = paths(pathArray); if (pth.abs) { return pathClone(pth.abs); } if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption pathArray = R.parsePathString(pathArray); } if (!pathArray || !pathArray.length) { return [["M", 0, 0]]; } var res = [], x = 0, y = 0, mx = 0, my = 0, start = 0; if (pathArray[0][0] == "M") { x = +pathArray[0][1]; y = +pathArray[0][2]; mx = x; my = y; start++; res[0] = ["M", x, y]; } var crz = pathArray.length == 3 && pathArray[0][0] == "M" && pathArray[1][0].toUpperCase() == "R" && pathArray[2][0].toUpperCase() == "Z"; for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) { res.push(r = []); pa = pathArray[i]; if (pa[0] != upperCase.call(pa[0])) { r[0] = upperCase.call(pa[0]); switch (r[0]) { case "A": r[1] = pa[1]; r[2] = pa[2]; r[3] = pa[3]; r[4] = pa[4]; r[5] = pa[5]; r[6] = +(pa[6] + x); r[7] = +(pa[7] + y); break; case "V": r[1] = +pa[1] + y; break; case "H": r[1] = +pa[1] + x; break; case "R": var dots = [x, y][concat](pa.slice(1)); for (var j = 2, jj = dots.length; j < jj; j++) { dots[j] = +dots[j] + x; dots[++j] = +dots[j] + y; } res.pop(); res = res[concat](catmullRom2bezier(dots, crz)); break; case "M": mx = +pa[1] + x; my = +pa[2] + y; default: for (j = 1, jj = pa.length; j < jj; j++) { r[j] = +pa[j] + ((j % 2) ? x : y); } } } else if (pa[0] == "R") { dots = [x, y][concat](pa.slice(1)); res.pop(); res = res[concat](catmullRom2bezier(dots, crz)); r = ["R"][concat](pa.slice(-2)); } else { for (var k = 0, kk = pa.length; k < kk; k++) { r[k] = pa[k]; } } switch (r[0]) { case "Z": x = mx; y = my; break; case "H": x = r[1]; break; case "V": y = r[1]; break; case "M": mx = r[r.length - 2]; my = r[r.length - 1]; default: x = r[r.length - 2]; y = r[r.length - 1]; } } res.toString = R._path2string; pth.abs = pathClone(res); return res; }, l2c = function (x1, y1, x2, y2) { return [x1, y1, x2, y2, x2, y2]; }, q2c = function (x1, y1, ax, ay, x2, y2) { var _13 = 1 / 3, _23 = 2 / 3; return [ _13 * x1 + _23 * ax, _13 * y1 + _23 * ay, _13 * x2 + _23 * ax, _13 * y2 + _23 * ay, x2, y2 ]; }, a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { // for more information of where this math came from visit: // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes var _120 = PI * 120 / 180, rad = PI / 180 * (+angle || 0), res = [], xy, rotate = cacher(function (x, y, rad) { var X = x * math.cos(rad) - y * math.sin(rad), Y = x * math.sin(rad) + y * math.cos(rad); return {x: X, y: Y}; }); if (!recursive) { xy = rotate(x1, y1, -rad); x1 = xy.x; y1 = xy.y; xy = rotate(x2, y2, -rad); x2 = xy.x; y2 = xy.y; var cos = math.cos(PI / 180 * angle), sin = math.sin(PI / 180 * angle), x = (x1 - x2) / 2, y = (y1 - y2) / 2; var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); if (h > 1) { h = math.sqrt(h); rx = h * rx; ry = h * ry; } var rx2 = rx * rx, ry2 = ry * ry, k = (large_arc_flag == sweep_flag ? -1 : 1) * math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))), cx = k * rx * y / ry + (x1 + x2) / 2, cy = k * -ry * x / rx + (y1 + y2) / 2, f1 = math.asin(((y1 - cy) / ry).toFixed(9)), f2 = math.asin(((y2 - cy) / ry).toFixed(9)); f1 = x1 < cx ? PI - f1 : f1; f2 = x2 < cx ? PI - f2 : f2; f1 < 0 && (f1 = PI * 2 + f1); f2 < 0 && (f2 = PI * 2 + f2); if (sweep_flag && f1 > f2) { f1 = f1 - PI * 2; } if (!sweep_flag && f2 > f1) { f2 = f2 - PI * 2; } } else { f1 = recursive[0]; f2 = recursive[1]; cx = recursive[2]; cy = recursive[3]; } var df = f2 - f1; if (abs(df) > _120) { var f2old = f2, x2old = x2, y2old = y2; f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); x2 = cx + rx * math.cos(f2); y2 = cy + ry * math.sin(f2); res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); } df = f2 - f1; var c1 = math.cos(f1), s1 = math.sin(f1), c2 = math.cos(f2), s2 = math.sin(f2), t = math.tan(df / 4), hx = 4 / 3 * rx * t, hy = 4 / 3 * ry * t, m1 = [x1, y1], m2 = [x1 + hx * s1, y1 - hy * c1], m3 = [x2 + hx * s2, y2 - hy * c2], m4 = [x2, y2]; m2[0] = 2 * m1[0] - m2[0]; m2[1] = 2 * m1[1] - m2[1]; if (recursive) { return [m2, m3, m4][concat](res); } else { res = [m2, m3, m4][concat](res).join()[split](","); var newres = []; for (var i = 0, ii = res.length; i < ii; i++) { newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; } return newres; } }, findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { var t1 = 1 - t; return { x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x, y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y }; }, curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x), b = 2 * (c1x - p1x) - 2 * (c2x - c1x), c = p1x - c1x, t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a, t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a, y = [p1y, p2y], x = [p1x, p2x], dot; abs(t1) > "1e12" && (t1 = .5); abs(t2) > "1e12" && (t2 = .5); if (t1 > 0 && t1 < 1) { dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); x.push(dot.x); y.push(dot.y); } if (t2 > 0 && t2 < 1) { dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); x.push(dot.x); y.push(dot.y); } a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y); b = 2 * (c1y - p1y) - 2 * (c2y - c1y); c = p1y - c1y; t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a; t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a; abs(t1) > "1e12" && (t1 = .5); abs(t2) > "1e12" && (t2 = .5); if (t1 > 0 && t1 < 1) { dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); x.push(dot.x); y.push(dot.y); } if (t2 > 0 && t2 < 1) { dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); x.push(dot.x); y.push(dot.y); } return { min: {x: mmin[apply](0, x), y: mmin[apply](0, y)}, max: {x: mmax[apply](0, x), y: mmax[apply](0, y)} }; }), path2curve = R._path2curve = cacher(function (path, path2) { var pth = !path2 && paths(path); if (!path2 && pth.curve) { return pathClone(pth.curve); } var p = pathToAbsolute(path), p2 = path2 && pathToAbsolute(path2), attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, processPath = function (path, d, pcom) { var nx, ny, tq = {T:1, Q:1}; if (!path) { return ["C", d.x, d.y, d.x, d.y, d.x, d.y]; } !(path[0] in tq) && (d.qx = d.qy = null); switch (path[0]) { case "M": d.X = path[1]; d.Y = path[2]; break; case "A": path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1)))); break; case "S": if (pcom == "C" || pcom == "S") { // In "S" case we have to take into account, if the previous command is C/S. nx = d.x * 2 - d.bx; // And reflect the previous ny = d.y * 2 - d.by; // command's control point relative to the current point. } else { // or some else or nothing nx = d.x; ny = d.y; } path = ["C", nx, ny][concat](path.slice(1)); break; case "T": if (pcom == "Q" || pcom == "T") { // In "T" case we have to take into account, if the previous command is Q/T. d.qx = d.x * 2 - d.qx; // And make a reflection similar d.qy = d.y * 2 - d.qy; // to case "S". } else { // or something else or nothing d.qx = d.x; d.qy = d.y; } path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); break; case "Q": d.qx = path[1]; d.qy = path[2]; path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4])); break; case "L": path = ["C"][concat](l2c(d.x, d.y, path[1], path[2])); break; case "H": path = ["C"][concat](l2c(d.x, d.y, path[1], d.y)); break; case "V": path = ["C"][concat](l2c(d.x, d.y, d.x, path[1])); break; case "Z": path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y)); break; } return path; }, fixArc = function (pp, i) { if (pp[i].length > 7) { pp[i].shift(); var pi = pp[i]; while (pi.length) { pcoms1[i]="A"; // if created multiple C:s, their original seg is saved p2 && (pcoms2[i]="A"); // the same as above pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6))); } pp.splice(i, 1); ii = mmax(p.length, p2 && p2.length || 0); } }, fixM = function (path1, path2, a1, a2, i) { if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { path2.splice(i, 0, ["M", a2.x, a2.y]); a1.bx = 0; a1.by = 0; a1.x = path1[i][1]; a1.y = path1[i][2]; ii = mmax(p.length, p2 && p2.length || 0); } }, pcoms1 = [], // path commands of original path p pcoms2 = [], // path commands of original path p2 pfirst = "", // temporary holder for original path command pcom = ""; // holder for previous path command of original path for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) { p[i] && (pfirst = p[i][0]); // save current path command if (pfirst != "C") // C is not saved yet, because it may be result of conversion { pcoms1[i] = pfirst; // Save current path command i && ( pcom = pcoms1[i-1]); // Get previous path command pcom } p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath if (pcoms1[i] != "A" && pfirst == "C") pcoms1[i] = "C"; // A is the only command // which may produce multiple C:s // so we have to make sure that C is also C in original path fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1 if (p2) { // the same procedures is done to p2 p2[i] && (pfirst = p2[i][0]); if (pfirst != "C") { pcoms2[i] = pfirst; i && (pcom = pcoms2[i-1]); } p2[i] = processPath(p2[i], attrs2, pcom); if (pcoms2[i]!="A" && pfirst=="C") pcoms2[i]="C"; fixArc(p2, i); } fixM(p, p2, attrs, attrs2, i); fixM(p2, p, attrs2, attrs, i); var seg = p[i], seg2 = p2 && p2[i], seglen = seg.length, seg2len = p2 && seg2.length; attrs.x = seg[seglen - 2]; attrs.y = seg[seglen - 1]; attrs.bx = toFloat(seg[seglen - 4]) || attrs.x; attrs.by = toFloat(seg[seglen - 3]) || attrs.y; attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x); attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y); attrs2.x = p2 && seg2[seg2len - 2]; attrs2.y = p2 && seg2[seg2len - 1]; } if (!p2) { pth.curve = pathClone(p); } return p2 ? [p, p2] : p; }, null, pathClone), parseDots = R._parseDots = cacher(function (gradient) { var dots = []; for (var i = 0, ii = gradient.length; i < ii; i++) { var dot = {}, par = gradient[i].match(/^([^:]*):?([\d\.]*)/); dot.color = R.getRGB(par[1]); if (dot.color.error) { return null; } dot.opacity = dot.color.opacity; dot.color = dot.color.hex; par[2] && (dot.offset = par[2] + "%"); dots.push(dot); } for (i = 1, ii = dots.length - 1; i < ii; i++) { if (!dots[i].offset) { var start = toFloat(dots[i - 1].offset || 0), end = 0; for (var j = i + 1; j < ii; j++) { if (dots[j].offset) { end = dots[j].offset; break; } } if (!end) { end = 100; j = ii; } end = toFloat(end); var d = (end - start) / (j - i + 1); for (; i < j; i++) { start += d; dots[i].offset = start + "%"; } } } return dots; }), tear = R._tear = function (el, paper) { el == paper.top && (paper.top = el.prev); el == paper.bottom && (paper.bottom = el.next); el.next && (el.next.prev = el.prev); el.prev && (el.prev.next = el.next); }, tofront = R._tofront = function (el, paper) { if (paper.top === el) { return; } tear(el, paper); el.next = null; el.prev = paper.top; paper.top.next = el; paper.top = el; }, toback = R._toback = function (el, paper) { if (paper.bottom === el) { return; } tear(el, paper); el.next = paper.bottom; el.prev = null; paper.bottom.prev = el; paper.bottom = el; }, insertafter = R._insertafter = function (el, el2, paper) { tear(el, paper); el2 == paper.top && (paper.top = el); el2.next && (el2.next.prev = el); el.next = el2.next; el.prev = el2; el2.next = el; }, insertbefore = R._insertbefore = function (el, el2, paper) { tear(el, paper); el2 == paper.bottom && (paper.bottom = el); el2.prev && (el2.prev.next = el); el.prev = el2.prev; el2.prev = el; el.next = el2; }, /*\ * Raphael.toMatrix [ method ] ** * Utility method ** * Returns matrix of transformations applied to a given path > Parameters - path (string) path string - transform (string|array) transformation string = (object) @Matrix \*/ toMatrix = R.toMatrix = function (path, transform) { var bb = pathDimensions(path), el = { _: { transform: E }, getBBox: function () { return bb; } }; extractTransform(el, transform); return el.matrix; }, /*\ * Raphael.transformPath [ method ] ** * Utility method ** * Returns path transformed by a given transformation > Parameters - path (string) path string - transform (string|array) transformation string = (string) path \*/ transformPath = R.transformPath = function (path, transform) { return mapPath(path, toMatrix(path, transform)); }, extractTransform = R._extractTransform = function (el, tstr) { if (tstr == null) { return el._.transform; } tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E); var tdata = R.parseTransformString(tstr), deg = 0, dx = 0, dy = 0, sx = 1, sy = 1, _ = el._, m = new Matrix; _.transform = tdata || []; if (tdata) { for (var i = 0, ii = tdata.length; i < ii; i++) { var t = tdata[i], tlen = t.length, command = Str(t[0]).toLowerCase(), absolute = t[0] != command, inver = absolute ? m.invert() : 0, x1, y1, x2, y2, bb; if (command == "t" && tlen == 3) { if (absolute) { x1 = inver.x(0, 0); y1 = inver.y(0, 0); x2 = inver.x(t[1], t[2]); y2 = inver.y(t[1], t[2]); m.translate(x2 - x1, y2 - y1); } else { m.translate(t[1], t[2]); } } else if (command == "r") { if (tlen == 2) { bb = bb || el.getBBox(1); m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2); deg += t[1]; } else if (tlen == 4) { if (absolute) { x2 = inver.x(t[2], t[3]); y2 = inver.y(t[2], t[3]); m.rotate(t[1], x2, y2); } else { m.rotate(t[1], t[2], t[3]); } deg += t[1]; } } else if (command == "s") { if (tlen == 2 || tlen == 3) { bb = bb || el.getBBox(1); m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2); sx *= t[1]; sy *= t[tlen - 1]; } else if (tlen == 5) { if (absolute) { x2 = inver.x(t[3], t[4]); y2 = inver.y(t[3], t[4]); m.scale(t[1], t[2], x2, y2); } else { m.scale(t[1], t[2], t[3], t[4]); } sx *= t[1]; sy *= t[2]; } } else if (command == "m" && tlen == 7) { m.add(t[1], t[2], t[3], t[4], t[5], t[6]); } _.dirtyT = 1; el.matrix = m; } } /*\ * Element.matrix [ property (object) ] ** * Keeps @Matrix object, which represents element transformation \*/ el.matrix = m; _.sx = sx; _.sy = sy; _.deg = deg; _.dx = dx = m.e; _.dy = dy = m.f; if (sx == 1 && sy == 1 && !deg && _.bbox) { _.bbox.x += +dx; _.bbox.y += +dy; } else { _.dirtyT = 1; } }, getEmpty = function (item) { var l = item[0]; switch (l.toLowerCase()) { case "t": return [l, 0, 0]; case "m": return [l, 1, 0, 0, 1, 0, 0]; case "r": if (item.length == 4) { return [l, 0, item[2], item[3]]; } else { return [l, 0]; } case "s": if (item.length == 5) { return [l, 1, 1, item[3], item[4]]; } else if (item.length == 3) { return [l, 1, 1]; } else { return [l, 1]; } } }, equaliseTransform = R._equaliseTransform = function (t1, t2) { t2 = Str(t2).replace(/\.{3}|\u2026/g, t1); t1 = R.parseTransformString(t1) || []; t2 = R.parseTransformString(t2) || []; var maxlength = mmax(t1.length, t2.length), from = [], to = [], i = 0, j, jj, tt1, tt2; for (; i < maxlength; i++) { tt1 = t1[i] || getEmpty(t2[i]); tt2 = t2[i] || getEmpty(tt1); if ((tt1[0] != tt2[0]) || (tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) || (tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4])) ) { return; } from[i] = []; to[i] = []; for (j = 0, jj = mmax(tt1.length, tt2.length); j < jj; j++) { j in tt1 && (from[i][j] = tt1[j]); j in tt2 && (to[i][j] = tt2[j]); } } return { from: from, to: to }; }; R._getContainer = function (x, y, w, h) { var container; container = h == null && !R.is(x, "object") ? g.doc.getElementById(x) : x; if (container == null) { return; } if (container.tagName) { if (y == null) { return { container: container, width: container.style.pixelWidth || container.offsetWidth, height: container.style.pixelHeight || container.offsetHeight }; } else { return { container: container, width: y, height: w }; } } return { container: 1, x: x, y: y, width: w, height: h }; }; /*\ * Raphael.pathToRelative [ method ] ** * Utility method ** * Converts path to relative form > Parameters - pathString (string|array) path string or array of segments = (array) array of segments. \*/ R.pathToRelative = pathToRelative; R._engine = {}; /*\ * Raphael.path2curve [ method ] ** * Utility method ** * Converts path to a new path where all segments are cubic bezier curves. > Parameters - pathString (string|array) path string or array of segments = (array) array of segments. \*/ R.path2curve = path2curve; /*\ * Raphael.matrix [ method ] ** * Utility method ** * Returns matrix based on given parameters. > Parameters - a (number) - b (number) - c (number) - d (number) - e (number) - f (number) = (object) @Matrix \*/ R.matrix = function (a, b, c, d, e, f) { return new Matrix(a, b, c, d, e, f); }; function Matrix(a, b, c, d, e, f) { if (a != null) { this.a = +a; this.b = +b; this.c = +c; this.d = +d; this.e = +e; this.f = +f; } else { this.a = 1; this.b = 0; this.c = 0; this.d = 1; this.e = 0; this.f = 0; } } (function (matrixproto) { /*\ * Matrix.add [ method ] ** * Adds given matrix to existing one. > Parameters - a (number) - b (number) - c (number) - d (number) - e (number) - f (number) or - matrix (object) @Matrix \*/ matrixproto.add = function (a, b, c, d, e, f) { var out = [[], [], []], m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], matrix = [[a, c, e], [b, d, f], [0, 0, 1]], x, y, z, res; if (a && a instanceof Matrix) { matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]; } for (x = 0; x < 3; x++) { for (y = 0; y < 3; y++) { res = 0; for (z = 0; z < 3; z++) { res += m[x][z] * matrix[z][y]; } out[x][y] = res; } } this.a = out[0][0]; this.b = out[1][0]; this.c = out[0][1]; this.d = out[1][1]; this.e = out[0][2]; this.f = out[1][2]; }; /*\ * Matrix.invert [ method ] ** * Returns inverted version of the matrix = (object) @Matrix \*/ matrixproto.invert = function () { var me = this, x = me.a * me.d - me.b * me.c; return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x); }; /*\ * Matrix.clone [ method ] ** * Returns copy of the matrix = (object) @Matrix \*/ matrixproto.clone = function () { return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f); }; /*\ * Matrix.translate [ method ] ** * Translate the matrix > Parameters - x (number) - y (number) \*/ matrixproto.translate = function (x, y) { this.add(1, 0, 0, 1, x, y); }; /*\ * Matrix.scale [ method ] ** * Scales the matrix > Parameters - x (number) - y (number) #optional - cx (number) #optional - cy (number) #optional \*/ matrixproto.scale = function (x, y, cx, cy) { y == null && (y = x); (cx || cy) && this.add(1, 0, 0, 1, cx, cy); this.add(x, 0, 0, y, 0, 0); (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy); }; /*\ * Matrix.rotate [ method ] ** * Rotates the matrix > Parameters - a (number) - x (number) - y (number) \*/ matrixproto.rotate = function (a, x, y) { a = R.rad(a); x = x || 0; y = y || 0; var cos = +math.cos(a).toFixed(9), sin = +math.sin(a).toFixed(9); this.add(cos, sin, -sin, cos, x, y); this.add(1, 0, 0, 1, -x, -y); }; /*\ * Matrix.x [ method ] ** * Return x coordinate for given point after transformation described by the matrix. See also @Matrix.y > Parameters - x (number) - y (number) = (number) x \*/ matrixproto.x = function (x, y) { return x * this.a + y * this.c + this.e; }; /*\ * Matrix.y [ method ] ** * Return y coordinate for given point after transformation described by the matrix. See also @Matrix.x > Parameters - x (number) - y (number) = (number) y \*/ matrixproto.y = function (x, y) { return x * this.b + y * this.d + this.f; }; matrixproto.get = function (i) { return +this[Str.fromCharCode(97 + i)].toFixed(4); }; matrixproto.toString = function () { return R.svg ? "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")" : [this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join(); }; matrixproto.toFilter = function () { return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.get(0) + ", M12=" + this.get(2) + ", M21=" + this.get(1) + ", M22=" + this.get(3) + ", Dx=" + this.get(4) + ", Dy=" + this.get(5) + ", sizingmethod='auto expand')"; }; matrixproto.offset = function () { return [this.e.toFixed(4), this.f.toFixed(4)]; }; function norm(a) { return a[0] * a[0] + a[1] * a[1]; } function normalize(a) { var mag = math.sqrt(norm(a)); a[0] && (a[0] /= mag); a[1] && (a[1] /= mag); } /*\ * Matrix.split [ method ] ** * Splits matrix into primitive transformations = (object) in format: o dx (number) translation by x o dy (number) translation by y o scalex (number) scale by x o scaley (number) scale by y o shear (number) shear o rotate (number) rotation in deg o isSimple (boolean) could it be represented via simple transformations \*/ matrixproto.split = function () { var out = {}; // translation out.dx = this.e; out.dy = this.f; // scale and shear var row = [[this.a, this.c], [this.b, this.d]]; out.scalex = math.sqrt(norm(row[0])); normalize(row[0]); out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1]; row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear]; out.scaley = math.sqrt(norm(row[1])); normalize(row[1]); out.shear /= out.scaley; // rotation var sin = -row[0][1], cos = row[1][1]; if (cos < 0) { out.rotate = R.deg(math.acos(cos)); if (sin < 0) { out.rotate = 360 - out.rotate; } } else { out.rotate = R.deg(math.asin(sin)); } out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate); out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate; out.noRotation = !+out.shear.toFixed(9) && !out.rotate; return out; }; /*\ * Matrix.toTransformString [ method ] ** * Return transform string that represents given matrix = (string) transform string \*/ matrixproto.toTransformString = function (shorter) { var s = shorter || this[split](); if (s.isSimple) { s.scalex = +s.scalex.toFixed(4); s.scaley = +s.scaley.toFixed(4); s.rotate = +s.rotate.toFixed(4); return (s.dx || s.dy ? "t" + [s.dx, s.dy] : E) + (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) + (s.rotate ? "r" + [s.rotate, 0, 0] : E); } else { return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)]; } }; })(Matrix.prototype); var preventDefault = function () { this.returnValue = false; }, preventTouch = function () { return this.originalEvent.preventDefault(); }, stopPropagation = function () { this.cancelBubble = true; }, stopTouch = function () { return this.originalEvent.stopPropagation(); }, getEventPosition = function (e) { var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft; return { x: e.clientX + scrollX, y: e.clientY + scrollY }; }, addEvent = (function () { if (g.doc.addEventListener) { return function (obj, type, fn, element) { var f = function (e) { var pos = getEventPosition(e); return fn.call(element, e, pos.x, pos.y); }; obj.addEventListener(type, f, false); if (supportsTouch && touchMap[type]) { var _f = function (e) { var pos = getEventPosition(e), olde = e; for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) { if (e.targetTouches[i].target == obj) { e = e.targetTouches[i]; e.originalEvent = olde; e.preventDefault = preventTouch; e.stopPropagation = stopTouch; break; } } return fn.call(element, e, pos.x, pos.y); }; obj.addEventListener(touchMap[type], _f, false); } return function () { obj.removeEventListener(type, f, false); if (supportsTouch && touchMap[type]) obj.removeEventListener(touchMap[type], _f, false); return true; }; }; } else if (g.doc.attachEvent) { return function (obj, type, fn, element) { var f = function (e) { e = e || g.win.event; var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft, x = e.clientX + scrollX, y = e.clientY + scrollY; e.preventDefault = e.preventDefault || preventDefault; e.stopPropagation = e.stopPropagation || stopPropagation; return fn.call(element, e, x, y); }; obj.attachEvent("on" + type, f); var detacher = function () { obj.detachEvent("on" + type, f); return true; }; return detacher; }; } })(), drag = [], dragMove = function (e) { var x = e.clientX, y = e.clientY, scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft, dragi, j = drag.length; while (j--) { dragi = drag[j]; if (supportsTouch && e.touches) { var i = e.touches.length, touch; while (i--) { touch = e.touches[i]; if (touch.identifier == dragi.el._drag.id) { x = touch.clientX; y = touch.clientY; (e.originalEvent ? e.originalEvent : e).preventDefault(); break; } } } else { e.preventDefault(); } var node = dragi.el.node, o, next = node.nextSibling, parent = node.parentNode, display = node.style.display; g.win.opera && parent.removeChild(node); node.style.display = "none"; o = dragi.el.paper.getElementByPoint(x, y); node.style.display = display; g.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node)); o && eve("raphael.drag.over." + dragi.el.id, dragi.el, o); x += scrollX; y += scrollY; eve("raphael.drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e); } }, dragUp = function (e) { R.unmousemove(dragMove).unmouseup(dragUp); var i = drag.length, dragi; while (i--) { dragi = drag[i]; dragi.el._drag = {}; eve("raphael.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e); } drag = []; }, /*\ * Raphael.el [ property (object) ] ** * You can add your own method to elements. This is usefull when you want to hack default functionality or * want to wrap some common transformation or attributes in one method. In difference to canvas methods, * you can redefine element method at any time. Expending element methods wouldn’t affect set. > Usage | Raphael.el.red = function () { | this.attr({fill: "#f00"}); | }; | // then use it | paper.circle(100, 100, 20).red(); \*/ elproto = R.el = {}; /*\ * Element.click [ method ] ** * Adds event handler for click for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.unclick [ method ] ** * Removes event handler for click for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.dblclick [ method ] ** * Adds event handler for double click for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.undblclick [ method ] ** * Removes event handler for double click for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.mousedown [ method ] ** * Adds event handler for mousedown for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.unmousedown [ method ] ** * Removes event handler for mousedown for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.mousemove [ method ] ** * Adds event handler for mousemove for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.unmousemove [ method ] ** * Removes event handler for mousemove for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.mouseout [ method ] ** * Adds event handler for mouseout for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.unmouseout [ method ] ** * Removes event handler for mouseout for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.mouseover [ method ] ** * Adds event handler for mouseover for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.unmouseover [ method ] ** * Removes event handler for mouseover for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.mouseup [ method ] ** * Adds event handler for mouseup for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.unmouseup [ method ] ** * Removes event handler for mouseup for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.touchstart [ method ] ** * Adds event handler for touchstart for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.untouchstart [ method ] ** * Removes event handler for touchstart for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.touchmove [ method ] ** * Adds event handler for touchmove for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.untouchmove [ method ] ** * Removes event handler for touchmove for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.touchend [ method ] ** * Adds event handler for touchend for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.untouchend [ method ] ** * Removes event handler for touchend for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ /*\ * Element.touchcancel [ method ] ** * Adds event handler for touchcancel for the element. > Parameters - handler (function) handler for the event = (object) @Element \*/ /*\ * Element.untouchcancel [ method ] ** * Removes event handler for touchcancel for the element. > Parameters - handler (function) #optional handler for the event = (object) @Element \*/ for (var i = events.length; i--;) { (function (eventName) { R[eventName] = elproto[eventName] = function (fn, scope) { if (R.is(fn, "function")) { this.events = this.events || []; this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || g.doc, eventName, fn, scope || this)}); } return this; }; R["un" + eventName] = elproto["un" + eventName] = function (fn) { var events = this.events || [], l = events.length; while (l--){ if (events[l].name == eventName && (R.is(fn, "undefined") || events[l].f == fn)) { events[l].unbind(); events.splice(l, 1); !events.length && delete this.events; } } return this; }; })(events[i]); } /*\ * Element.data [ method ] ** * Adds or retrieves given value asociated with given key. ** * See also @Element.removeData > Parameters - key (string) key to store data - value (any) #optional value to store = (object) @Element * or, if value is not specified: = (any) value * or, if key and value are not specified: = (object) Key/value pairs for all the data associated with the element. > Usage | for (var i = 0, i < 5, i++) { | paper.circle(10 + 15 * i, 10, 10) | .attr({fill: "#000"}) | .data("i", i) | .click(function () { | alert(this.data("i")); | }); | } \*/ elproto.data = function (key, value) { var data = eldata[this.id] = eldata[this.id] || {}; if (arguments.length == 0) { return data; } if (arguments.length == 1) { if (R.is(key, "object")) { for (var i in key) if (key[has](i)) { this.data(i, key[i]); } return this; } eve("raphael.data.get." + this.id, this, data[key], key); return data[key]; } data[key] = value; eve("raphael.data.set." + this.id, this, value, key); return this; }; elproto.datum = function(){ return arguments.length == 0 ? this._bindData : ((this._bindData = arguments[0]), this); }; /*\ * Element.removeData [ method ] ** * Removes value associated with an element by given key. * If key is not provided, removes all the data of the element. > Parameters - key (string) #optional key = (object) @Element \*/ elproto.removeData = function (key) { if (key == null) { eldata[this.id] = {}; } else { eldata[this.id] && delete eldata[this.id][key]; } return this; }; /*\ * Element.getData [ method ] ** * Retrieves the element data = (object) data \*/ elproto.getData = function () { return clone(eldata[this.id] || {}); }; /*\ * Element.hover [ method ] ** * Adds event handlers for hover for the element. > Parameters - f_in (function) handler for hover in - f_out (function) handler for hover out - icontext (object) #optional context for hover in handler - ocontext (object) #optional context for hover out handler = (object) @Element \*/ elproto.hover = function (f_in, f_out, scope_in, scope_out) { return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in); }; /*\ * Element.unhover [ method ] ** * Removes event handlers for hover for the element. > Parameters - f_in (function) handler for hover in - f_out (function) handler for hover out = (object) @Element \*/ elproto.unhover = function (f_in, f_out) { return this.unmouseover(f_in).unmouseout(f_out); }; var draggable = []; /*\ * Element.drag [ method ] ** * Adds event handlers for drag of the element. > Parameters - onmove (function) handler for moving - onstart (function) handler for drag start - onend (function) handler for drag end - mcontext (object) #optional context for moving handler - scontext (object) #optional context for drag start handler - econtext (object) #optional context for drag end handler * Additionaly following `drag` events will be triggered: `drag.start.` on start, * `drag.end.` on end and `drag.move.` on every move. When element will be dragged over another element * `drag.over.` will be fired as well. * * Start event and start handler will be called in specified context or in context of the element with following parameters: o x (number) x position of the mouse o y (number) y position of the mouse o event (object) DOM event object * Move event and move handler will be called in specified context or in context of the element with following parameters: o dx (number) shift by x from the start point o dy (number) shift by y from the start point o x (number) x position of the mouse o y (number) y position of the mouse o event (object) DOM event object * End event and end handler will be called in specified context or in context of the element with following parameters: o event (object) DOM event object = (object) @Element \*/ elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) { function start(e) { (e.originalEvent || e).preventDefault(); var x = e.clientX, y = e.clientY, scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft; this._drag.id = e.identifier; if (supportsTouch && e.touches) { var i = e.touches.length, touch; while (i--) { touch = e.touches[i]; this._drag.id = touch.identifier; if (touch.identifier == this._drag.id) { x = touch.clientX; y = touch.clientY; break; } } } this._drag.x = x + scrollX; this._drag.y = y + scrollY; !drag.length && R.mousemove(dragMove).mouseup(dragUp); drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope}); onstart && eve.on("raphael.drag.start." + this.id, onstart); onmove && eve.on("raphael.drag.move." + this.id, onmove); onend && eve.on("raphael.drag.end." + this.id, onend); eve("raphael.drag.start." + this.id, start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e); } this._drag = {}; draggable.push({el: this, start: start}); this.mousedown(start); return this; }; /*\ * Element.onDragOver [ method ] ** * Shortcut for assigning event handler for `drag.over.` event, where id is id of the element (see @Element.id). > Parameters - f (function) handler for event, first argument would be the element you are dragging over \*/ elproto.onDragOver = function (f) { f ? eve.on("raphael.drag.over." + this.id, f) : eve.unbind("raphael.drag.over." + this.id); }; /*\ * Element.undrag [ method ] ** * Removes all drag event handlers from given element. \*/ elproto.undrag = function () { var i = draggable.length; while (i--) if (draggable[i].el == this) { this.unmousedown(draggable[i].start); draggable.splice(i, 1); eve.unbind("raphael.drag.*." + this.id); } !draggable.length && R.unmousemove(dragMove).unmouseup(dragUp); drag = []; }; /*\ * Paper.circle [ method ] ** * Draws a circle. ** > Parameters ** - x (number) x coordinate of the centre - y (number) y coordinate of the centre - r (number) radius = (object) Raphaël element object with type “circle” ** > Usage | var c = paper.circle(50, 50, 40); \*/ paperproto.circle = function (x, y, r) { var out = R._engine.circle(this, x || 0, y || 0, r || 0); this.__set__ && this.__set__.push(out); return out; }; /*\ * Paper.rect [ method ] * * Draws a rectangle. ** > Parameters ** - x (number) x coordinate of the top left corner - y (number) y coordinate of the top left corner - width (number) width - height (number) height - r (number) #optional radius for rounded corners, default is 0 = (object) Raphaël element object with type “rect” ** > Usage | // regular rectangle | var c = paper.rect(10, 10, 50, 50); | // rectangle with rounded corners | var c = paper.rect(40, 40, 50, 50, 10); \*/ paperproto.rect = function (x, y, w, h, r) { var out = R._engine.rect(this, x || 0, y || 0, w || 0, h || 0, r || 0); this.__set__ && this.__set__.push(out); return out; }; /*\ * Paper.ellipse [ method ] ** * Draws an ellipse. ** > Parameters ** - x (number) x coordinate of the centre - y (number) y coordinate of the centre - rx (number) horizontal radius - ry (number) vertical radius = (object) Raphaël element object with type “ellipse” ** > Usage | var c = paper.ellipse(50, 50, 40, 20); \*/ paperproto.ellipse = function (x, y, rx, ry) { var out = R._engine.ellipse(this, x || 0, y || 0, rx || 0, ry || 0); this.__set__ && this.__set__.push(out); return out; }; /*\ * Paper.path [ method ] ** * Creates a path element by given path data string. > Parameters - pathString (string) #optional path string in SVG format. * Path string consists of one-letter commands, followed by comma seprarated arguments in numercal form. Example: | "M10,20L30,40" * Here we can see two commands: “M”, with arguments `(10, 20)` and “L” with arguments `(30, 40)`. Upper case letter mean command is absolute, lower case—relative. * #

Here is short list of commands available, for more details see SVG path string format.

#
# # # # # # # # # # #
CommandNameParameters
Mmoveto(x y)+
Zclosepath(none)
Llineto(x y)+
Hhorizontal linetox+
Vvertical linetoy+
Ccurveto(x1 y1 x2 y2 x y)+
Ssmooth curveto(x2 y2 x y)+
Qquadratic Bézier curveto(x1 y1 x y)+
Tsmooth quadratic Bézier curveto(x y)+
Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
RCatmull-Rom curveto*x1 y1 (x y)+
* * “Catmull-Rom curveto” is a not standard SVG command and added in 2.0 to make life easier. * Note: there is a special case when path consist of just three commands: “M10,10R…z”. In this case path will smoothly connects to its beginning. > Usage | var c = paper.path("M10 10L90 90"); | // draw a diagonal line: | // move to 10,10, line to 90,90 * For example of path strings, check out these icons: http://raphaeljs.com/icons/ \*/ paperproto.path = function (pathString) { pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E); var out = R._engine.path(R.format[apply](R, arguments), this); this.__set__ && this.__set__.push(out); return out; }; /*\ * Paper.image [ method ] ** * Embeds an image into the surface. ** > Parameters ** - src (string) URI of the source image - x (number) x coordinate position - y (number) y coordinate position - width (number) width of the image - height (number) height of the image = (object) Raphaël element object with type “image” ** > Usage | var c = paper.image("apple.png", 10, 10, 80, 80); \*/ paperproto.image = function (src, x, y, w, h) { var out = R._engine.image(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0); this.__set__ && this.__set__.push(out); return out; }; /*\ * Paper.text [ method ] ** * Draws a text string. If you need line breaks, put “\n” in the string. ** > Parameters ** - x (number) x coordinate position - y (number) y coordinate position - text (string) The text string to draw = (object) Raphaël element object with type “text” ** > Usage | var t = paper.text(50, 50, "Raphaël\nkicks\nbutt!"); \*/ paperproto.text = function (x, y, text) { var out = R._engine.text(this, x || 0, y || 0, Str(text)); this.__set__ && this.__set__.push(out); return out; }; /*\ * Paper.set [ method ] ** * Creates array-like object to keep and operate several elements at once. * Warning: it doesn’t create any elements for itself in the page, it just groups existing elements. * Sets act as pseudo elements — all methods available to an element can be used on a set. = (object) array-like object that represents set of elements ** > Usage | var st = paper.set(); | st.push( | paper.circle(10, 10, 5), | paper.circle(30, 10, 5) | ); | st.attr({fill: "red"}); // changes the fill of both circles \*/ paperproto.set = function (itemsArray) { !R.is(itemsArray, "array") && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length)); var out = new Set(itemsArray); this.__set__ && this.__set__.push(out); out["paper"] = this; out["type"] = "set"; return out; }; /*\ * Paper.setStart [ method ] ** * Creates @Paper.set. All elements that will be created after calling this method and before calling * @Paper.setFinish will be added to the set. ** > Usage | paper.setStart(); | paper.circle(10, 10, 5), | paper.circle(30, 10, 5) | var st = paper.setFinish(); | st.attr({fill: "red"}); // changes the fill of both circles \*/ paperproto.setStart = function (set) { this.__set__ = set || this.set(); }; /*\ * Paper.setFinish [ method ] ** * See @Paper.setStart. This method finishes catching and returns resulting set. ** = (object) set \*/ paperproto.setFinish = function (set) { var out = this.__set__; delete this.__set__; return out; }; /*\ * Paper.getSize [ method ] ** * Obtains current paper actual size. ** = (object) \*/ paperproto.getSize = function () { var container = this.canvas.parentNode; return { width: container.offsetWidth, height: container.offsetHeight }; }; /*\ * Paper.setSize [ method ] ** * If you need to change dimensions of the canvas call this method ** > Parameters ** - width (number) new width of the canvas - height (number) new height of the canvas \*/ paperproto.setSize = function (width, height) { return R._engine.setSize.call(this, width, height); }; /*\ * Paper.setViewBox [ method ] ** * Sets the view box of the paper. Practically it gives you ability to zoom and pan whole paper surface by * specifying new boundaries. ** > Parameters ** - x (number) new x position, default is `0` - y (number) new y position, default is `0` - w (number) new width of the canvas - h (number) new height of the canvas - fit (boolean) `true` if you want graphics to fit into new boundary box \*/ paperproto.setViewBox = function (x, y, w, h, fit) { return R._engine.setViewBox.call(this, x, y, w, h, fit); }; /*\ * Paper.top [ property ] ** * Points to the topmost element on the paper \*/ /*\ * Paper.bottom [ property ] ** * Points to the bottom element on the paper \*/ paperproto.top = paperproto.bottom = null; /*\ * Paper.raphael [ property ] ** * Points to the @Raphael object/function \*/ paperproto.raphael = R; var getOffset = function (elem) { var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement, clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop, left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft; return { y: top, x: left }; }; /*\ * Paper.getElementByPoint [ method ] ** * Returns you topmost element under given point. ** = (object) Raphaël element object > Parameters ** - x (number) x coordinate from the top left corner of the window - y (number) y coordinate from the top left corner of the window > Usage | paper.getElementByPoint(mouseX, mouseY).attr({stroke: "#f00"}); \*/ paperproto.getElementByPoint = function (x, y) { var paper = this, svg = paper.canvas, target = g.doc.elementFromPoint(x, y); if (g.win.opera && target.tagName == "svg") { var so = getOffset(svg), sr = svg.createSVGRect(); sr.x = x - so.x; sr.y = y - so.y; sr.width = sr.height = 1; var hits = svg.getIntersectionList(sr, null); if (hits.length) { target = hits[hits.length - 1]; } } if (!target) { return null; } while (target.parentNode && target != svg.parentNode && !target.raphael) { target = target.parentNode; } target == paper.canvas.parentNode && (target = svg); target = target && target.raphael ? paper.getById(target.raphaelid) : null; return target; }; /*\ * Paper.getElementsByBBox [ method ] ** * Returns set of elements that have an intersecting bounding box ** > Parameters ** - bbox (object) bbox to check with = (object) @Set \*/ paperproto.getElementsByBBox = function (bbox) { var set = this.set(); this.forEach(function (el) { if (R.isBBoxIntersect(el.getBBox(), bbox)) { set.push(el); } }); return set; }; /*\ * Paper.getById [ method ] ** * Returns you element by its internal ID. ** > Parameters ** - id (number) id = (object) Raphaël element object \*/ paperproto.getById = function (id) { var bot = this.bottom; while (bot) { if (bot.id == id) { return bot; } bot = bot.next; } return null; }; /*\ * Paper.forEach [ method ] ** * Executes given function for each element on the paper * * If callback function returns `false` it will stop loop running. ** > Parameters ** - callback (function) function to run - thisArg (object) context object for the callback = (object) Paper object > Usage | paper.forEach(function (el) { | el.attr({ stroke: "blue" }); | }); \*/ paperproto.forEach = function (callback, thisArg) { var bot = this.bottom; while (bot) { if (callback.call(thisArg, bot) === false) { return this; } bot = bot.next; } return this; }; /*\ * Paper.getElementsByPoint [ method ] ** * Returns set of elements that have common point inside ** > Parameters ** - x (number) x coordinate of the point - y (number) y coordinate of the point = (object) @Set \*/ paperproto.getElementsByPoint = function (x, y) { var set = this.set(); this.forEach(function (el) { if (el.isPointInside(x, y)) { set.push(el); } }); return set; }; function x_y() { return this.x + S + this.y; } function x_y_w_h() { return this.x + S + this.y + S + this.width + " \xd7 " + this.height; } /*\ * Element.isPointInside [ method ] ** * Determine if given point is inside this element’s shape ** > Parameters ** - x (number) x coordinate of the point - y (number) y coordinate of the point = (boolean) `true` if point inside the shape \*/ elproto.isPointInside = function (x, y) { var rp = this.realPath = getPath[this.type](this); if (this.attr('transform') && this.attr('transform').length) { rp = R.transformPath(rp, this.attr('transform')); } return R.isPointInsidePath(rp, x, y); }; /*\ * Element.getBBox [ method ] ** * Return bounding box for a given element ** > Parameters ** - isWithoutTransform (boolean) flag, `true` if you want to have bounding box before transformations. Default is `false`. = (object) Bounding box object: o { o x: (number) top left corner x o y: (number) top left corner y o x2: (number) bottom right corner x o y2: (number) bottom right corner y o width: (number) width o height: (number) height o } \*/ elproto.getBBox = function (isWithoutTransform) { if (this.removed) { return {}; } var _ = this._; if (isWithoutTransform) { if (_.dirty || !_.bboxwt) { this.realPath = getPath[this.type](this); _.bboxwt = pathDimensions(this.realPath); _.bboxwt.toString = x_y_w_h; _.dirty = 0; } return _.bboxwt; } if (_.dirty || _.dirtyT || !_.bbox) { if (_.dirty || !this.realPath) { _.bboxwt = 0; this.realPath = getPath[this.type](this); } _.bbox = pathDimensions(mapPath(this.realPath, this.matrix)); _.bbox.toString = x_y_w_h; _.dirty = _.dirtyT = 0; } return _.bbox; }; /*\ * Element.clone [ method ] ** = (object) clone of a given element ** \*/ elproto.clone = function () { if (this.removed) { return null; } var out = this.paper[this.type]().attr(this.attr()); this.__set__ && this.__set__.push(out); return out; }; /*\ * Element.glow [ method ] ** * Return set of elements that create glow-like effect around given element. See @Paper.set. * * Note: Glow is not connected to the element. If you change element attributes it won’t adjust itself. ** > Parameters ** - glow (object) #optional parameters object with all properties optional: o { o width (number) size of the glow, default is `10` o fill (boolean) will it be filled, default is `false` o opacity (number) opacity, default is `0.5` o offsetx (number) horizontal offset, default is `0` o offsety (number) vertical offset, default is `0` o color (string) glow colour, default is `black` o } = (object) @Paper.set of elements that represents glow \*/ elproto.glow = function (glow) { if (this.type == "text") { return null; } glow = glow || {}; var s = { width: (glow.width || 10) + (+this.attr("stroke-width") || 1), fill: glow.fill || false, opacity: glow.opacity == null ? .5 : glow.opacity, offsetx: glow.offsetx || 0, offsety: glow.offsety || 0, color: glow.color || "#000" }, c = s.width / 2, r = this.paper, out = r.set(), path = this.realPath || getPath[this.type](this); path = this.matrix ? mapPath(path, this.matrix) : path; for (var i = 1; i < c + 1; i++) { out.push(r.path(path).attr({ stroke: s.color, fill: s.fill ? s.color : "none", "stroke-linejoin": "round", "stroke-linecap": "round", "stroke-width": +(s.width / c * i).toFixed(3), opacity: +(s.opacity / c).toFixed(3) })); } return out.insertBefore(this).translate(s.offsetx, s.offsety); }; var curveslengths = {}, getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) { if (length == null) { return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y); } else { return R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, getTatLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length)); } }, getLengthFactory = function (istotal, subpath) { return function (path, length, onlystart) { path = path2curve(path); var x, y, p, l, sp = "", subpaths = {}, point, len = 0; for (var i = 0, ii = path.length; i < ii; i++) { p = path[i]; if (p[0] == "M") { x = +p[1]; y = +p[2]; } else { l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); if (len + l > length) { if (subpath && !subpaths.start) { point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); sp += ["C" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y]; if (onlystart) {return sp;} subpaths.start = sp; sp = ["M" + point.x, point.y + "C" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join(); len += l; x = +p[5]; y = +p[6]; continue; } if (!istotal && !subpath) { point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); return {x: point.x, y: point.y, alpha: point.alpha}; } } len += l; x = +p[5]; y = +p[6]; } sp += p.shift() + p; } subpaths.end = sp; point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1); point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha}); return point; }; }; var getTotalLength = getLengthFactory(1), getPointAtLength = getLengthFactory(), getSubpathsAtLength = getLengthFactory(0, 1); /*\ * Raphael.getTotalLength [ method ] ** * Returns length of the given path in pixels. ** > Parameters ** - path (string) SVG path string. ** = (number) length. \*/ R.getTotalLength = getTotalLength; /*\ * Raphael.getPointAtLength [ method ] ** * Return coordinates of the point located at the given length on the given path. ** > Parameters ** - path (string) SVG path string - length (number) ** = (object) representation of the point: o { o x: (number) x coordinate o y: (number) y coordinate o alpha: (number) angle of derivative o } \*/ R.getPointAtLength = getPointAtLength; /*\ * Raphael.getSubpath [ method ] ** * Return subpath of a given path from given length to given length. ** > Parameters ** - path (string) SVG path string - from (number) position of the start of the segment - to (number) position of the end of the segment ** = (string) pathstring for the segment \*/ R.getSubpath = function (path, from, to) { if (this.getTotalLength(path) - to < 1e-6) { return getSubpathsAtLength(path, from).end; } var a = getSubpathsAtLength(path, to, 1); return from ? getSubpathsAtLength(a, from).end : a; }; /*\ * Element.getTotalLength [ method ] ** * Returns length of the path in pixels. Only works for element of “path” type. = (number) length. \*/ elproto.getTotalLength = function () { var path = this.getPath(); if (!path) { return; } if (this.node.getTotalLength) { return this.node.getTotalLength(); } return getTotalLength(path); }; /*\ * Element.getPointAtLength [ method ] ** * Return coordinates of the point located at the given length on the given path. Only works for element of “path” type. ** > Parameters ** - length (number) ** = (object) representation of the point: o { o x: (number) x coordinate o y: (number) y coordinate o alpha: (number) angle of derivative o } \*/ elproto.getPointAtLength = function (length) { var path = this.getPath(); if (!path) { return; } return getPointAtLength(path, length); }; /*\ * Element.getPath [ method ] ** * Returns path of the element. Only works for elements of “path” type and simple elements like circle. = (object) path ** \*/ elproto.getPath = function () { var path, getPath = R._getPath[this.type]; if (this.type == "text" || this.type == "set") { return; } if (getPath) { path = getPath(this); } return path; }; /*\ * Element.getSubpath [ method ] ** * Return subpath of a given element from given length to given length. Only works for element of “path” type. ** > Parameters ** - from (number) position of the start of the segment - to (number) position of the end of the segment ** = (string) pathstring for the segment \*/ elproto.getSubpath = function (from, to) { var path = this.getPath(); if (!path) { return; } return R.getSubpath(path, from, to); }; /*\ * Raphael.easing_formulas [ property ] ** * Object that contains easing formulas for animation. You could extend it with your own. By default it has following list of easing: # #

See also Easing demo.

\*/ var ef = R.easing_formulas = { linear: function (n) { return n; }, "<": function (n) { return pow(n, 1.7); }, ">": function (n) { return pow(n, .48); }, "<>": function (n) { var q = .48 - n / 1.04, Q = math.sqrt(.1734 + q * q), x = Q - q, X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1), y = -Q - q, Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1), t = X + Y + .5; return (1 - t) * 3 * t * t + t * t * t; }, backIn: function (n) { var s = 1.70158; return n * n * ((s + 1) * n - s); }, backOut: function (n) { n = n - 1; var s = 1.70158; return n * n * ((s + 1) * n + s) + 1; }, elastic: function (n) { if (n == !!n) { return n; } return pow(2, -10 * n) * math.sin((n - .075) * (2 * PI) / .3) + 1; }, bounce: function (n) { var s = 7.5625, p = 2.75, l; if (n < (1 / p)) { l = s * n * n; } else { if (n < (2 / p)) { n -= (1.5 / p); l = s * n * n + .75; } else { if (n < (2.5 / p)) { n -= (2.25 / p); l = s * n * n + .9375; } else { n -= (2.625 / p); l = s * n * n + .984375; } } } return l; } }; ef.easeIn = ef["ease-in"] = ef["<"]; ef.easeOut = ef["ease-out"] = ef[">"]; ef.easeInOut = ef["ease-in-out"] = ef["<>"]; ef["back-in"] = ef.backIn; ef["back-out"] = ef.backOut; var animationElements = [], requestAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { setTimeout(callback, 16); }, animation = function () { var Now = +new Date, l = 0; for (; l < animationElements.length; l++) { var e = animationElements[l]; if (e.el.removed || e.paused) { continue; } var time = Now - e.start, ms = e.ms, easing = e.easing, from = e.from, diff = e.diff, to = e.to, t = e.t, that = e.el, set = {}, now, init = {}, key; if (e.initstatus) { time = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * ms; e.status = e.initstatus; delete e.initstatus; e.stop && animationElements.splice(l--, 1); } else { e.status = (e.prev + (e.percent - e.prev) * (time / ms)) / e.anim.top; } if (time < 0) { continue; } if (time < ms) { var pos = easing(time / ms); for (var attr in from) if (from[has](attr)) { switch (availableAnimAttrs[attr]) { case nu: now = +from[attr] + pos * ms * diff[attr]; break; case "colour": now = "rgb(" + [ upto255(round(from[attr].r + pos * ms * diff[attr].r)), upto255(round(from[attr].g + pos * ms * diff[attr].g)), upto255(round(from[attr].b + pos * ms * diff[attr].b)) ].join(",") + ")"; break; case "path": now = []; for (var i = 0, ii = from[attr].length; i < ii; i++) { now[i] = [from[attr][i][0]]; for (var j = 1, jj = from[attr][i].length; j < jj; j++) { now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j]; } now[i] = now[i].join(S); } now = now.join(S); break; case "transform": if (diff[attr].real) { now = []; for (i = 0, ii = from[attr].length; i < ii; i++) { now[i] = [from[attr][i][0]]; for (j = 1, jj = from[attr][i].length; j < jj; j++) { now[i][j] = from[attr][i][j] + pos * ms * diff[attr][i][j]; } } } else { var get = function (i) { return +from[attr][i] + pos * ms * diff[attr][i]; }; // now = [["r", get(2), 0, 0], ["t", get(3), get(4)], ["s", get(0), get(1), 0, 0]]; now = [["m", get(0), get(1), get(2), get(3), get(4), get(5)]]; } break; case "csv": if (attr == "clip-rect") { now = []; i = 4; while (i--) { now[i] = +from[attr][i] + pos * ms * diff[attr][i]; } } break; default: var from2 = [][concat](from[attr]); now = []; i = that.paper.customAttributes[attr].length; while (i--) { now[i] = +from2[i] + pos * ms * diff[attr][i]; } break; } set[attr] = now; } that.attr(set); (function (id, that, anim) { setTimeout(function () { eve("raphael.anim.frame." + id, that, anim); }); })(that.id, that, e.anim); } else { (function(f, el, a) { setTimeout(function() { eve("raphael.anim.frame." + el.id, el, a); eve("raphael.anim.finish." + el.id, el, a); R.is(f, "function") && f.call(el); }); })(e.callback, that, e.anim); that.attr(to); animationElements.splice(l--, 1); if (e.repeat > 1 && !e.next) { for (key in to) if (to[has](key)) { init[key] = e.totalOrigin[key]; } e.el.attr(init); runAnimation(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1); } if (e.next && !e.stop) { runAnimation(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat); } } } animationElements.length && requestAnimFrame(animation); }, upto255 = function (color) { return color > 255 ? 255 : color < 0 ? 0 : color; }; /*\ * Element.animateWith [ method ] ** * Acts similar to @Element.animate, but ensure that given animation runs in sync with another given element. ** > Parameters ** - el (object) element to sync with - anim (object) animation to sync with - params (object) #optional final attributes for the element, see also @Element.attr - ms (number) #optional number of milliseconds for animation to run - easing (string) #optional easing type. Accept on of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)` - callback (function) #optional callback function. Will be called at the end of animation. * or - element (object) element to sync with - anim (object) animation to sync with - animation (object) #optional animation object, see @Raphael.animation ** = (object) original element \*/ elproto.animateWith = function (el, anim, params, ms, easing, callback) { var element = this; if (element.removed) { callback && callback.call(element); return element; } var a = params instanceof Animation ? params : R.animation(params, ms, easing, callback), x, y; runAnimation(a, element, a.percents[0], null, element.attr()); for (var i = 0, ii = animationElements.length; i < ii; i++) { if (animationElements[i].anim == anim && animationElements[i].el == el) { animationElements[ii - 1].start = animationElements[i].start; break; } } return element; // // // var a = params ? R.animation(params, ms, easing, callback) : anim, // status = element.status(anim); // return this.animate(a).status(a, status * anim.ms / a.ms); }; function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) { var cx = 3 * p1x, bx = 3 * (p2x - p1x) - cx, ax = 1 - cx - bx, cy = 3 * p1y, by = 3 * (p2y - p1y) - cy, ay = 1 - cy - by; function sampleCurveX(t) { return ((ax * t + bx) * t + cx) * t; } function solve(x, epsilon) { var t = solveCurveX(x, epsilon); return ((ay * t + by) * t + cy) * t; } function solveCurveX(x, epsilon) { var t0, t1, t2, x2, d2, i; for(t2 = x, i = 0; i < 8; i++) { x2 = sampleCurveX(t2) - x; if (abs(x2) < epsilon) { return t2; } d2 = (3 * ax * t2 + 2 * bx) * t2 + cx; if (abs(d2) < 1e-6) { break; } t2 = t2 - x2 / d2; } t0 = 0; t1 = 1; t2 = x; if (t2 < t0) { return t0; } if (t2 > t1) { return t1; } while (t0 < t1) { x2 = sampleCurveX(t2); if (abs(x2 - x) < epsilon) { return t2; } if (x > x2) { t0 = t2; } else { t1 = t2; } t2 = (t1 - t0) / 2 + t0; } return t2; } return solve(t, 1 / (200 * duration)); } elproto.onAnimation = function (f) { f ? eve.on("raphael.anim.frame." + this.id, f) : eve.unbind("raphael.anim.frame." + this.id); return this; }; function Animation(anim, ms) { var percents = [], newAnim = {}; this.ms = ms; this.times = 1; if (anim) { for (var attr in anim) if (anim[has](attr)) { newAnim[toFloat(attr)] = anim[attr]; percents.push(toFloat(attr)); } percents.sort(sortByNumber); } this.anim = newAnim; this.top = percents[percents.length - 1]; this.percents = percents; } /*\ * Animation.delay [ method ] ** * Creates a copy of existing animation object with given delay. ** > Parameters ** - delay (number) number of ms to pass between animation start and actual animation ** = (object) new altered Animation object | var anim = Raphael.animation({cx: 10, cy: 20}, 2e3); | circle1.animate(anim); // run the given animation immediately | circle2.animate(anim.delay(500)); // run the given animation after 500 ms \*/ Animation.prototype.delay = function (delay) { var a = new Animation(this.anim, this.ms); a.times = this.times; a.del = +delay || 0; return a; }; /*\ * Animation.repeat [ method ] ** * Creates a copy of existing animation object with given repetition. ** > Parameters ** - repeat (number) number iterations of animation. For infinite animation pass `Infinity` ** = (object) new altered Animation object \*/ Animation.prototype.repeat = function (times) { var a = new Animation(this.anim, this.ms); a.del = this.del; a.times = math.floor(mmax(times, 0)) || 1; return a; }; function runAnimation(anim, element, percent, status, totalOrigin, times) { percent = toFloat(percent); var params, isInAnim, isInAnimSet, percents = [], next, prev, timestamp, ms = anim.ms, from = {}, to = {}, diff = {}; if (status) { for (i = 0, ii = animationElements.length; i < ii; i++) { var e = animationElements[i]; if (e.el.id == element.id && e.anim == anim) { if (e.percent != percent) { animationElements.splice(i, 1); isInAnimSet = 1; } else { isInAnim = e; } element.attr(e.totalOrigin); break; } } } else { status = +to; // NaN } for (var i = 0, ii = anim.percents.length; i < ii; i++) { if (anim.percents[i] == percent || anim.percents[i] > status * anim.top) { percent = anim.percents[i]; prev = anim.percents[i - 1] || 0; ms = ms / anim.top * (percent - prev); next = anim.percents[i + 1]; params = anim.anim[percent]; break; } else if (status) { element.attr(anim.anim[anim.percents[i]]); } } if (!params) { return; } if (!isInAnim) { for (var attr in params) if (params[has](attr)) { if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) { from[attr] = element.attr(attr); (from[attr] == null) && (from[attr] = availableAttrs[attr]); to[attr] = params[attr]; switch (availableAnimAttrs[attr]) { case nu: diff[attr] = (to[attr] - from[attr]) / ms; break; case "colour": from[attr] = R.getRGB(from[attr]); var toColour = R.getRGB(to[attr]); diff[attr] = { r: (toColour.r - from[attr].r) / ms, g: (toColour.g - from[attr].g) / ms, b: (toColour.b - from[attr].b) / ms }; break; case "path": var pathes = path2curve(from[attr], to[attr]), toPath = pathes[1]; from[attr] = pathes[0]; diff[attr] = []; for (i = 0, ii = from[attr].length; i < ii; i++) { diff[attr][i] = [0]; for (var j = 1, jj = from[attr][i].length; j < jj; j++) { diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms; } } break; case "transform": var _ = element._, eq = equaliseTransform(_[attr], to[attr]); if (eq) { from[attr] = eq.from; to[attr] = eq.to; diff[attr] = []; diff[attr].real = true; for (i = 0, ii = from[attr].length; i < ii; i++) { diff[attr][i] = [from[attr][i][0]]; for (j = 1, jj = from[attr][i].length; j < jj; j++) { diff[attr][i][j] = (to[attr][i][j] - from[attr][i][j]) / ms; } } } else { var m = (element.matrix || new Matrix), to2 = { _: {transform: _.transform}, getBBox: function () { return element.getBBox(1); } }; from[attr] = [ m.a, m.b, m.c, m.d, m.e, m.f ]; extractTransform(to2, to[attr]); to[attr] = to2._.transform; diff[attr] = [ (to2.matrix.a - m.a) / ms, (to2.matrix.b - m.b) / ms, (to2.matrix.c - m.c) / ms, (to2.matrix.d - m.d) / ms, (to2.matrix.e - m.e) / ms, (to2.matrix.f - m.f) / ms ]; // from[attr] = [_.sx, _.sy, _.deg, _.dx, _.dy]; // var to2 = {_:{}, getBBox: function () { return element.getBBox(); }}; // extractTransform(to2, to[attr]); // diff[attr] = [ // (to2._.sx - _.sx) / ms, // (to2._.sy - _.sy) / ms, // (to2._.deg - _.deg) / ms, // (to2._.dx - _.dx) / ms, // (to2._.dy - _.dy) / ms // ]; } break; case "csv": var values = Str(params[attr])[split](separator), from2 = Str(from[attr])[split](separator); if (attr == "clip-rect") { from[attr] = from2; diff[attr] = []; i = from2.length; while (i--) { diff[attr][i] = (values[i] - from[attr][i]) / ms; } } to[attr] = values; break; default: values = [][concat](params[attr]); from2 = [][concat](from[attr]); diff[attr] = []; i = element.paper.customAttributes[attr].length; while (i--) { diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms; } break; } } } var easing = params.easing, easyeasy = R.easing_formulas[easing]; if (!easyeasy) { easyeasy = Str(easing).match(bezierrg); if (easyeasy && easyeasy.length == 5) { var curve = easyeasy; easyeasy = function (t) { return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms); }; } else { easyeasy = pipe; } } timestamp = params.start || anim.start || +new Date; e = { anim: anim, percent: percent, timestamp: timestamp, start: timestamp + (anim.del || 0), status: 0, initstatus: status || 0, stop: false, ms: ms, easing: easyeasy, from: from, diff: diff, to: to, el: element, callback: params.callback, prev: prev, next: next, repeat: times || anim.times, origin: element.attr(), totalOrigin: totalOrigin }; animationElements.push(e); if (status && !isInAnim && !isInAnimSet) { e.stop = true; e.start = new Date - ms * status; if (animationElements.length == 1) { return animation(); } } if (isInAnimSet) { e.start = new Date - e.ms * status; } animationElements.length == 1 && requestAnimFrame(animation); } else { isInAnim.initstatus = status; isInAnim.start = new Date - isInAnim.ms * status; } eve("raphael.anim.start." + element.id, element, anim); } /*\ * Raphael.animation [ method ] ** * Creates an animation object that can be passed to the @Element.animate or @Element.animateWith methods. * See also @Animation.delay and @Animation.repeat methods. ** > Parameters ** - params (object) final attributes for the element, see also @Element.attr - ms (number) number of milliseconds for animation to run - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)` - callback (function) #optional callback function. Will be called at the end of animation. ** = (object) @Animation \*/ R.animation = function (params, ms, easing, callback) { if (params instanceof Animation) { return params; } if (R.is(easing, "function") || !easing) { callback = callback || easing || null; easing = null; } params = Object(params); ms = +ms || 0; var p = {}, json, attr; for (attr in params) if (params[has](attr) && toFloat(attr) != attr && toFloat(attr) + "%" != attr) { json = true; p[attr] = params[attr]; } if (!json) { // if percent-like syntax is used and end-of-all animation callback used if(callback){ // find the last one var lastKey = 0; for(var i in params){ var percent = toInt(i); if(params[has](i) && percent > lastKey){ lastKey = percent; } } lastKey += '%'; // if already defined callback in the last keyframe, skip !params[lastKey].callback && (params[lastKey].callback = callback); } return new Animation(params, ms); } else { easing && (p.easing = easing); callback && (p.callback = callback); return new Animation({100: p}, ms); } }; /*\ * Element.animate [ method ] ** * Creates and starts animation for given element. ** > Parameters ** - params (object) final attributes for the element, see also @Element.attr - ms (number) number of milliseconds for animation to run - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)` - callback (function) #optional callback function. Will be called at the end of animation. * or - animation (object) animation object, see @Raphael.animation ** = (object) original element \*/ elproto.animate = function (params, ms, easing, callback) { var element = this; if (element.removed) { callback && callback.call(element); return element; } var anim = params instanceof Animation ? params : R.animation(params, ms, easing, callback); runAnimation(anim, element, anim.percents[0], null, element.attr()); return element; }; /*\ * Element.setTime [ method ] ** * Sets the status of animation of the element in milliseconds. Similar to @Element.status method. ** > Parameters ** - anim (object) animation object - value (number) number of milliseconds from the beginning of the animation ** = (object) original element if `value` is specified * Note, that during animation following events are triggered: * * On each animation frame event `anim.frame.`, on start `anim.start.` and on end `anim.finish.`. \*/ elproto.setTime = function (anim, value) { if (anim && value != null) { this.status(anim, mmin(value, anim.ms) / anim.ms); } return this; }; /*\ * Element.status [ method ] ** * Gets or sets the status of animation of the element. ** > Parameters ** - anim (object) #optional animation object - value (number) #optional 0 – 1. If specified, method works like a setter and sets the status of a given animation to the value. This will cause animation to jump to the given position. ** = (number) status * or = (array) status if `anim` is not specified. Array of objects in format: o { o anim: (object) animation object o status: (number) status o } * or = (object) original element if `value` is specified \*/ elproto.status = function (anim, value) { var out = [], i = 0, len, e; if (value != null) { runAnimation(anim, this, -1, mmin(value, 1)); return this; } else { len = animationElements.length; for (; i < len; i++) { e = animationElements[i]; if (e.el.id == this.id && (!anim || e.anim == anim)) { if (anim) { return e.status; } out.push({ anim: e.anim, status: e.status }); } } if (anim) { return 0; } return out; } }; /*\ * Element.pause [ method ] ** * Stops animation of the element with ability to resume it later on. ** > Parameters ** - anim (object) #optional animation object ** = (object) original element \*/ elproto.pause = function (anim) { for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) { if (eve("raphael.anim.pause." + this.id, this, animationElements[i].anim) !== false) { animationElements[i].paused = true; } } return this; }; /*\ * Element.resume [ method ] ** * Resumes animation if it was paused with @Element.pause method. ** > Parameters ** - anim (object) #optional animation object ** = (object) original element \*/ elproto.resume = function (anim) { for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) { var e = animationElements[i]; if (eve("raphael.anim.resume." + this.id, this, e.anim) !== false) { delete e.paused; this.status(e.anim, e.status); } } return this; }; /*\ * Element.stop [ method ] ** * Stops animation of the element. ** > Parameters ** - anim (object) #optional animation object ** = (object) original element \*/ elproto.stop = function (anim) { for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) { if (eve("raphael.anim.stop." + this.id, this, animationElements[i].anim) !== false) { animationElements.splice(i--, 1); } } return this; }; function stopAnimation(paper) { for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.paper == paper) { animationElements.splice(i--, 1); } } eve.on("raphael.remove", stopAnimation); eve.on("raphael.clear", stopAnimation); elproto.toString = function () { return "Rapha\xebl\u2019s object"; }; // Set var Set = function (items) { this.items = []; this.length = 0; this.type = "set"; if (items) { for (var i = 0, ii = items.length; i < ii; i++) { if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) { this[this.items.length] = this.items[this.items.length] = items[i]; this.length++; } } } }, setproto = Set.prototype; /*\ * Set.push [ method ] ** * Adds each argument to the current set. = (object) original element \*/ setproto.push = function () { var item, len; for (var i = 0, ii = arguments.length; i < ii; i++) { item = arguments[i]; if (item && (item.constructor == elproto.constructor || item.constructor == Set)) { len = this.items.length; this[len] = this.items[len] = item; this.length++; } } return this; }; /*\ * Set.pop [ method ] ** * Removes last element and returns it. = (object) element \*/ setproto.pop = function () { this.length && delete this[this.length--]; return this.items.pop(); }; /*\ * Set.forEach [ method ] ** * Executes given function for each element in the set. * * If function returns `false` it will stop loop running. ** > Parameters ** - callback (function) function to run - thisArg (object) context object for the callback = (object) Set object \*/ setproto.forEach = function (callback, thisArg) { for (var i = 0, ii = this.items.length; i < ii; i++) { if (callback.call(thisArg, this.items[i], i) === false) { return this; } } return this; }; for (var method in elproto) if (elproto[has](method)) { setproto[method] = (function (methodname) { return function () { var arg = arguments; return this.forEach(function (el) { el[methodname][apply](el, arg); }); }; })(method); } setproto.attr = function (name, value) { if (name && R.is(name, array) && R.is(name[0], "object")) { for (var j = 0, jj = name.length; j < jj; j++) { this.items[j].attr(name[j]); } } else { for (var i = 0, ii = this.items.length; i < ii; i++) { this.items[i].attr(name, value); } } return this; }; /*\ * Set.clear [ method ] ** * Removes all elements from the set \*/ setproto.clear = function () { while (this.length) { this.pop(); } }; /*\ * Set.splice [ method ] ** * Removes given element from the set ** > Parameters ** - index (number) position of the deletion - count (number) number of element to remove - insertion… (object) #optional elements to insert = (object) set elements that were deleted \*/ setproto.splice = function (index, count, insertion) { index = index < 0 ? mmax(this.length + index, 0) : index; count = mmax(0, mmin(this.length - index, count)); var tail = [], todel = [], args = [], i; for (i = 2; i < arguments.length; i++) { args.push(arguments[i]); } for (i = 0; i < count; i++) { todel.push(this[index + i]); } for (; i < this.length - index; i++) { tail.push(this[index + i]); } var arglen = args.length; for (i = 0; i < arglen + tail.length; i++) { this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen]; } i = this.items.length = this.length -= count - arglen; while (this[i]) { delete this[i++]; } return new Set(todel); }; /*\ * Set.exclude [ method ] ** * Removes given element from the set ** > Parameters ** - element (object) element to remove = (boolean) `true` if object was found & removed from the set \*/ setproto.exclude = function (el) { for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) { this.splice(i, 1); return true; } }; setproto.animate = function (params, ms, easing, callback) { (R.is(easing, "function") || !easing) && (callback = easing || null); var len = this.items.length, i = len, item, set = this, collector; if (!len) { return this; } callback && (collector = function () { !--len && callback.call(set); }); easing = R.is(easing, string) ? easing : collector; var anim = R.animation(params, ms, easing, collector); item = this.items[--i].animate(anim); while (i--) { this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim, anim); (this.items[i] && !this.items[i].removed) || len--; } return this; }; setproto.insertAfter = function (el) { var i = this.items.length; while (i--) { this.items[i].insertAfter(el); } return this; }; setproto.getBBox = function () { var x = [], y = [], x2 = [], y2 = []; for (var i = this.items.length; i--;) if (!this.items[i].removed) { var box = this.items[i].getBBox(); x.push(box.x); y.push(box.y); x2.push(box.x + box.width); y2.push(box.y + box.height); } x = mmin[apply](0, x); y = mmin[apply](0, y); x2 = mmax[apply](0, x2); y2 = mmax[apply](0, y2); return { x: x, y: y, x2: x2, y2: y2, width: x2 - x, height: y2 - y }; }; setproto.clone = function (s) { s = this.paper.set(); for (var i = 0, ii = this.items.length; i < ii; i++) { s.push(this.items[i].clone()); } return s; }; setproto.toString = function () { return "Rapha\xebl\u2018s set"; }; setproto.glow = function(glowConfig) { var ret = this.paper.set(); this.forEach(function(shape, index){ var g = shape.glow(glowConfig); if(g != null){ g.forEach(function(shape2, index2){ ret.push(shape2); }); } }); return ret; }; /*\ * Set.isPointInside [ method ] ** * Determine if given point is inside this set’s elements ** > Parameters ** - x (number) x coordinate of the point - y (number) y coordinate of the point = (boolean) `true` if point is inside any of the set's elements \*/ setproto.isPointInside = function (x, y) { var isPointInside = false; this.forEach(function (el) { if (el.isPointInside(x, y)) { isPointInside = true; return false; // stop loop } }); return isPointInside; }; /*\ * Raphael.registerFont [ method ] ** * Adds given font to the registered set of font for Raphaël. Should be used as an internal call from within Cufón’s font file. * Returns original parameter, so it could be used with chaining. # More about Cufón and how to convert your font form TTF, OTF, etc to JavaScript file. ** > Parameters ** - font (object) the font to register = (object) the font you passed in > Usage | Cufon.registerFont(Raphael.registerFont({…})); \*/ R.registerFont = function (font) { if (!font.face) { return font; } this.fonts = this.fonts || {}; var fontcopy = { w: font.w, face: {}, glyphs: {} }, family = font.face["font-family"]; for (var prop in font.face) if (font.face[has](prop)) { fontcopy.face[prop] = font.face[prop]; } if (this.fonts[family]) { this.fonts[family].push(fontcopy); } else { this.fonts[family] = [fontcopy]; } if (!font.svg) { fontcopy.face["units-per-em"] = toInt(font.face["units-per-em"], 10); for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) { var path = font.glyphs[glyph]; fontcopy.glyphs[glyph] = { w: path.w, k: {}, d: path.d && "M" + path.d.replace(/[mlcxtrv]/g, function (command) { return {l: "L", c: "C", x: "z", t: "m", r: "l", v: "c"}[command] || "M"; }) + "z" }; if (path.k) { for (var k in path.k) if (path[has](k)) { fontcopy.glyphs[glyph].k[k] = path.k[k]; } } } } return font; }; /*\ * Paper.getFont [ method ] ** * Finds font object in the registered font by given parameters. You could specify only one word from the font name, like “Myriad” for “Myriad Pro”. ** > Parameters ** - family (string) font family name or any word from it - weight (string) #optional font weight - style (string) #optional font style - stretch (string) #optional font stretch = (object) the font object > Usage | paper.print(100, 100, "Test string", paper.getFont("Times", 800), 30); \*/ paperproto.getFont = function (family, weight, style, stretch) { stretch = stretch || "normal"; style = style || "normal"; weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400; if (!R.fonts) { return; } var font = R.fonts[family]; if (!font) { var name = new RegExp("(^|\\s)" + family.replace(/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i"); for (var fontName in R.fonts) if (R.fonts[has](fontName)) { if (name.test(fontName)) { font = R.fonts[fontName]; break; } } } var thefont; if (font) { for (var i = 0, ii = font.length; i < ii; i++) { thefont = font[i]; if (thefont.face["font-weight"] == weight && (thefont.face["font-style"] == style || !thefont.face["font-style"]) && thefont.face["font-stretch"] == stretch) { break; } } } return thefont; }; /*\ * Paper.print [ method ] ** * Creates path that represent given text written using given font at given position with given size. * Result of the method is path element that contains whole text as a separate path. ** > Parameters ** - x (number) x position of the text - y (number) y position of the text - string (string) text to print - font (object) font object, see @Paper.getFont - size (number) #optional size of the font, default is `16` - origin (string) #optional could be `"baseline"` or `"middle"`, default is `"middle"` - letter_spacing (number) #optional number in range `-1..1`, default is `0` - line_spacing (number) #optional number in range `1..3`, default is `1` = (object) resulting path element, which consist of all letters > Usage | var txt = r.print(10, 50, "print", r.getFont("Museo"), 30).attr({fill: "#fff"}); \*/ paperproto.print = function (x, y, string, font, size, origin, letter_spacing, line_spacing) { origin = origin || "middle"; // baseline|middle letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1); line_spacing = mmax(mmin(line_spacing || 1, 3), 1); var letters = Str(string)[split](E), shift = 0, notfirst = 0, path = E, scale; R.is(font, "string") && (font = this.getFont(font)); if (font) { scale = (size || 16) / font.face["units-per-em"]; var bb = font.face.bbox[split](separator), top = +bb[0], lineHeight = bb[3] - bb[1], shifty = 0, height = +bb[1] + (origin == "baseline" ? lineHeight + (+font.face.descent) : lineHeight / 2); for (var i = 0, ii = letters.length; i < ii; i++) { if (letters[i] == "\n") { shift = 0; curr = 0; notfirst = 0; shifty += lineHeight * line_spacing; } else { var prev = notfirst && font.glyphs[letters[i - 1]] || {}, curr = font.glyphs[letters[i]]; shift += notfirst ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0; notfirst = 1; } if (curr && curr.d) { path += R.transformPath(curr.d, ["t", shift * scale, shifty * scale, "s", scale, scale, top, height, "t", (x - top) / scale, (y - height) / scale]); } } } return this.path(path).attr({ fill: "#000", stroke: "none" }); }; /*\ * Paper.add [ method ] ** * Imports elements in JSON array in format `{type: type, }` ** > Parameters ** - json (array) = (object) resulting set of imported elements > Usage | paper.add([ | { | type: "circle", | cx: 10, | cy: 10, | r: 5 | }, | { | type: "rect", | x: 10, | y: 10, | width: 10, | height: 10, | fill: "#fc0" | } | ]); \*/ paperproto.add = function (json) { if (R.is(json, "array")) { var res = this.set(), i = 0, ii = json.length, j; for (; i < ii; i++) { j = json[i] || {}; elements[has](j.type) && res.push(this[j.type]().attr(j)); } } return res; }; /*\ * Raphael.format [ method ] ** * Simple format function. Replaces construction of type “`{}`” to the corresponding argument. ** > Parameters ** - token (string) string to format - … (string) rest of arguments will be treated as parameters for replacement = (string) formated string > Usage | var x = 10, | y = 20, | width = 40, | height = 50; | // this will draw a rectangular shape equivalent to "M10,20h40v50h-40z" | paper.path(Raphael.format("M{0},{1}h{2}v{3}h{4}z", x, y, width, height, -width)); \*/ R.format = function (token, params) { var args = R.is(params, array) ? [0][concat](params) : arguments; token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) { return args[++i] == null ? E : args[i]; })); return token || E; }; /*\ * Raphael.fullfill [ method ] ** * A little bit more advanced format function than @Raphael.format. Replaces construction of type “`{}`” to the corresponding argument. ** > Parameters ** - token (string) string to format - json (object) object which properties will be used as a replacement = (string) formated string > Usage | // this will draw a rectangular shape equivalent to "M10,20h40v50h-40z" | paper.path(Raphael.fullfill("M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z", { | x: 10, | y: 20, | dim: { | width: 40, | height: 50, | "negative width": -40 | } | })); \*/ R.fullfill = (function () { var tokenRegex = /\{([^\}]+)\}/g, objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties replacer = function (all, key, obj) { var res = obj; key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) { name = name || quotedName; if (res) { if (name in res) { res = res[name]; } typeof res == "function" && isFunc && (res = res()); } }); res = (res == null || res == obj ? all : res) + ""; return res; }; return function (str, obj) { return String(str).replace(tokenRegex, function (all, key) { return replacer(all, key, obj); }); }; })(); /*\ * Raphael.ninja [ method ] ** * If you want to leave no trace of Raphaël (Well, Raphaël creates only one global variable `Raphael`, but anyway.) You can use `ninja` method. * Beware, that in this case plugins could stop working, because they are depending on global variable existence. ** = (object) Raphael object > Usage | (function (local_raphael) { | var paper = local_raphael(10, 10, 320, 200); | … | })(Raphael.ninja()); \*/ R.ninja = function () { oldRaphael.was ? (g.win.Raphael = oldRaphael.is) : delete Raphael; return R; }; /*\ * Raphael.st [ property (object) ] ** * You can add your own method to elements and sets. It is wise to add a set method for each element method * you added, so you will be able to call the same method on sets too. ** * See also @Raphael.el. > Usage | Raphael.el.red = function () { | this.attr({fill: "#f00"}); | }; | Raphael.st.red = function () { | this.forEach(function (el) { | el.red(); | }); | }; | // then use it | paper.set(paper.circle(100, 100, 20), paper.circle(110, 100, 20)).red(); \*/ R.st = setproto; eve.on("raphael.DOMload", function () { loaded = true; }); // Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html (function (doc, loaded, f) { if (doc.readyState == null && doc.addEventListener){ doc.addEventListener(loaded, f = function () { doc.removeEventListener(loaded, f, false); doc.readyState = "complete"; }, false); doc.readyState = "loading"; } function isLoaded() { (/in/).test(doc.readyState) ? setTimeout(isLoaded, 9) : R.eve("raphael.DOMload"); } isLoaded(); })(document, "DOMContentLoaded"); return R; })); // ┌─────────────────────────────────────────────────────────────────────┐ \\ // │ Raphaël 2.1.4 - JavaScript Vector Library │ \\ // ├─────────────────────────────────────────────────────────────────────┤ \\ // │ SVG Module │ \\ // ├─────────────────────────────────────────────────────────────────────┤ \\ // │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ // │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\ // │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\ // └─────────────────────────────────────────────────────────────────────┘ \\ (function (glob, factory) { if (typeof define === "function" && define.amd) { define("raphael.svg", ["raphael.core"], function(raphael) { return factory(raphael); }); } else if (typeof exports === "object") { factory(require("raphael.core")); } else { factory(glob.Raphael); } }(this, function(R) { if (R && !R.svg) { return; } var has = "hasOwnProperty", Str = String, toFloat = parseFloat, toInt = parseInt, math = Math, mmax = math.max, abs = math.abs, pow = math.pow, separator = /[, ]+/, eve = R.eve, E = "", S = " "; var xlink = "http://www.w3.org/1999/xlink", markers = { block: "M5,0 0,2.5 5,5z", classic: "M5,0 0,2.5 5,5 3.5,3 3.5,2z", diamond: "M2.5,0 5,2.5 2.5,5 0,2.5z", open: "M6,1 1,3.5 6,6", oval: "M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z" }, markerCounter = {}; R.toString = function () { return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version; }; var $ = function (el, attr) { if (attr) { if (typeof el == "string") { el = $(el); } for (var key in attr) if (attr[has](key)) { if (key.substring(0, 6) == "xlink:") { el.setAttributeNS(xlink, key.substring(6), Str(attr[key])); } else { el.setAttribute(key, Str(attr[key])); } } } else { el = R._g.doc.createElementNS("http://www.w3.org/2000/svg", el); el.style && (el.style.webkitTapHighlightColor = "rgba(0,0,0,0)"); } return el; }, addGradientFill = function (element, gradient) { var type = "linear", id = element.id + gradient, fx = .5, fy = .5, o = element.node, SVG = element.paper, s = o.style, el = R._g.doc.getElementById(id); if (!el) { gradient = Str(gradient).replace(R._radial_gradient, function (all, _fx, _fy) { type = "radial"; if (_fx && _fy) { fx = toFloat(_fx); fy = toFloat(_fy); var dir = ((fy > .5) * 2 - 1); pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) && fy != .5 && (fy = fy.toFixed(5) - 1e-5 * dir); } return E; }); gradient = gradient.split(/\s*\-\s*/); if (type == "linear") { var angle = gradient.shift(); angle = -toFloat(angle); if (isNaN(angle)) { return null; } var vector = [0, 0, math.cos(R.rad(angle)), math.sin(R.rad(angle))], max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1); vector[2] *= max; vector[3] *= max; if (vector[2] < 0) { vector[0] = -vector[2]; vector[2] = 0; } if (vector[3] < 0) { vector[1] = -vector[3]; vector[3] = 0; } } var dots = R._parseDots(gradient); if (!dots) { return null; } id = id.replace(/[\(\)\s,\xb0#]/g, "_"); if (element.gradient && id != element.gradient.id) { SVG.defs.removeChild(element.gradient); delete element.gradient; } if (!element.gradient) { el = $(type + "Gradient", {id: id}); element.gradient = el; $(el, type == "radial" ? { fx: fx, fy: fy } : { x1: vector[0], y1: vector[1], x2: vector[2], y2: vector[3], gradientTransform: element.matrix.invert() }); SVG.defs.appendChild(el); for (var i = 0, ii = dots.length; i < ii; i++) { el.appendChild($("stop", { offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%", "stop-color": dots[i].color || "#fff", "stop-opacity": isFinite(dots[i].opacity) ? dots[i].opacity : 1 })); } } } $(o, { fill: "url('" + document.location.origin + document.location.pathname + "#" + id + "')", opacity: 1, "fill-opacity": 1 }); s.fill = E; s.opacity = 1; s.fillOpacity = 1; return 1; }, updatePosition = function (o) { var bbox = o.getBBox(1); $(o.pattern, {patternTransform: o.matrix.invert() + " translate(" + bbox.x + "," + bbox.y + ")"}); }, addArrow = function (o, value, isEnd) { if (o.type == "path") { var values = Str(value).toLowerCase().split("-"), p = o.paper, se = isEnd ? "end" : "start", node = o.node, attrs = o.attrs, stroke = attrs["stroke-width"], i = values.length, type = "classic", from, to, dx, refX, attr, w = 3, h = 3, t = 5; while (i--) { switch (values[i]) { case "block": case "classic": case "oval": case "diamond": case "open": case "none": type = values[i]; break; case "wide": h = 5; break; case "narrow": h = 2; break; case "long": w = 5; break; case "short": w = 2; break; } } if (type == "open") { w += 2; h += 2; t += 2; dx = 1; refX = isEnd ? 4 : 1; attr = { fill: "none", stroke: attrs.stroke }; } else { refX = dx = w / 2; attr = { fill: attrs.stroke, stroke: "none" }; } if (o._.arrows) { if (isEnd) { o._.arrows.endPath && markerCounter[o._.arrows.endPath]--; o._.arrows.endMarker && markerCounter[o._.arrows.endMarker]--; } else { o._.arrows.startPath && markerCounter[o._.arrows.startPath]--; o._.arrows.startMarker && markerCounter[o._.arrows.startMarker]--; } } else { o._.arrows = {}; } if (type != "none") { var pathId = "raphael-marker-" + type, markerId = "raphael-marker-" + se + type + w + h + "-obj" + o.id; if (!R._g.doc.getElementById(pathId)) { p.defs.appendChild($($("path"), { "stroke-linecap": "round", d: markers[type], id: pathId })); markerCounter[pathId] = 1; } else { markerCounter[pathId]++; } var marker = R._g.doc.getElementById(markerId), use; if (!marker) { marker = $($("marker"), { id: markerId, markerHeight: h, markerWidth: w, orient: "auto", refX: refX, refY: h / 2 }); use = $($("use"), { "xlink:href": "#" + pathId, transform: (isEnd ? "rotate(180 " + w / 2 + " " + h / 2 + ") " : E) + "scale(" + w / t + "," + h / t + ")", "stroke-width": (1 / ((w / t + h / t) / 2)).toFixed(4) }); marker.appendChild(use); p.defs.appendChild(marker); markerCounter[markerId] = 1; } else { markerCounter[markerId]++; use = marker.getElementsByTagName("use")[0]; } $(use, attr); var delta = dx * (type != "diamond" && type != "oval"); if (isEnd) { from = o._.arrows.startdx * stroke || 0; to = R.getTotalLength(attrs.path) - delta * stroke; } else { from = delta * stroke; to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0); } attr = {}; attr["marker-" + se] = "url(#" + markerId + ")"; if (to || from) { attr.d = R.getSubpath(attrs.path, from, to); } $(node, attr); o._.arrows[se + "Path"] = pathId; o._.arrows[se + "Marker"] = markerId; o._.arrows[se + "dx"] = delta; o._.arrows[se + "Type"] = type; o._.arrows[se + "String"] = value; } else { if (isEnd) { from = o._.arrows.startdx * stroke || 0; to = R.getTotalLength(attrs.path) - from; } else { from = 0; to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0); } o._.arrows[se + "Path"] && $(node, {d: R.getSubpath(attrs.path, from, to)}); delete o._.arrows[se + "Path"]; delete o._.arrows[se + "Marker"]; delete o._.arrows[se + "dx"]; delete o._.arrows[se + "Type"]; delete o._.arrows[se + "String"]; } for (attr in markerCounter) if (markerCounter[has](attr) && !markerCounter[attr]) { var item = R._g.doc.getElementById(attr); item && item.parentNode.removeChild(item); } } }, dasharray = { "-": [3, 1], ".": [1, 1], "-.": [3, 1, 1, 1], "-..": [3, 1, 1, 1, 1, 1], ". ": [1, 3], "- ": [4, 3], "--": [8, 3], "- .": [4, 3, 1, 3], "--.": [8, 3, 1, 3], "--..": [8, 3, 1, 3, 1, 3] }, addDashes = function (o, value, params) { value = dasharray[Str(value).toLowerCase()]; if (value) { var width = o.attrs["stroke-width"] || "1", butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0, dashes = [], i = value.length; while (i--) { dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt; } $(o.node, {"stroke-dasharray": dashes.join(",")}); } else { $(o.node, {"stroke-dasharray": "none"}); } }, setFillAndStroke = function (o, params) { var node = o.node, attrs = o.attrs, vis = node.style.visibility; node.style.visibility = "hidden"; for (var att in params) { if (params[has](att)) { if (!R._availableAttrs[has](att)) { continue; } var value = params[att]; attrs[att] = value; switch (att) { case "blur": o.blur(value); break; case "title": var title = node.getElementsByTagName("title"); // Use the existing . if (title.length && (title = title[0])) { title.firstChild.nodeValue = value; } else { title = $("title"); var val = R._g.doc.createTextNode(value); title.appendChild(val); node.appendChild(title); } break; case "href": case "target": var pn = node.parentNode; if (pn.tagName.toLowerCase() != "a") { var hl = $("a"); pn.insertBefore(hl, node); hl.appendChild(node); pn = hl; } if (att == "target") { pn.setAttributeNS(xlink, "show", value == "blank" ? "new" : value); } else { pn.setAttributeNS(xlink, att, value); } break; case "cursor": node.style.cursor = value; break; case "transform": o.transform(value); break; case "arrow-start": addArrow(o, value); break; case "arrow-end": addArrow(o, value, 1); break; case "clip-rect": var rect = Str(value).split(separator); if (rect.length == 4) { o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode); var el = $("clipPath"), rc = $("rect"); el.id = R.createUUID(); $(rc, { x: rect[0], y: rect[1], width: rect[2], height: rect[3] }); el.appendChild(rc); o.paper.defs.appendChild(el); $(node, {"clip-path": "url(#" + el.id + ")"}); o.clip = rc; } if (!value) { var path = node.getAttribute("clip-path"); if (path) { var clip = R._g.doc.getElementById(path.replace(/(^url\(#|\)$)/g, E)); clip && clip.parentNode.removeChild(clip); $(node, {"clip-path": E}); delete o.clip; } } break; case "path": if (o.type == "path") { $(node, {d: value ? attrs.path = R._pathToAbsolute(value) : "M0,0"}); o._.dirty = 1; if (o._.arrows) { "startString" in o._.arrows && addArrow(o, o._.arrows.startString); "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1); } } break; case "width": node.setAttribute(att, value); o._.dirty = 1; if (attrs.fx) { att = "x"; value = attrs.x; } else { break; } case "x": if (attrs.fx) { value = -attrs.x - (attrs.width || 0); } case "rx": if (att == "rx" && o.type == "rect") { break; } case "cx": node.setAttribute(att, value); o.pattern && updatePosition(o); o._.dirty = 1; break; case "height": node.setAttribute(att, value); o._.dirty = 1; if (attrs.fy) { att = "y"; value = attrs.y; } else { break; } case "y": if (attrs.fy) { value = -attrs.y - (attrs.height || 0); } case "ry": if (att == "ry" && o.type == "rect") { break; } case "cy": node.setAttribute(att, value); o.pattern && updatePosition(o); o._.dirty = 1; break; case "r": if (o.type == "rect") { $(node, {rx: value, ry: value}); } else { node.setAttribute(att, value); } o._.dirty = 1; break; case "src": if (o.type == "image") { node.setAttributeNS(xlink, "href", value); } break; case "stroke-width": if (o._.sx != 1 || o._.sy != 1) { value /= mmax(abs(o._.sx), abs(o._.sy)) || 1; } node.setAttribute(att, value); if (attrs["stroke-dasharray"]) { addDashes(o, attrs["stroke-dasharray"], params); } if (o._.arrows) { "startString" in o._.arrows && addArrow(o, o._.arrows.startString); "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1); } break; case "stroke-dasharray": addDashes(o, value, params); break; case "fill": var isURL = Str(value).match(R._ISURL); if (isURL) { el = $("pattern"); var ig = $("image"); el.id = R.createUUID(); $(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1}); $(ig, {x: 0, y: 0, "xlink:href": isURL[1]}); el.appendChild(ig); (function (el) { R._preload(isURL[1], function () { var w = this.offsetWidth, h = this.offsetHeight; $(el, {width: w, height: h}); $(ig, {width: w, height: h}); }); })(el); o.paper.defs.appendChild(el); $(node, {fill: "url(#" + el.id + ")"}); o.pattern = el; o.pattern && updatePosition(o); break; } var clr = R.getRGB(value); if (!clr.error) { delete params.gradient; delete attrs.gradient; !R.is(attrs.opacity, "undefined") && R.is(params.opacity, "undefined") && $(node, {opacity: attrs.opacity}); !R.is(attrs["fill-opacity"], "undefined") && R.is(params["fill-opacity"], "undefined") && $(node, {"fill-opacity": attrs["fill-opacity"]}); } else if ((o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value)) { if ("opacity" in attrs || "fill-opacity" in attrs) { var gradient = R._g.doc.getElementById(node.getAttribute("fill").replace(/^url\(#|\)$/g, E)); if (gradient) { var stops = gradient.getElementsByTagName("stop"); $(stops[stops.length - 1], {"stop-opacity": ("opacity" in attrs ? attrs.opacity : 1) * ("fill-opacity" in attrs ? attrs["fill-opacity"] : 1)}); } } attrs.gradient = value; attrs.fill = "none"; break; } clr[has]("opacity") && $(node, {"fill-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity}); case "stroke": clr = R.getRGB(value); node.setAttribute(att, clr.hex); att == "stroke" && clr[has]("opacity") && $(node, {"stroke-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity}); if (att == "stroke" && o._.arrows) { "startString" in o._.arrows && addArrow(o, o._.arrows.startString); "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1); } break; case "gradient": (o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value); break; case "opacity": if (attrs.gradient && !attrs[has]("stroke-opacity")) { $(node, {"stroke-opacity": value > 1 ? value / 100 : value}); } // fall case "fill-opacity": if (attrs.gradient) { gradient = R._g.doc.getElementById(node.getAttribute("fill").replace(/^url\(#|\)$/g, E)); if (gradient) { stops = gradient.getElementsByTagName("stop"); $(stops[stops.length - 1], {"stop-opacity": value}); } break; } default: att == "font-size" && (value = toInt(value, 10) + "px"); var cssrule = att.replace(/(\-.)/g, function (w) { return w.substring(1).toUpperCase(); }); node.style[cssrule] = value; o._.dirty = 1; node.setAttribute(att, value); break; } } } tuneText(o, params); node.style.visibility = vis; }, leading = 1.2, tuneText = function (el, params) { if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) { return; } var a = el.attrs, node = el.node, fontSize = node.firstChild ? toInt(R._g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10; if (params[has]("text")) { a.text = params.text; while (node.firstChild) { node.removeChild(node.firstChild); } var texts = Str(params.text).split("\n"), tspans = [], tspan; for (var i = 0, ii = texts.length; i < ii; i++) { tspan = $("tspan"); i && $(tspan, {dy: fontSize * leading, x: a.x}); tspan.appendChild(R._g.doc.createTextNode(texts[i])); node.appendChild(tspan); tspans[i] = tspan; } } else { tspans = node.getElementsByTagName("tspan"); for (i = 0, ii = tspans.length; i < ii; i++) if (i) { $(tspans[i], {dy: fontSize * leading, x: a.x}); } else { $(tspans[0], {dy: 0}); } } $(node, {x: a.x, y: a.y}); el._.dirty = 1; var bb = el._getBBox(), dif = a.y - (bb.y + bb.height / 2); dif && R.is(dif, "finite") && $(tspans[0], {dy: dif}); }, getRealNode = function (node) { if (node.parentNode && node.parentNode.tagName.toLowerCase() === "a") { return node.parentNode; } else { return node; } }, Element = function (node, svg) { var X = 0, Y = 0; /*\ * Element.node [ property (object) ] ** * Gives you a reference to the DOM object, so you can assign event handlers or just mess around. ** * Note: Don’t mess with it. > Usage | // draw a circle at coordinate 10,10 with radius of 10 | var c = paper.circle(10, 10, 10); | c.node.onclick = function () { | c.attr("fill", "red"); | }; \*/ this[0] = this.node = node; /*\ * Element.raphael [ property (object) ] ** * Internal reference to @Raphael object. In case it is not available. > Usage | Raphael.el.red = function () { | var hsb = this.paper.raphael.rgb2hsb(this.attr("fill")); | hsb.h = 1; | this.attr({fill: this.paper.raphael.hsb2rgb(hsb).hex}); | } \*/ node.raphael = true; /*\ * Element.id [ property (number) ] ** * Unique id of the element. Especially useful when you want to listen to events of the element, * because all events are fired in format `<module>.<action>.<id>`. Also useful for @Paper.getById method. \*/ this.id = R._oid++; node.raphaelid = this.id; this.matrix = R.matrix(); this.realPath = null; /*\ * Element.paper [ property (object) ] ** * Internal reference to “paper” where object drawn. Mainly for use in plugins and element extensions. > Usage | Raphael.el.cross = function () { | this.attr({fill: "red"}); | this.paper.path("M10,10L50,50M50,10L10,50") | .attr({stroke: "red"}); | } \*/ this.paper = svg; this.attrs = this.attrs || {}; this._ = { transform: [], sx: 1, sy: 1, deg: 0, dx: 0, dy: 0, dirty: 1 }; !svg.bottom && (svg.bottom = this); /*\ * Element.prev [ property (object) ] ** * Reference to the previous element in the hierarchy. \*/ this.prev = svg.top; svg.top && (svg.top.next = this); svg.top = this; /*\ * Element.next [ property (object) ] ** * Reference to the next element in the hierarchy. \*/ this.next = null; }, elproto = R.el; Element.prototype = elproto; elproto.constructor = Element; R._engine.path = function (pathString, SVG) { var el = $("path"); SVG.canvas && SVG.canvas.appendChild(el); var p = new Element(el, SVG); p.type = "path"; setFillAndStroke(p, { fill: "none", stroke: "#000", path: pathString }); return p; }; /*\ * Element.rotate [ method ] ** * Deprecated! Use @Element.transform instead. * Adds rotation by given angle around given point to the list of * transformations of the element. > Parameters - deg (number) angle in degrees - cx (number) #optional x coordinate of the centre of rotation - cy (number) #optional y coordinate of the centre of rotation * If cx & cy aren’t specified centre of the shape is used as a point of rotation. = (object) @Element \*/ elproto.rotate = function (deg, cx, cy) { if (this.removed) { return this; } deg = Str(deg).split(separator); if (deg.length - 1) { cx = toFloat(deg[1]); cy = toFloat(deg[2]); } deg = toFloat(deg[0]); (cy == null) && (cx = cy); if (cx == null || cy == null) { var bbox = this.getBBox(1); cx = bbox.x + bbox.width / 2; cy = bbox.y + bbox.height / 2; } this.transform(this._.transform.concat([["r", deg, cx, cy]])); return this; }; /*\ * Element.scale [ method ] ** * Deprecated! Use @Element.transform instead. * Adds scale by given amount relative to given point to the list of * transformations of the element. > Parameters - sx (number) horisontal scale amount - sy (number) vertical scale amount - cx (number) #optional x coordinate of the centre of scale - cy (number) #optional y coordinate of the centre of scale * If cx & cy aren’t specified centre of the shape is used instead. = (object) @Element \*/ elproto.scale = function (sx, sy, cx, cy) { if (this.removed) { return this; } sx = Str(sx).split(separator); if (sx.length - 1) { sy = toFloat(sx[1]); cx = toFloat(sx[2]); cy = toFloat(sx[3]); } sx = toFloat(sx[0]); (sy == null) && (sy = sx); (cy == null) && (cx = cy); if (cx == null || cy == null) { var bbox = this.getBBox(1); } cx = cx == null ? bbox.x + bbox.width / 2 : cx; cy = cy == null ? bbox.y + bbox.height / 2 : cy; this.transform(this._.transform.concat([["s", sx, sy, cx, cy]])); return this; }; /*\ * Element.translate [ method ] ** * Deprecated! Use @Element.transform instead. * Adds translation by given amount to the list of transformations of the element. > Parameters - dx (number) horisontal shift - dy (number) vertical shift = (object) @Element \*/ elproto.translate = function (dx, dy) { if (this.removed) { return this; } dx = Str(dx).split(separator); if (dx.length - 1) { dy = toFloat(dx[1]); } dx = toFloat(dx[0]) || 0; dy = +dy || 0; this.transform(this._.transform.concat([["t", dx, dy]])); return this; }; /*\ * Element.transform [ method ] ** * Adds transformation to the element which is separate to other attributes, * i.e. translation doesn’t change `x` or `y` of the rectange. The format * of transformation string is similar to the path string syntax: | "t100,100r30,100,100s2,2,100,100r45s1.5" * Each letter is a command. There are four commands: `t` is for translate, `r` is for rotate, `s` is for * scale and `m` is for matrix. * * There are also alternative “absolute” translation, rotation and scale: `T`, `R` and `S`. They will not take previous transformation into account. For example, `...T100,0` will always move element 100 px horisontally, while `...t100,0` could move it vertically if there is `r90` before. Just compare results of `r90t100,0` and `r90T100,0`. * * So, the example line above could be read like “translate by 100, 100; rotate 30° around 100, 100; scale twice around 100, 100; * rotate 45° around centre; scale 1.5 times relative to centre”. As you can see rotate and scale commands have origin * coordinates as optional parameters, the default is the centre point of the element. * Matrix accepts six parameters. > Usage | var el = paper.rect(10, 20, 300, 200); | // translate 100, 100, rotate 45°, translate -100, 0 | el.transform("t100,100r45t-100,0"); | // if you want you can append or prepend transformations | el.transform("...t50,50"); | el.transform("s2..."); | // or even wrap | el.transform("t50,50...t-50-50"); | // to reset transformation call method with empty string | el.transform(""); | // to get current value call it without parameters | console.log(el.transform()); > Parameters - tstr (string) #optional transformation string * If tstr isn’t specified = (string) current transformation string * else = (object) @Element \*/ elproto.transform = function (tstr) { var _ = this._; if (tstr == null) { return _.transform; } R._extractTransform(this, tstr); this.clip && $(this.clip, {transform: this.matrix.invert()}); this.pattern && updatePosition(this); this.node && $(this.node, {transform: this.matrix}); if (_.sx != 1 || _.sy != 1) { var sw = this.attrs[has]("stroke-width") ? this.attrs["stroke-width"] : 1; this.attr({"stroke-width": sw}); } return this; }; /*\ * Element.hide [ method ] ** * Makes element invisible. See @Element.show. = (object) @Element \*/ elproto.hide = function () { if(!this.removed) this.node.style.display = "none"; return this; }; /*\ * Element.show [ method ] ** * Makes element visible. See @Element.hide. = (object) @Element \*/ elproto.show = function () { if(!this.removed) this.node.style.display = ""; return this; }; /*\ * Element.remove [ method ] ** * Removes element from the paper. \*/ elproto.remove = function () { var node = getRealNode(this.node); if (this.removed || !node.parentNode) { return; } var paper = this.paper; paper.__set__ && paper.__set__.exclude(this); eve.unbind("raphael.*.*." + this.id); if (this.gradient) { paper.defs.removeChild(this.gradient); } R._tear(this, paper); node.parentNode.removeChild(node); // Remove custom data for element this.removeData(); for (var i in this) { this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; } this.removed = true; }; elproto._getBBox = function () { if (this.node.style.display == "none") { this.show(); var hide = true; } var canvasHidden = false, containerStyle; if (this.paper.canvas.parentElement) { containerStyle = this.paper.canvas.parentElement.style; } //IE10+ can't find parentElement else if (this.paper.canvas.parentNode) { containerStyle = this.paper.canvas.parentNode.style; } if(containerStyle && containerStyle.display == "none") { canvasHidden = true; containerStyle.display = ""; } var bbox = {}; try { bbox = this.node.getBBox(); } catch(e) { // Firefox 3.0.x, 25.0.1 (probably more versions affected) play badly here - possible fix bbox = { x: this.node.clientLeft, y: this.node.clientTop, width: this.node.clientWidth, height: this.node.clientHeight } } finally { bbox = bbox || {}; if(canvasHidden){ containerStyle.display = "none"; } } hide && this.hide(); return bbox; }; /*\ * Element.attr [ method ] ** * Sets the attributes of the element. > Parameters - attrName (string) attribute’s name - value (string) value * or - params (object) object of name/value pairs * or - attrName (string) attribute’s name * or - attrNames (array) in this case method returns array of current values for given attribute names = (object) @Element if attrsName & value or params are passed in. = (...) value of the attribute if only attrsName is passed in. = (array) array of values of the attribute if attrsNames is passed in. = (object) object of attributes if nothing is passed in. > Possible parameters # <p>Please refer to the <a href="http://www.w3.org/TR/SVG/" title="The W3C Recommendation for the SVG language describes these properties in detail.">SVG specification</a> for an explanation of these parameters.</p> o arrow-end (string) arrowhead on the end of the path. The format for string is `<type>[-<width>[-<length>]]`. Possible types: `classic`, `block`, `open`, `oval`, `diamond`, `none`, width: `wide`, `narrow`, `medium`, length: `long`, `short`, `midium`. o clip-rect (string) comma or space separated values: x, y, width and height o cursor (string) CSS type of the cursor o cx (number) the x-axis coordinate of the center of the circle, or ellipse o cy (number) the y-axis coordinate of the center of the circle, or ellipse o fill (string) colour, gradient or image o fill-opacity (number) o font (string) o font-family (string) o font-size (number) font size in pixels o font-weight (string) o height (number) o href (string) URL, if specified element behaves as hyperlink o opacity (number) o path (string) SVG path string format o r (number) radius of the circle, ellipse or rounded corner on the rect o rx (number) horisontal radius of the ellipse o ry (number) vertical radius of the ellipse o src (string) image URL, only works for @Element.image element o stroke (string) stroke colour o stroke-dasharray (string) [“”, “none”, “`-`”, “`.`”, “`-.`”, “`-..`”, “`. `”, “`- `”, “`--`”, “`- .`”, “`--.`”, “`--..`”] o stroke-linecap (string) [“`butt`”, “`square`”, “`round`”] o stroke-linejoin (string) [“`bevel`”, “`round`”, “`miter`”] o stroke-miterlimit (number) o stroke-opacity (number) o stroke-width (number) stroke width in pixels, default is '1' o target (string) used with href o text (string) contents of the text element. Use `\n` for multiline text o text-anchor (string) [“`start`”, “`middle`”, “`end`”], default is “`middle`” o title (string) will create tooltip with a given text o transform (string) see @Element.transform o width (number) o x (number) o y (number) > Gradients * Linear gradient format: “`‹angle›-‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`90-#fff-#000`” – 90° * gradient from white to black or “`0-#fff-#f00:20-#000`” – 0° gradient from white via red (at 20%) to black. * * radial gradient: “`r[(‹fx›, ‹fy›)]‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`r#fff-#000`” – * gradient from white to black or “`r(0.25, 0.75)#fff-#000`” – gradient from white to black with focus point * at 0.25, 0.75. Focus point coordinates are in 0..1 range. Radial gradients can only be applied to circles and ellipses. > Path String # <p>Please refer to <a href="http://www.w3.org/TR/SVG/paths.html#PathData" title="Details of a path’s data attribute’s format are described in the SVG specification.">SVG documentation regarding path string</a>. Raphaël fully supports it.</p> > Colour Parsing # <ul> # <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li> # <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li> # <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li> # <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200, 100, 0)</code>”)</li> # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%, 175%, 0%)</code>”)</li> # <li>rgba(•••, •••, •••, •••) — red, green and blue channels’ values: (“<code>rgba(200, 100, 0, .5)</code>”)</li> # <li>rgba(•••%, •••%, •••%, •••%) — same as above, but in %: (“<code>rgba(100%, 175%, 0%, 50%)</code>”)</li> # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5, 0.25, 1)</code>”)</li> # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li> # <li>hsba(•••, •••, •••, •••) — same as above, but with opacity</li> # <li>hsl(•••, •••, •••) — almost the same as hsb, see <a href="http://en.wikipedia.org/wiki/HSL_and_HSV" title="HSL and HSV - Wikipedia, the free encyclopedia">Wikipedia page</a></li> # <li>hsl(•••%, •••%, •••%) — same as above, but in %</li> # <li>hsla(•••, •••, •••, •••) — same as above, but with opacity</li> # <li>Optionally for hsb and hsl you could specify hue as a degree: “<code>hsl(240deg, 1, .5)</code>” or, if you want to go fancy, “<code>hsl(240°, 1, .5)</code>”</li> # </ul> \*/ elproto.attr = function (name, value) { if (this.removed) { return this; } if (name == null) { var res = {}; for (var a in this.attrs) if (this.attrs[has](a)) { res[a] = this.attrs[a]; } res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient; res.transform = this._.transform; return res; } if (value == null && R.is(name, "string")) { if (name == "fill" && this.attrs.fill == "none" && this.attrs.gradient) { return this.attrs.gradient; } if (name == "transform") { return this._.transform; } var names = name.split(separator), out = {}; for (var i = 0, ii = names.length; i < ii; i++) { name = names[i]; if (name in this.attrs) { out[name] = this.attrs[name]; } else if (R.is(this.paper.customAttributes[name], "function")) { out[name] = this.paper.customAttributes[name].def; } else { out[name] = R._availableAttrs[name]; } } return ii - 1 ? out : out[names[0]]; } if (value == null && R.is(name, "array")) { out = {}; for (i = 0, ii = name.length; i < ii; i++) { out[name[i]] = this.attr(name[i]); } return out; } if (value != null) { var params = {}; params[name] = value; } else if (name != null && R.is(name, "object")) { params = name; } for (var key in params) { eve("raphael.attr." + key + "." + this.id, this, params[key]); } for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) { var par = this.paper.customAttributes[key].apply(this, [].concat(params[key])); this.attrs[key] = params[key]; for (var subkey in par) if (par[has](subkey)) { params[subkey] = par[subkey]; } } setFillAndStroke(this, params); return this; }; /*\ * Element.toFront [ method ] ** * Moves the element so it is the closest to the viewer’s eyes, on top of other elements. = (object) @Element \*/ elproto.toFront = function () { if (this.removed) { return this; } var node = getRealNode(this.node); node.parentNode.appendChild(node); var svg = this.paper; svg.top != this && R._tofront(this, svg); return this; }; /*\ * Element.toBack [ method ] ** * Moves the element so it is the furthest from the viewer’s eyes, behind other elements. = (object) @Element \*/ elproto.toBack = function () { if (this.removed) { return this; } var node = getRealNode(this.node); var parentNode = node.parentNode; parentNode.insertBefore(node, parentNode.firstChild); R._toback(this, this.paper); var svg = this.paper; return this; }; /*\ * Element.insertAfter [ method ] ** * Inserts current object after the given one. = (object) @Element \*/ elproto.insertAfter = function (element) { if (this.removed || !element) { return this; } var node = getRealNode(this.node); var afterNode = getRealNode(element.node || element[element.length - 1].node); if (afterNode.nextSibling) { afterNode.parentNode.insertBefore(node, afterNode.nextSibling); } else { afterNode.parentNode.appendChild(node); } R._insertafter(this, element, this.paper); return this; }; /*\ * Element.insertBefore [ method ] ** * Inserts current object before the given one. = (object) @Element \*/ elproto.insertBefore = function (element) { if (this.removed || !element) { return this; } var node = getRealNode(this.node); var beforeNode = getRealNode(element.node || element[0].node); beforeNode.parentNode.insertBefore(node, beforeNode); R._insertbefore(this, element, this.paper); return this; }; elproto.blur = function (size) { // Experimental. No Safari support. Use it on your own risk. var t = this; if (+size !== 0) { var fltr = $("filter"), blur = $("feGaussianBlur"); t.attrs.blur = size; fltr.id = R.createUUID(); $(blur, {stdDeviation: +size || 1.5}); fltr.appendChild(blur); t.paper.defs.appendChild(fltr); t._blur = fltr; $(t.node, {filter: "url(#" + fltr.id + ")"}); } else { if (t._blur) { t._blur.parentNode.removeChild(t._blur); delete t._blur; delete t.attrs.blur; } t.node.removeAttribute("filter"); } return t; }; R._engine.circle = function (svg, x, y, r) { var el = $("circle"); svg.canvas && svg.canvas.appendChild(el); var res = new Element(el, svg); res.attrs = {cx: x, cy: y, r: r, fill: "none", stroke: "#000"}; res.type = "circle"; $(el, res.attrs); return res; }; R._engine.rect = function (svg, x, y, w, h, r) { var el = $("rect"); svg.canvas && svg.canvas.appendChild(el); var res = new Element(el, svg); res.attrs = {x: x, y: y, width: w, height: h, rx: r || 0, ry: r || 0, fill: "none", stroke: "#000"}; res.type = "rect"; $(el, res.attrs); return res; }; R._engine.ellipse = function (svg, x, y, rx, ry) { var el = $("ellipse"); svg.canvas && svg.canvas.appendChild(el); var res = new Element(el, svg); res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: "none", stroke: "#000"}; res.type = "ellipse"; $(el, res.attrs); return res; }; R._engine.image = function (svg, src, x, y, w, h) { var el = $("image"); $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: "none"}); el.setAttributeNS(xlink, "href", src); svg.canvas && svg.canvas.appendChild(el); var res = new Element(el, svg); res.attrs = {x: x, y: y, width: w, height: h, src: src}; res.type = "image"; return res; }; R._engine.text = function (svg, x, y, text) { var el = $("text"); svg.canvas && svg.canvas.appendChild(el); var res = new Element(el, svg); res.attrs = { x: x, y: y, "text-anchor": "middle", text: text, "font-family": R._availableAttrs["font-family"], "font-size": R._availableAttrs["font-size"], stroke: "none", fill: "#000" }; res.type = "text"; setFillAndStroke(res, res.attrs); return res; }; R._engine.setSize = function (width, height) { this.width = width || this.width; this.height = height || this.height; this.canvas.setAttribute("width", this.width); this.canvas.setAttribute("height", this.height); if (this._viewBox) { this.setViewBox.apply(this, this._viewBox); } return this; }; R._engine.create = function () { var con = R._getContainer.apply(0, arguments), container = con && con.container, x = con.x, y = con.y, width = con.width, height = con.height; if (!container) { throw new Error("SVG container not found."); } var cnvs = $("svg"), css = "overflow:hidden;", isFloating; x = x || 0; y = y || 0; width = width || 512; height = height || 342; $(cnvs, { height: height, version: 1.1, width: width, xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink" }); if (container == 1) { cnvs.style.cssText = css + "position:absolute;left:" + x + "px;top:" + y + "px"; R._g.doc.body.appendChild(cnvs); isFloating = 1; } else { cnvs.style.cssText = css + "position:relative"; if (container.firstChild) { container.insertBefore(cnvs, container.firstChild); } else { container.appendChild(cnvs); } } container = new R._Paper; container.width = width; container.height = height; container.canvas = cnvs; container.clear(); container._left = container._top = 0; isFloating && (container.renderfix = function () {}); container.renderfix(); return container; }; R._engine.setViewBox = function (x, y, w, h, fit) { eve("raphael.setViewBox", this, this._viewBox, [x, y, w, h, fit]); var paperSize = this.getSize(), size = mmax(w / paperSize.width, h / paperSize.height), top = this.top, aspectRatio = fit ? "xMidYMid meet" : "xMinYMin", vb, sw; if (x == null) { if (this._vbSize) { size = 1; } delete this._vbSize; vb = "0 0 " + this.width + S + this.height; } else { this._vbSize = size; vb = x + S + y + S + w + S + h; } $(this.canvas, { viewBox: vb, preserveAspectRatio: aspectRatio }); while (size && top) { sw = "stroke-width" in top.attrs ? top.attrs["stroke-width"] : 1; top.attr({"stroke-width": sw}); top._.dirty = 1; top._.dirtyT = 1; top = top.prev; } this._viewBox = [x, y, w, h, !!fit]; return this; }; /*\ * Paper.renderfix [ method ] ** * Fixes the issue of Firefox and IE9 regarding subpixel rendering. If paper is dependant * on other elements after reflow it could shift half pixel which cause for lines to lost their crispness. * This method fixes the issue. ** Special thanks to Mariusz Nowak (http://www.medikoo.com/) for this method. \*/ R.prototype.renderfix = function () { var cnvs = this.canvas, s = cnvs.style, pos; try { pos = cnvs.getScreenCTM() || cnvs.createSVGMatrix(); } catch (e) { pos = cnvs.createSVGMatrix(); } var left = -pos.e % 1, top = -pos.f % 1; if (left || top) { if (left) { this._left = (this._left + left) % 1; s.left = this._left + "px"; } if (top) { this._top = (this._top + top) % 1; s.top = this._top + "px"; } } }; /*\ * Paper.clear [ method ] ** * Clears the paper, i.e. removes all the elements. \*/ R.prototype.clear = function () { R.eve("raphael.clear", this); var c = this.canvas; while (c.firstChild) { c.removeChild(c.firstChild); } this.bottom = this.top = null; (this.desc = $("desc")).appendChild(R._g.doc.createTextNode("Created with Rapha\xebl " + R.version)); c.appendChild(this.desc); c.appendChild(this.defs = $("defs")); }; /*\ * Paper.remove [ method ] ** * Removes the paper from the DOM. \*/ R.prototype.remove = function () { eve("raphael.remove", this); this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas); for (var i in this) { this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; } }; var setproto = R.st; for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) { setproto[method] = (function (methodname) { return function () { var arg = arguments; return this.forEach(function (el) { el[methodname].apply(el, arg); }); }; })(method); } })); // ┌─────────────────────────────────────────────────────────────────────┐ \\ // │ Raphaël 2.1.4 - JavaScript Vector Library │ \\ // ├─────────────────────────────────────────────────────────────────────┤ \\ // │ VML Module │ \\ // ├─────────────────────────────────────────────────────────────────────┤ \\ // │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ // │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\ // │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\ // └─────────────────────────────────────────────────────────────────────┘ \\ (function (glob, factory) { if (typeof define === "function" && define.amd) { define("raphael.vml", ["raphael.core"], function(raphael) { return factory(raphael); }); } else if (typeof exports === "object") { factory(require("raphael")); } else { factory(glob.Raphael); } }(this, function(R) { if (R && !R.vml) { return; } var has = "hasOwnProperty", Str = String, toFloat = parseFloat, math = Math, round = math.round, mmax = math.max, mmin = math.min, abs = math.abs, fillString = "fill", separator = /[, ]+/, eve = R.eve, ms = " progid:DXImageTransform.Microsoft", S = " ", E = "", map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"}, bites = /([clmz]),?([^clmz]*)/gi, blurregexp = / progid:\S+Blur\([^\)]+\)/g, val = /-?[^,\s-]+/g, cssDot = "position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)", zoom = 21600, pathTypes = {path: 1, rect: 1, image: 1}, ovalTypes = {circle: 1, ellipse: 1}, path2vml = function (path) { var total = /[ahqstv]/ig, command = R._pathToAbsolute; Str(path).match(total) && (command = R._path2curve); total = /[clmz]/g; if (command == R._pathToAbsolute && !Str(path).match(total)) { var res = Str(path).replace(bites, function (all, command, args) { var vals = [], isMove = command.toLowerCase() == "m", res = map[command]; args.replace(val, function (value) { if (isMove && vals.length == 2) { res += vals + map[command == "m" ? "l" : "L"]; vals = []; } vals.push(round(value * zoom)); }); return res + vals; }); return res; } var pa = command(path), p, r; res = []; for (var i = 0, ii = pa.length; i < ii; i++) { p = pa[i]; r = pa[i][0].toLowerCase(); r == "z" && (r = "x"); for (var j = 1, jj = p.length; j < jj; j++) { r += round(p[j] * zoom) + (j != jj - 1 ? "," : E); } res.push(r); } return res.join(S); }, compensation = function (deg, dx, dy) { var m = R.matrix(); m.rotate(-deg, .5, .5); return { dx: m.x(dx, dy), dy: m.y(dx, dy) }; }, setCoords = function (p, sx, sy, dx, dy, deg) { var _ = p._, m = p.matrix, fillpos = _.fillpos, o = p.node, s = o.style, y = 1, flip = "", dxdy, kx = zoom / sx, ky = zoom / sy; s.visibility = "hidden"; if (!sx || !sy) { return; } o.coordsize = abs(kx) + S + abs(ky); s.rotation = deg * (sx * sy < 0 ? -1 : 1); if (deg) { var c = compensation(deg, dx, dy); dx = c.dx; dy = c.dy; } sx < 0 && (flip += "x"); sy < 0 && (flip += " y") && (y = -1); s.flip = flip; o.coordorigin = (dx * -kx) + S + (dy * -ky); if (fillpos || _.fillsize) { var fill = o.getElementsByTagName(fillString); fill = fill && fill[0]; o.removeChild(fill); if (fillpos) { c = compensation(deg, m.x(fillpos[0], fillpos[1]), m.y(fillpos[0], fillpos[1])); fill.position = c.dx * y + S + c.dy * y; } if (_.fillsize) { fill.size = _.fillsize[0] * abs(sx) + S + _.fillsize[1] * abs(sy); } o.appendChild(fill); } s.visibility = "visible"; }; R.toString = function () { return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version; }; var addArrow = function (o, value, isEnd) { var values = Str(value).toLowerCase().split("-"), se = isEnd ? "end" : "start", i = values.length, type = "classic", w = "medium", h = "medium"; while (i--) { switch (values[i]) { case "block": case "classic": case "oval": case "diamond": case "open": case "none": type = values[i]; break; case "wide": case "narrow": h = values[i]; break; case "long": case "short": w = values[i]; break; } } var stroke = o.node.getElementsByTagName("stroke")[0]; stroke[se + "arrow"] = type; stroke[se + "arrowlength"] = w; stroke[se + "arrowwidth"] = h; }, setFillAndStroke = function (o, params) { // o.paper.canvas.style.display = "none"; o.attrs = o.attrs || {}; var node = o.node, a = o.attrs, s = node.style, xy, newpath = pathTypes[o.type] && (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.cx != a.cx || params.cy != a.cy || params.rx != a.rx || params.ry != a.ry || params.r != a.r), isOval = ovalTypes[o.type] && (a.cx != params.cx || a.cy != params.cy || a.r != params.r || a.rx != params.rx || a.ry != params.ry), res = o; for (var par in params) if (params[has](par)) { a[par] = params[par]; } if (newpath) { a.path = R._getPath[o.type](o); o._.dirty = 1; } params.href && (node.href = params.href); params.title && (node.title = params.title); params.target && (node.target = params.target); params.cursor && (s.cursor = params.cursor); "blur" in params && o.blur(params.blur); if (params.path && o.type == "path" || newpath) { node.path = path2vml(~Str(a.path).toLowerCase().indexOf("r") ? R._pathToAbsolute(a.path) : a.path); o._.dirty = 1; if (o.type == "image") { o._.fillpos = [a.x, a.y]; o._.fillsize = [a.width, a.height]; setCoords(o, 1, 1, 0, 0, 0); } } "transform" in params && o.transform(params.transform); if (isOval) { var cx = +a.cx, cy = +a.cy, rx = +a.rx || +a.r || 0, ry = +a.ry || +a.r || 0; node.path = R.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x", round((cx - rx) * zoom), round((cy - ry) * zoom), round((cx + rx) * zoom), round((cy + ry) * zoom), round(cx * zoom)); o._.dirty = 1; } if ("clip-rect" in params) { var rect = Str(params["clip-rect"]).split(separator); if (rect.length == 4) { rect[2] = +rect[2] + (+rect[0]); rect[3] = +rect[3] + (+rect[1]); var div = node.clipRect || R._g.doc.createElement("div"), dstyle = div.style; dstyle.clip = R.format("rect({1}px {2}px {3}px {0}px)", rect); if (!node.clipRect) { dstyle.position = "absolute"; dstyle.top = 0; dstyle.left = 0; dstyle.width = o.paper.width + "px"; dstyle.height = o.paper.height + "px"; node.parentNode.insertBefore(div, node); div.appendChild(node); node.clipRect = div; } } if (!params["clip-rect"]) { node.clipRect && (node.clipRect.style.clip = "auto"); } } if (o.textpath) { var textpathStyle = o.textpath.style; params.font && (textpathStyle.font = params.font); params["font-family"] && (textpathStyle.fontFamily = '"' + params["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g, E) + '"'); params["font-size"] && (textpathStyle.fontSize = params["font-size"]); params["font-weight"] && (textpathStyle.fontWeight = params["font-weight"]); params["font-style"] && (textpathStyle.fontStyle = params["font-style"]); } if ("arrow-start" in params) { addArrow(res, params["arrow-start"]); } if ("arrow-end" in params) { addArrow(res, params["arrow-end"], 1); } if (params.opacity != null || params["stroke-width"] != null || params.fill != null || params.src != null || params.stroke != null || params["stroke-width"] != null || params["stroke-opacity"] != null || params["fill-opacity"] != null || params["stroke-dasharray"] != null || params["stroke-miterlimit"] != null || params["stroke-linejoin"] != null || params["stroke-linecap"] != null) { var fill = node.getElementsByTagName(fillString), newfill = false; fill = fill && fill[0]; !fill && (newfill = fill = createNode(fillString)); if (o.type == "image" && params.src) { fill.src = params.src; } params.fill && (fill.on = true); if (fill.on == null || params.fill == "none" || params.fill === null) { fill.on = false; } if (fill.on && params.fill) { var isURL = Str(params.fill).match(R._ISURL); if (isURL) { fill.parentNode == node && node.removeChild(fill); fill.rotate = true; fill.src = isURL[1]; fill.type = "tile"; var bbox = o.getBBox(1); fill.position = bbox.x + S + bbox.y; o._.fillpos = [bbox.x, bbox.y]; R._preload(isURL[1], function () { o._.fillsize = [this.offsetWidth, this.offsetHeight]; }); } else { fill.color = R.getRGB(params.fill).hex; fill.src = E; fill.type = "solid"; if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != "r") && addGradientFill(res, params.fill, fill)) { a.fill = "none"; a.gradient = params.fill; fill.rotate = false; } } } if ("fill-opacity" in params || "opacity" in params) { var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1); opacity = mmin(mmax(opacity, 0), 1); fill.opacity = opacity; if (fill.src) { fill.color = "none"; } } node.appendChild(fill); var stroke = (node.getElementsByTagName("stroke") && node.getElementsByTagName("stroke")[0]), newstroke = false; !stroke && (newstroke = stroke = createNode("stroke")); if ((params.stroke && params.stroke != "none") || params["stroke-width"] || params["stroke-opacity"] != null || params["stroke-dasharray"] || params["stroke-miterlimit"] || params["stroke-linejoin"] || params["stroke-linecap"]) { stroke.on = true; } (params.stroke == "none" || params.stroke === null || stroke.on == null || params.stroke == 0 || params["stroke-width"] == 0) && (stroke.on = false); var strokeColor = R.getRGB(params.stroke); stroke.on && params.stroke && (stroke.color = strokeColor.hex); opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1); var width = (toFloat(params["stroke-width"]) || 1) * .75; opacity = mmin(mmax(opacity, 0), 1); params["stroke-width"] == null && (width = a["stroke-width"]); params["stroke-width"] && (stroke.weight = width); width && width < 1 && (opacity *= width) && (stroke.weight = 1); stroke.opacity = opacity; params["stroke-linejoin"] && (stroke.joinstyle = params["stroke-linejoin"] || "miter"); stroke.miterlimit = params["stroke-miterlimit"] || 8; params["stroke-linecap"] && (stroke.endcap = params["stroke-linecap"] == "butt" ? "flat" : params["stroke-linecap"] == "square" ? "square" : "round"); if ("stroke-dasharray" in params) { var dasharray = { "-": "shortdash", ".": "shortdot", "-.": "shortdashdot", "-..": "shortdashdotdot", ". ": "dot", "- ": "dash", "--": "longdash", "- .": "dashdot", "--.": "longdashdot", "--..": "longdashdotdot" }; stroke.dashstyle = dasharray[has](params["stroke-dasharray"]) ? dasharray[params["stroke-dasharray"]] : E; } newstroke && node.appendChild(stroke); } if (res.type == "text") { res.paper.canvas.style.display = E; var span = res.paper.span, m = 100, fontSize = a.font && a.font.match(/\d+(?:\.\d*)?(?=px)/); s = span.style; a.font && (s.font = a.font); a["font-family"] && (s.fontFamily = a["font-family"]); a["font-weight"] && (s.fontWeight = a["font-weight"]); a["font-style"] && (s.fontStyle = a["font-style"]); fontSize = toFloat(a["font-size"] || fontSize && fontSize[0]) || 10; s.fontSize = fontSize * m + "px"; res.textpath.string && (span.innerHTML = Str(res.textpath.string).replace(/</g, "<").replace(/&/g, "&").replace(/\n/g, "<br>")); var brect = span.getBoundingClientRect(); res.W = a.w = (brect.right - brect.left) / m; res.H = a.h = (brect.bottom - brect.top) / m; // res.paper.canvas.style.display = "none"; res.X = a.x; res.Y = a.y + res.H / 2; ("x" in params || "y" in params) && (res.path.v = R.format("m{0},{1}l{2},{1}", round(a.x * zoom), round(a.y * zoom), round(a.x * zoom) + 1)); var dirtyattrs = ["x", "y", "text", "font", "font-family", "font-weight", "font-style", "font-size"]; for (var d = 0, dd = dirtyattrs.length; d < dd; d++) if (dirtyattrs[d] in params) { res._.dirty = 1; break; } // text-anchor emulation switch (a["text-anchor"]) { case "start": res.textpath.style["v-text-align"] = "left"; res.bbx = res.W / 2; break; case "end": res.textpath.style["v-text-align"] = "right"; res.bbx = -res.W / 2; break; default: res.textpath.style["v-text-align"] = "center"; res.bbx = 0; break; } res.textpath.style["v-text-kern"] = true; } // res.paper.canvas.style.display = E; }, addGradientFill = function (o, gradient, fill) { o.attrs = o.attrs || {}; var attrs = o.attrs, pow = Math.pow, opacity, oindex, type = "linear", fxfy = ".5 .5"; o.attrs.gradient = gradient; gradient = Str(gradient).replace(R._radial_gradient, function (all, fx, fy) { type = "radial"; if (fx && fy) { fx = toFloat(fx); fy = toFloat(fy); pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5); fxfy = fx + S + fy; } return E; }); gradient = gradient.split(/\s*\-\s*/); if (type == "linear") { var angle = gradient.shift(); angle = -toFloat(angle); if (isNaN(angle)) { return null; } } var dots = R._parseDots(gradient); if (!dots) { return null; } o = o.shape || o.node; if (dots.length) { o.removeChild(fill); fill.on = true; fill.method = "none"; fill.color = dots[0].color; fill.color2 = dots[dots.length - 1].color; var clrs = []; for (var i = 0, ii = dots.length; i < ii; i++) { dots[i].offset && clrs.push(dots[i].offset + S + dots[i].color); } fill.colors = clrs.length ? clrs.join() : "0% " + fill.color; if (type == "radial") { fill.type = "gradientTitle"; fill.focus = "100%"; fill.focussize = "0 0"; fill.focusposition = fxfy; fill.angle = 0; } else { // fill.rotate= true; fill.type = "gradient"; fill.angle = (270 - angle) % 360; } o.appendChild(fill); } return 1; }, Element = function (node, vml) { this[0] = this.node = node; node.raphael = true; this.id = R._oid++; node.raphaelid = this.id; this.X = 0; this.Y = 0; this.attrs = {}; this.paper = vml; this.matrix = R.matrix(); this._ = { transform: [], sx: 1, sy: 1, dx: 0, dy: 0, deg: 0, dirty: 1, dirtyT: 1 }; !vml.bottom && (vml.bottom = this); this.prev = vml.top; vml.top && (vml.top.next = this); vml.top = this; this.next = null; }; var elproto = R.el; Element.prototype = elproto; elproto.constructor = Element; elproto.transform = function (tstr) { if (tstr == null) { return this._.transform; } var vbs = this.paper._viewBoxShift, vbt = vbs ? "s" + [vbs.scale, vbs.scale] + "-1-1t" + [vbs.dx, vbs.dy] : E, oldt; if (vbs) { oldt = tstr = Str(tstr).replace(/\.{3}|\u2026/g, this._.transform || E); } R._extractTransform(this, vbt + tstr); var matrix = this.matrix.clone(), skew = this.skew, o = this.node, split, isGrad = ~Str(this.attrs.fill).indexOf("-"), isPatt = !Str(this.attrs.fill).indexOf("url("); matrix.translate(1, 1); if (isPatt || isGrad || this.type == "image") { skew.matrix = "1 0 0 1"; skew.offset = "0 0"; split = matrix.split(); if ((isGrad && split.noRotation) || !split.isSimple) { o.style.filter = matrix.toFilter(); var bb = this.getBBox(), bbt = this.getBBox(1), dx = bb.x - bbt.x, dy = bb.y - bbt.y; o.coordorigin = (dx * -zoom) + S + (dy * -zoom); setCoords(this, 1, 1, dx, dy, 0); } else { o.style.filter = E; setCoords(this, split.scalex, split.scaley, split.dx, split.dy, split.rotate); } } else { o.style.filter = E; skew.matrix = Str(matrix); skew.offset = matrix.offset(); } if (oldt !== null) { // empty string value is true as well this._.transform = oldt; R._extractTransform(this, oldt); } return this; }; elproto.rotate = function (deg, cx, cy) { if (this.removed) { return this; } if (deg == null) { return; } deg = Str(deg).split(separator); if (deg.length - 1) { cx = toFloat(deg[1]); cy = toFloat(deg[2]); } deg = toFloat(deg[0]); (cy == null) && (cx = cy); if (cx == null || cy == null) { var bbox = this.getBBox(1); cx = bbox.x + bbox.width / 2; cy = bbox.y + bbox.height / 2; } this._.dirtyT = 1; this.transform(this._.transform.concat([["r", deg, cx, cy]])); return this; }; elproto.translate = function (dx, dy) { if (this.removed) { return this; } dx = Str(dx).split(separator); if (dx.length - 1) { dy = toFloat(dx[1]); } dx = toFloat(dx[0]) || 0; dy = +dy || 0; if (this._.bbox) { this._.bbox.x += dx; this._.bbox.y += dy; } this.transform(this._.transform.concat([["t", dx, dy]])); return this; }; elproto.scale = function (sx, sy, cx, cy) { if (this.removed) { return this; } sx = Str(sx).split(separator); if (sx.length - 1) { sy = toFloat(sx[1]); cx = toFloat(sx[2]); cy = toFloat(sx[3]); isNaN(cx) && (cx = null); isNaN(cy) && (cy = null); } sx = toFloat(sx[0]); (sy == null) && (sy = sx); (cy == null) && (cx = cy); if (cx == null || cy == null) { var bbox = this.getBBox(1); } cx = cx == null ? bbox.x + bbox.width / 2 : cx; cy = cy == null ? bbox.y + bbox.height / 2 : cy; this.transform(this._.transform.concat([["s", sx, sy, cx, cy]])); this._.dirtyT = 1; return this; }; elproto.hide = function () { !this.removed && (this.node.style.display = "none"); return this; }; elproto.show = function () { !this.removed && (this.node.style.display = E); return this; }; // Needed to fix the vml setViewBox issues elproto.auxGetBBox = R.el.getBBox; elproto.getBBox = function(){ var b = this.auxGetBBox(); if (this.paper && this.paper._viewBoxShift) { var c = {}; var z = 1/this.paper._viewBoxShift.scale; c.x = b.x - this.paper._viewBoxShift.dx; c.x *= z; c.y = b.y - this.paper._viewBoxShift.dy; c.y *= z; c.width = b.width * z; c.height = b.height * z; c.x2 = c.x + c.width; c.y2 = c.y + c.height; return c; } return b; }; elproto._getBBox = function () { if (this.removed) { return {}; } return { x: this.X + (this.bbx || 0) - this.W / 2, y: this.Y - this.H, width: this.W, height: this.H }; }; elproto.remove = function () { if (this.removed || !this.node.parentNode) { return; } this.paper.__set__ && this.paper.__set__.exclude(this); R.eve.unbind("raphael.*.*." + this.id); R._tear(this, this.paper); this.node.parentNode.removeChild(this.node); this.shape && this.shape.parentNode.removeChild(this.shape); for (var i in this) { this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; } this.removed = true; }; elproto.attr = function (name, value) { if (this.removed) { return this; } if (name == null) { var res = {}; for (var a in this.attrs) if (this.attrs[has](a)) { res[a] = this.attrs[a]; } res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient; res.transform = this._.transform; return res; } if (value == null && R.is(name, "string")) { if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) { return this.attrs.gradient; } var names = name.split(separator), out = {}; for (var i = 0, ii = names.length; i < ii; i++) { name = names[i]; if (name in this.attrs) { out[name] = this.attrs[name]; } else if (R.is(this.paper.customAttributes[name], "function")) { out[name] = this.paper.customAttributes[name].def; } else { out[name] = R._availableAttrs[name]; } } return ii - 1 ? out : out[names[0]]; } if (this.attrs && value == null && R.is(name, "array")) { out = {}; for (i = 0, ii = name.length; i < ii; i++) { out[name[i]] = this.attr(name[i]); } return out; } var params; if (value != null) { params = {}; params[name] = value; } value == null && R.is(name, "object") && (params = name); for (var key in params) { eve("raphael.attr." + key + "." + this.id, this, params[key]); } if (params) { for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) { var par = this.paper.customAttributes[key].apply(this, [].concat(params[key])); this.attrs[key] = params[key]; for (var subkey in par) if (par[has](subkey)) { params[subkey] = par[subkey]; } } // this.paper.canvas.style.display = "none"; if (params.text && this.type == "text") { this.textpath.string = params.text; } setFillAndStroke(this, params); // this.paper.canvas.style.display = E; } return this; }; elproto.toFront = function () { !this.removed && this.node.parentNode.appendChild(this.node); this.paper && this.paper.top != this && R._tofront(this, this.paper); return this; }; elproto.toBack = function () { if (this.removed) { return this; } if (this.node.parentNode.firstChild != this.node) { this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild); R._toback(this, this.paper); } return this; }; elproto.insertAfter = function (element) { if (this.removed) { return this; } if (element.constructor == R.st.constructor) { element = element[element.length - 1]; } if (element.node.nextSibling) { element.node.parentNode.insertBefore(this.node, element.node.nextSibling); } else { element.node.parentNode.appendChild(this.node); } R._insertafter(this, element, this.paper); return this; }; elproto.insertBefore = function (element) { if (this.removed) { return this; } if (element.constructor == R.st.constructor) { element = element[0]; } element.node.parentNode.insertBefore(this.node, element.node); R._insertbefore(this, element, this.paper); return this; }; elproto.blur = function (size) { var s = this.node.runtimeStyle, f = s.filter; f = f.replace(blurregexp, E); if (+size !== 0) { this.attrs.blur = size; s.filter = f + S + ms + ".Blur(pixelradius=" + (+size || 1.5) + ")"; s.margin = R.format("-{0}px 0 0 -{0}px", round(+size || 1.5)); } else { s.filter = f; s.margin = 0; delete this.attrs.blur; } return this; }; R._engine.path = function (pathString, vml) { var el = createNode("shape"); el.style.cssText = cssDot; el.coordsize = zoom + S + zoom; el.coordorigin = vml.coordorigin; var p = new Element(el, vml), attr = {fill: "none", stroke: "#000"}; pathString && (attr.path = pathString); p.type = "path"; p.path = []; p.Path = E; setFillAndStroke(p, attr); vml.canvas.appendChild(el); var skew = createNode("skew"); skew.on = true; el.appendChild(skew); p.skew = skew; p.transform(E); return p; }; R._engine.rect = function (vml, x, y, w, h, r) { var path = R._rectPath(x, y, w, h, r), res = vml.path(path), a = res.attrs; res.X = a.x = x; res.Y = a.y = y; res.W = a.width = w; res.H = a.height = h; a.r = r; a.path = path; res.type = "rect"; return res; }; R._engine.ellipse = function (vml, x, y, rx, ry) { var res = vml.path(), a = res.attrs; res.X = x - rx; res.Y = y - ry; res.W = rx * 2; res.H = ry * 2; res.type = "ellipse"; setFillAndStroke(res, { cx: x, cy: y, rx: rx, ry: ry }); return res; }; R._engine.circle = function (vml, x, y, r) { var res = vml.path(), a = res.attrs; res.X = x - r; res.Y = y - r; res.W = res.H = r * 2; res.type = "circle"; setFillAndStroke(res, { cx: x, cy: y, r: r }); return res; }; R._engine.image = function (vml, src, x, y, w, h) { var path = R._rectPath(x, y, w, h), res = vml.path(path).attr({stroke: "none"}), a = res.attrs, node = res.node, fill = node.getElementsByTagName(fillString)[0]; a.src = src; res.X = a.x = x; res.Y = a.y = y; res.W = a.width = w; res.H = a.height = h; a.path = path; res.type = "image"; fill.parentNode == node && node.removeChild(fill); fill.rotate = true; fill.src = src; fill.type = "tile"; res._.fillpos = [x, y]; res._.fillsize = [w, h]; node.appendChild(fill); setCoords(res, 1, 1, 0, 0, 0); return res; }; R._engine.text = function (vml, x, y, text) { var el = createNode("shape"), path = createNode("path"), o = createNode("textpath"); x = x || 0; y = y || 0; text = text || ""; path.v = R.format("m{0},{1}l{2},{1}", round(x * zoom), round(y * zoom), round(x * zoom) + 1); path.textpathok = true; o.string = Str(text); o.on = true; el.style.cssText = cssDot; el.coordsize = zoom + S + zoom; el.coordorigin = "0 0"; var p = new Element(el, vml), attr = { fill: "#000", stroke: "none", font: R._availableAttrs.font, text: text }; p.shape = el; p.path = path; p.textpath = o; p.type = "text"; p.attrs.text = Str(text); p.attrs.x = x; p.attrs.y = y; p.attrs.w = 1; p.attrs.h = 1; setFillAndStroke(p, attr); el.appendChild(o); el.appendChild(path); vml.canvas.appendChild(el); var skew = createNode("skew"); skew.on = true; el.appendChild(skew); p.skew = skew; p.transform(E); return p; }; R._engine.setSize = function (width, height) { var cs = this.canvas.style; this.width = width; this.height = height; width == +width && (width += "px"); height == +height && (height += "px"); cs.width = width; cs.height = height; cs.clip = "rect(0 " + width + " " + height + " 0)"; if (this._viewBox) { R._engine.setViewBox.apply(this, this._viewBox); } return this; }; R._engine.setViewBox = function (x, y, w, h, fit) { R.eve("raphael.setViewBox", this, this._viewBox, [x, y, w, h, fit]); var paperSize = this.getSize(), width = paperSize.width, height = paperSize.height, H, W; if (fit) { H = height / h; W = width / w; if (w * H < width) { x -= (width - w * H) / 2 / H; } if (h * W < height) { y -= (height - h * W) / 2 / W; } } this._viewBox = [x, y, w, h, !!fit]; this._viewBoxShift = { dx: -x, dy: -y, scale: paperSize }; this.forEach(function (el) { el.transform("..."); }); return this; }; var createNode; R._engine.initWin = function (win) { var doc = win.document; if (doc.styleSheets.length < 31) { doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)"); } else { // no more room, add to the existing one // http://msdn.microsoft.com/en-us/library/ms531194%28VS.85%29.aspx doc.styleSheets[0].addRule(".rvml", "behavior:url(#default#VML)"); } try { !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"); createNode = function (tagName) { return doc.createElement('<rvml:' + tagName + ' class="rvml">'); }; } catch (e) { createNode = function (tagName) { return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">'); }; } }; R._engine.initWin(R._g.win); R._engine.create = function () { var con = R._getContainer.apply(0, arguments), container = con.container, height = con.height, s, width = con.width, x = con.x, y = con.y; if (!container) { throw new Error("VML container not found."); } var res = new R._Paper, c = res.canvas = R._g.doc.createElement("div"), cs = c.style; x = x || 0; y = y || 0; width = width || 512; height = height || 342; res.width = width; res.height = height; width == +width && (width += "px"); height == +height && (height += "px"); res.coordsize = zoom * 1e3 + S + zoom * 1e3; res.coordorigin = "0 0"; res.span = R._g.doc.createElement("span"); res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;"; c.appendChild(res.span); cs.cssText = R.format("top:0;left:0;display:inline-block;position:absolute;clip:rect(0 {0} {1} 0);", width, height); if (container == 1) { R._g.doc.body.appendChild(c); cs.left = x + "px"; cs.top = y + "px"; cs.position = "absolute"; } else { if (container.firstChild) { container.insertBefore(c, container.firstChild); } else { container.appendChild(c); } } res.renderfix = function () {}; return res; }; R.prototype.clear = function () { R.eve("raphael.clear", this); this.canvas.innerHTML = E; this.span = R._g.doc.createElement("span"); this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;"; this.canvas.appendChild(this.span); this.bottom = this.top = null; }; R.prototype.remove = function () { R.eve("raphael.remove", this); this.canvas.parentNode.removeChild(this.canvas); for (var i in this) { this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; } return true; }; var setproto = R.st; for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) { setproto[method] = (function (methodname) { return function () { var arg = arguments; return this.forEach(function (el) { el[methodname].apply(el, arg); }); }; })(method); } })); // ┌────────────────────────────────────────────────────────────────────┐ \\ // │ Raphaël 2.1.4 - JavaScript Vector Library │ \\ // ├────────────────────────────────────────────────────────────────────┤ \\ // │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ // │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\ // ├────────────────────────────────────────────────────────────────────┤ \\ // │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\ // └────────────────────────────────────────────────────────────────────┘ \\ (function (glob, factory) { if (typeof define === "function" && define.amd) { define("raphael", ["raphael.core", "raphael.svg", "raphael.vml"], function(Raphael) { return factory(Raphael); }); } else if (typeof exports === "object") { var raphael = require("raphael.core"); require("raphael.svg"); require("raphael.vml"); module.exports = factory(raphael); } else { //glob.Raphael = factory(glob.Raphael); } }(this, function (Raphael) { return Raphael.ninja(); }));/** * svg绘图 * * Created by GUY on 2015/12/3. * @class BI.Svg * @extends BI.Widget */ BI.Svg = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.Svg.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-svg" }); }, _init: function () { BI.Svg.superclass._init.apply(this, arguments); this.paper = Raphael(this.element[0]); this.element.css("overflow", "hidden"); $(this.paper.canvas).width("100%").height("100%").css({left: "0", top: "0"}).appendTo(this.element); this.top = this.paper.top; this.bottom = this.paper.bottom; this.customAttributes = this.paper.customAttributes; this.ca = this.paper.ca; this.raphael = this.paper.raphael; }, add: function () { return this.paper.add.apply(this.paper, arguments); }, path: function () { return this.paper.path.apply(this.paper, arguments); }, image: function () { return this.paper.image.apply(this.paper, arguments); }, rect: function () { return this.paper.rect.apply(this.paper, arguments); }, circle: function () { return this.paper.circle.apply(this.paper, arguments); }, ellipse: function () { return this.paper.ellipse.apply(this.paper, arguments); }, text: function () { return this.paper.text.apply(this.paper, arguments); }, print: function () { return this.paper.print.apply(this.paper, arguments); }, setStart: function () { return this.paper.setStart.apply(this.paper, arguments); }, setFinish: function () { return this.paper.setFinish.apply(this.paper, arguments); }, setSize: function () { return this.paper.setSize.apply(this.paper, arguments); }, setViewBox: function () { return this.paper.setViewBox.apply(this.paper, arguments); }, getById: function () { return this.paper.getById.apply(this.paper, arguments); }, getElementByPoint: function () { return this.paper.getElementByPoint.apply(this.paper, arguments); }, getElementsByPoint: function () { return this.paper.getElementsByPoint.apply(this.paper, arguments); }, getFont: function () { return this.paper.getFont.apply(this.paper, arguments); }, set: function () { return this.paper.set.apply(this.paper, arguments); }, remove: function () { return this.paper.remove.apply(this.paper, arguments); }, clear: function () { return this.paper.clear.apply(this.paper, arguments); } }); BI.shortcut("bi.svg", BI.Svg);/** * * 原生表格滚动条,为了IE8的兼容 * * Created by GUY on 2016/1/12. * @class BI.NativeTableScrollbar * @extends BI.Widget */ BI.NativeTableScrollbar = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.NativeTableScrollbar.superclass._defaultConfig.apply(this, arguments), { attributes: { tabIndex: 0 }, contentSize: 0, defaultPosition: 0, position: 0, size: 0 }); }, render: function () { var self = this, o = this.options; // 把滚动台size改掉 this.element.width(36); var throttle = BI.throttle(function () { self.fireEvent(BI.NativeTableScrollbar.EVENT_SCROLL, self.element.scrollTop()); }, 150, {leading: false}); this.element.scroll(function () { throttle(); }); return { type: "bi.default", scrolly: true, items: [{ type: "bi.layout", width: 1, ref: function (_ref) { self.inner = _ref; } }] }; }, mounted: function () { this._populate(); }, _populate: function () { var self = this, o = this.options; if (o.size < 1 || o.contentSize <= o.size) { this.setVisible(false); return; } this.setVisible(true); try { this.element.scrollTop(o.position); } catch (e) { } this.inner.element.height(o.contentSize); }, setContentSize: function (contentSize) { this.options.contentSize = contentSize; }, setPosition: function (position) { this.options.position = position; }, setSize: function (size) { this.setHeight(size); this.options.size = size; }, populate: function () { this._populate(); } }); BI.NativeTableScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; BI.shortcut("bi.native_table_scrollbar", BI.NativeTableScrollbar); BI.NativeTableHorizontalScrollbar = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.NativeTableHorizontalScrollbar.superclass._defaultConfig.apply(this, arguments), { attributes: { tabIndex: 0 }, contentSize: 0, position: 0, size: 0 }); }, render: function () { var self = this, o = this.options; // 把滚动台size改掉 this.element.height(36); var throttle = BI.throttle(function () { self.fireEvent(BI.NativeTableScrollbar.EVENT_SCROLL, self.element.scrollLeft()); }, 150, {leading: false}); this.element.scroll(function () { throttle(); }); return { type: "bi.default", scrollx: true, items: [{ type: "bi.layout", height: 1, ref: function (_ref) { self.inner = _ref; } }] }; }, setContentSize: function (contentSize) { this.options.contentSize = contentSize; }, setPosition: function (position) { this.options.position = position; }, setSize: function (size) { this.setWidth(size); this.options.size = size; }, _populate: function () { var self = this, o = this.options; if (o.size < 1 || o.contentSize <= o.size) { this.setVisible(false); return; } this.setVisible(true); try { this.element.scrollLeft(o.position); } catch (e) { } this.inner.element.width(o.contentSize); }, populate: function () { this._populate(); } }); BI.NativeTableHorizontalScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; BI.shortcut("bi.native_table_horizontal_scrollbar", BI.NativeTableHorizontalScrollbar);/** * * 表格 * * Created by GUY on 2015/9/22. * @class BI.TableCell * @extends BI.Single */ BI.TableCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.TableCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-table-cell", textAlign: "left", text: "" }); }, _init: function () { BI.TableCell.superclass._init.apply(this, arguments); BI.createWidget({ type: "bi.label", element: this, whiteSpace: "nowrap", textAlign: this.options.textAlign, height: this.options.height, text: this.options.text, value: this.options.value, lgap: 5 }); } }); BI.shortcut("bi.table_cell", BI.TableCell);/** * * 表格单元格 * * Created by GUY on 2016/1/12. * @class BI.CollectionTableCell * @extends BI.Widget */ BI.CollectionTableCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionTableCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection-table-cell bi-border-right bi-border-bottom", width: 0, height: 0, _left: 0, _top: 0, cell: {} }); }, _init: function () { BI.CollectionTableCell.superclass._init.apply(this, arguments); var o = this.options; this.cell = BI.createWidget(BI.extend({ type: "bi.label" }, o.cell, { cls: (o.cell.cls || "") + " collection-table-cell-wrapper", width: o.width - (o._left === 0 ? 1 : 0) - 1, height: o.height - (o._top === 0 ? 1 : 0) - 1 })); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.cell, left: 0, right: 0, top: 0, bottom: 0 }] }); }, setWidth: function (width) { BI.CollectionTableCell.superclass.setWidth.apply(this, arguments); var o = this.options; this.cell.setWidth(o.width - (o._left === 0 ? 1 : 0) - 1); }, setHeight: function (height) { BI.CollectionTableCell.superclass.setHeight.apply(this, arguments); var o = this.options; this.cell.setHeight(o.height - (o._top === 0 ? 1 : 0) - 1); } }); BI.shortcut("bi.collection_table_cell", BI.CollectionTableCell);/** * CollectionTable * * Created by GUY on 2016/1/12. * @class BI.CollectionTable * @extends BI.Widget */ BI.CollectionTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection-table", headerRowSize: 25, rowSize: 25, columnSize: [], isNeedFreeze: false, freezeCols: [], isNeedMerge: false, mergeCols: [], mergeRule: BI.emptyFn, header: [], items: [], regionColumnSize: [] }); }, render: function () { var self = this, o = this.options; this._width = 0; this._height = 0; this._scrollBarSize = BI.DOM.getScrollWidth(); this.topLeftCollection = BI.createWidget({ type: "bi.collection_view", cellSizeAndPositionGetter: function (index) { return self.topLeftItems[index]; } }); this.topLeftCollection.on(BI.CollectionView.EVENT_SCROLL, function (scroll) { self.bottomLeftCollection.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.topRightCollection = BI.createWidget({ type: "bi.collection_view", cellSizeAndPositionGetter: function (index) { return self.topRightItems[index]; } }); this.topRightCollection.on(BI.CollectionView.EVENT_SCROLL, function (scroll) { self.bottomRightCollection.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.bottomLeftCollection = BI.createWidget({ type: "bi.collection_view", cellSizeAndPositionGetter: function (index) { return self.bottomLeftItems[index]; } }); this.bottomLeftCollection.on(BI.CollectionView.EVENT_SCROLL, function (scroll) { self.bottomRightCollection.setScrollTop(scroll.scrollTop); self.topLeftCollection.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.bottomRightCollection = BI.createWidget({ type: "bi.collection_view", cellSizeAndPositionGetter: function (index) { return self.bottomRightItems[index]; } }); this.bottomRightCollection.on(BI.CollectionView.EVENT_SCROLL, function (scroll) { self.bottomLeftCollection.setScrollTop(scroll.scrollTop); self.topRightCollection.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.topLeft = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.topLeftCollection] }); this.topRight = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.topRightCollection] }); this.bottomLeft = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.bottomLeftCollection] }); this.bottomRight = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.bottomRightCollection] }); this.contextLayout = BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.topLeft, top: 0, left: 0 }, { el: this.topRight, top: 0 }, { el: this.bottomLeft, left: 0 }, { el: this.bottomRight }] }); this.topScrollbar = BI.createWidget({ type: "bi.grid_table_scrollbar", width: BI.GridTableScrollbar.SIZE }); this.topScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollTop) { self.bottomLeftCollection.setScrollTop(scrollTop); self.bottomRightCollection.setScrollTop(scrollTop); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.leftScrollbar = BI.createWidget({ type: "bi.grid_table_horizontal_scrollbar", height: BI.GridTableScrollbar.SIZE }); this.leftScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollLeft) { self.topLeftCollection.setScrollLeft(scrollLeft); self.bottomLeftCollection.setScrollLeft(scrollLeft); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.rightScrollbar = BI.createWidget({ type: "bi.grid_table_horizontal_scrollbar", height: BI.GridTableScrollbar.SIZE }); this.rightScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollLeft) { self.topRightCollection.setScrollLeft(scrollLeft); self.bottomRightCollection.setScrollLeft(scrollLeft); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.scrollBarLayout = BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.topScrollbar, right: 0, top: 0 }, { el: this.leftScrollbar, left: 0 }, { el: this.rightScrollbar }] }); this._width = o.width - BI.GridTableScrollbar.SIZE; this._height = o.height - BI.GridTableScrollbar.SIZE; }, mounted: function () { var o = this.options; if (o.items.length > 0 || o.header.length > 0) { this._digest(); this._populate(); } }, _getFreezeColLength: function () { var o = this.options; return o.isNeedFreeze === true ? BI.clamp(o.freezeCols.length, 0, o.columnSize.length) : 0; }, _getFreezeHeaderHeight: function () { var o = this.options; if (o.header.length * o.headerRowSize >= this._height) { return 0; } return o.header.length * o.headerRowSize; }, _getActualItems: function () { var o = this.options; if (o.header.length * o.headerRowSize >= this._height) { return o.header.concat(o.items); } return o.items; }, _populateScrollbar: function () { var o = this.options; var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = []; BI.each(o.columnSize, function (i, size) { if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { totalLeftColumnSize += size; } else { totalRightColumnSize += size; } totalColumnSize += size; if (i === 0) { summaryColumnSizeArray[i] = size; } else { summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; } }); this.topScrollbar.setContentSize(this._getActualItems().length * o.rowSize); this.topScrollbar.setSize(this._height - this._getFreezeHeaderHeight()); this.topScrollbar.setPosition(this.bottomRightCollection.getScrollTop()); this.topScrollbar.populate(); this.leftScrollbar.setContentSize(totalLeftColumnSize); this.leftScrollbar.setSize(regionSize); this.leftScrollbar.setPosition(this.bottomLeftCollection.getScrollLeft()); this.leftScrollbar.populate(); this.rightScrollbar.setContentSize(totalRightColumnSize); this.rightScrollbar.setSize(this._width - regionSize); this.rightScrollbar.setPosition(this.bottomRightCollection.getScrollLeft()); this.rightScrollbar.populate(); var items = this.scrollBarLayout.attr("items"); items[0].top = this._getFreezeHeaderHeight(); items[1].top = this._height; items[2].top = this._height; items[2].left = regionSize; this.scrollBarLayout.attr("items", items); this.scrollBarLayout.resize(); }, _populateTable: function () { var self = this, o = this.options; var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = []; BI.each(o.columnSize, function (i, size) { if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { totalLeftColumnSize += size; } else { totalRightColumnSize += size; } totalColumnSize += size; if (i === 0) { summaryColumnSizeArray[i] = size; } else { summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; } }); var otlw = regionSize; var otlh = this._getFreezeHeaderHeight(); var otrw = this._width - regionSize; var otrh = this._getFreezeHeaderHeight(); var oblw = regionSize; var oblh = this._height - otlh; var obrw = this._width - regionSize; var obrh = this._height - otrh; var tlw = otlw + this._scrollBarSize; var tlh = otlh + this._scrollBarSize; var trw = otrw + this._scrollBarSize; var trh = otrh + this._scrollBarSize; var blw = oblw + this._scrollBarSize; var blh = oblh + this._scrollBarSize; var brw = obrw + this._scrollBarSize; var brh = obrh + this._scrollBarSize; var digest = function (el) { el.element.css({ overflow: "scroll", overflowX: "scroll", overflowY: "scroll" }); }; this.topLeft.setWidth(otlw); this.topLeft.setHeight(otlh); this.topRight.setWidth(otrw); this.topRight.setHeight(otrh); this.bottomLeft.setWidth(oblw); this.bottomLeft.setHeight(oblh); this.bottomRight.setWidth(obrw); this.bottomRight.setHeight(obrh); this.topLeftCollection.setWidth(tlw); this.topLeftCollection.setHeight(tlh); this.topRightCollection.setWidth(trw); this.topRightCollection.setHeight(trh); this.bottomLeftCollection.setWidth(blw); this.bottomLeftCollection.setHeight(blh); this.bottomRightCollection.setWidth(brw); this.bottomRightCollection.setHeight(brh); digest(this.topLeftCollection); digest(this.topRightCollection); digest(this.bottomLeftCollection); digest(this.bottomRightCollection); var items = this.contextLayout.attr("items"); items[1].left = regionSize; items[2].top = this._getFreezeHeaderHeight(); items[3].left = regionSize; items[3].top = this._getFreezeHeaderHeight(); this.contextLayout.attr("items", items); this.contextLayout.resize(); var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; var run = function (positions, items, rendered) { BI.each(positions, function (i, item) { var cell = { type: "bi.collection_table_cell", cell: items[item.row][item.col] }; rendered.push(cell); }); }; run(this.topLeftItems, o.header, leftHeader); run(this.topRightItems, o.header, rightHeader); run(this.bottomLeftItems, this._getActualItems(), leftItems); run(this.bottomRightItems, this._getActualItems(), rightItems); this.topLeftCollection._populate(leftHeader); this.topRightCollection._populate(rightHeader); this.bottomLeftCollection._populate(leftItems); this.bottomRightCollection._populate(rightItems); }, _digest: function () { var o = this.options; var freezeColLength = this._getFreezeColLength(); // 如果表头位置不够,取消表头冻结 if (this._getFreezeHeaderHeight() <= 0) { this.topLeftItems = []; this.topRightItems = []; this.bottomLeftItems = this._serialize(this._getActualItems(), 0, freezeColLength, o.rowSize, o.columnSize, o.mergeCols, BI.range(o.header.length)); this.bottomRightItems = this._serialize(this._getActualItems(), freezeColLength, o.columnSize.length, o.rowSize, o.columnSize, o.mergeCols, BI.range(o.header.length)); } else { this.topLeftItems = this._serialize(o.header, 0, freezeColLength, o.headerRowSize, o.columnSize, o.mergeCols); this.topRightItems = this._serialize(o.header, freezeColLength, o.columnSize.length, o.headerRowSize, o.columnSize, true); this.bottomLeftItems = this._serialize(o.items, 0, freezeColLength, o.rowSize, o.columnSize, o.mergeCols); this.bottomRightItems = this._serialize(o.items, freezeColLength, o.columnSize.length, o.rowSize, o.columnSize, o.mergeCols); } }, _serialize: function (items, startCol, endCol, rowHeight, columnSize, mergeCols, mergeRows) { mergeCols = mergeCols || []; mergeRows = mergeRows || []; var self = this, o = this.options; var result = [], cache = {}, preCol = {}, preRow = {}, map = {}; var summaryColumnSize = []; for (var i = startCol; i < endCol; i++) { if (i === startCol) { summaryColumnSize[i] = columnSize[i]; } else { summaryColumnSize[i] = summaryColumnSize[i - 1] + columnSize[i]; } } var mergeRow = function (i, j) { preCol[j]._height += rowHeight; preCol[j].__mergeRows.push(i); }; var mergeCol = function (i, j) { preRow[i]._width += columnSize[j]; preRow[i].__mergeCols.push(j); }; var createOneEl = function (r, c) { var width = columnSize[c]; var height = rowHeight; map[r][c]._row = r; map[r][c]._col = c; map[r][c]._width = width; map[r][c]._height = height; preCol[c] = map[r][c]; preCol[c].__mergeRows = [r]; preRow[r] = map[r][c]; preRow[r].__mergeCols = [c]; result.push({ x: summaryColumnSize[c] - columnSize[c], y: +r * rowHeight, item: map[r][c] }); }; BI.each(items, function (i, cols) { for (var j = startCol; j < endCol; j++) { if (!cache[i]) { cache[i] = {}; } if (!map[i]) { map[i] = {}; } cache[i][j] = cols[j]; map[i][j] = {}; if (mergeCols === true || mergeCols.indexOf(j) > -1 || mergeRows === true || mergeRows.indexOf(i) > -1) { if (i === 0 && j === startCol) { createOneEl(0, startCol); } else if (j === startCol && i > 0) { var isNeedMergeRow = o.mergeRule(cache[i][j], cache[i - 1][j]); if (isNeedMergeRow === true) { mergeRow(i, j); preRow[i] = preCol[j]; } else { createOneEl(i, j); } } else if (i === 0 && j > startCol) { var isNeedMergeCol = o.mergeRule(cache[i][j], cache[i][j - 1]); if (isNeedMergeCol === true) { mergeCol(i, j); preCol[j] = preRow[i]; } else { createOneEl(i, j); } } else { var isNeedMergeRow = o.mergeRule(cache[i][j], cache[i - 1][j]); var isNeedMergeCol = o.mergeRule(cache[i][j], cache[i][j - 1]); if (isNeedMergeCol && isNeedMergeRow) { continue; // mergeRow(i, j);//优先合并列 } if (isNeedMergeCol) { mergeCol(i, j); } if (isNeedMergeRow) { mergeRow(i, j); } if (!isNeedMergeCol && !isNeedMergeRow) { createOneEl(i, j); } } } else { createOneEl(i, j); } } }); return BI.map(result, function (i, item) { return { x: item.x, y: item.y, row: item.item._row, col: item.item._col, width: item.item._width, height: item.item._height }; }); }, _populate: function () { if (this._width <= 0 || this._height <= 0) { return; } if (this._isNeedDigest === true) { this._digest(); } this._isNeedDigest = false; this._populateTable(); this._populateScrollbar(); }, getRegionSize: function () { var o = this.options; var regionSize = o.regionColumnSize[0] || 0; if (o.isNeedFreeze === false || o.freezeCols.length === 0) { return 0; } if (!regionSize) { BI.each(o.freezeCols, function (i, col) { regionSize += o.columnSize[col]; }); } return regionSize; }, setVerticalScroll: function (scrollTop) { this.bottomLeftCollection.setScrollTop(scrollTop); this.bottomRightCollection.setScrollTop(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.topLeftCollection.setScrollLeft(scrollLeft); this.bottomLeftCollection.setScrollLeft(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.topRightCollection.setScrollLeft(scrollLeft); this.bottomRightCollection.setScrollLeft(scrollLeft); }, getVerticalScroll: function () { return this.bottomRightCollection.getScrollTop(); }, getLeftHorizontalScroll: function () { return this.bottomLeftCollection.getScrollLeft(); }, getRightHorizontalScroll: function () { return this.bottomRightCollection.getScrollLeft(); }, setWidth: function (width) { BI.CollectionTable.superclass.setWidth.apply(this, arguments); this._width = this.options.width - BI.GridTableScrollbar.SIZE; }, setHeight: function (height) { BI.CollectionTable.superclass.setHeight.apply(this, arguments); this._height = this.options.height - BI.GridTableScrollbar.SIZE; }, setColumnSize: function (columnSize) { this._isNeedDigest = true; this.options.columnSize = columnSize; }, setRegionColumnSize: function (regionColumnSize) { this._isNeedDigest = true; this.options.regionColumnSize = regionColumnSize; }, getColumnSize: function () { return this.options.columnSize; }, getRegionColumnSize: function () { return this.options.regionColumnSize; }, populate: function (items, header) { if (items && items !== this.options.items) { this._isNeedDigest = true; this.options.items = items; this._restore(); } if (header && header !== this.options.header) { this._isNeedDigest = true; this.options.header = header; this._restore(); } this._populate(); }, _restore: function () { this.topLeftCollection.restore(); this.topRightCollection.restore(); this.bottomLeftCollection.restore(); this.bottomRightCollection.restore(); }, restore: function () { this._restore(); } }); BI.shortcut("bi.collection_table", BI.CollectionTable);/** * QuickCollectionTable * * Created by GUY on 2016/1/12. * @class BI.QuickCollectionTable * @extends BI.CollectionTable */ BI.QuickCollectionTable = BI.inherit(BI.CollectionTable, { _defaultConfig: function () { return BI.extend(BI.QuickCollectionTable.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-quick-collection-table" }); }, render: function () { BI.QuickCollectionTable.superclass.render.apply(this, arguments); var self = this, o = this.options; this.topLeftCollection.setOverflowX(false); this.topLeftCollection.setOverflowY(false); this.topRightCollection.setOverflowX(false); this.topRightCollection.setOverflowY(false); this.bottomLeftCollection.setOverflowX(false); this.bottomLeftCollection.setOverflowY(false); this.bottomRightCollection.setOverflowX(false); this.bottomRightCollection.setOverflowY(false); }, mounted: function () { BI.QuickCollectionTable.superclass.mounted.apply(this, arguments); var self = this; this._topLeftWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelLeft, this), BI.bind(this._shouldHandleLeftX, this), BI.bind(this._shouldHandleY, this) ); this._topRightWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelRight, this), BI.bind(this._shouldHandleRightX, this), BI.bind(this._shouldHandleY, this) ); this._bottomLeftWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelLeft, this), BI.bind(this._shouldHandleLeftX, this), BI.bind(this._shouldHandleY, this) ); this._bottomRightWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelRight, this), BI.bind(this._shouldHandleRightX, this), BI.bind(this._shouldHandleY, this) ); this.topLeftCollection.element.mousewheel(function (e) { self._topLeftWheelHandler.onWheel(e.originalEvent); }); this.topRightCollection.element.mousewheel(function (e) { self._topRightWheelHandler.onWheel(e.originalEvent); }); this.bottomLeftCollection.element.mousewheel(function (e) { self._bottomLeftWheelHandler.onWheel(e.originalEvent); }); this.bottomRightCollection.element.mousewheel(function (e) { self._bottomRightWheelHandler.onWheel(e.originalEvent); }); }, _shouldHandleLeftX: function (delta) { if (delta > 0) { return this.bottomLeftCollection.getScrollLeft() < this.bottomLeftCollection.getMaxScrollLeft(); } return this.bottomLeftCollection.getScrollLeft() > 0; }, _shouldHandleRightX: function (delta) { if (delta > 0) { return this.bottomRightCollection.getScrollLeft() < this.bottomRightCollection.getMaxScrollLeft(); } return this.bottomRightCollection.getScrollLeft() > 0; }, _shouldHandleY: function (delta) { if (delta > 0) { return this.bottomRightCollection.getScrollTop() < this.bottomRightCollection.getMaxScrollTop(); } return this.bottomRightCollection.getScrollTop() > 0; }, _onWheelLeft: function (deltaX, deltaY) { var self = this; var scrollTop = this.bottomLeftCollection.getScrollTop(); var scrollLeft = this.bottomLeftCollection.getScrollLeft(); scrollTop += deltaY; scrollLeft += deltaX; this.bottomLeftCollection.setScrollTop(scrollTop); this.bottomRightCollection.setScrollTop(scrollTop); this.topLeftCollection.setScrollLeft(scrollLeft); this.bottomLeftCollection.setScrollLeft(scrollLeft); self._populateScrollbar(); this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }, _onWheelRight: function (deltaX, deltaY) { var self = this; var scrollTop = this.bottomRightCollection.getScrollTop(); var scrollLeft = this.bottomRightCollection.getScrollLeft(); scrollTop += deltaY; scrollLeft += deltaX; this.bottomLeftCollection.setScrollTop(scrollTop); this.bottomRightCollection.setScrollTop(scrollTop); this.topRightCollection.setScrollLeft(scrollLeft); this.bottomRightCollection.setScrollLeft(scrollLeft); self._populateScrollbar(); this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }, _populateTable: function () { var self = this, o = this.options; var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = []; BI.each(o.columnSize, function (i, size) { if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { totalLeftColumnSize += size; } else { totalRightColumnSize += size; } totalColumnSize += size; if (i === 0) { summaryColumnSizeArray[i] = size; } else { summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; } }); var otlw = regionSize; var otlh = this._getFreezeHeaderHeight(); var otrw = this._width - regionSize; var otrh = this._getFreezeHeaderHeight(); var oblw = regionSize; var oblh = this._height - otlh; var obrw = this._width - regionSize; var obrh = this._height - otrh; this.topLeft.setWidth(otlw); this.topLeft.setHeight(otlh); this.topRight.setWidth(otrw); this.topRight.setHeight(otrh); this.bottomLeft.setWidth(oblw); this.bottomLeft.setHeight(oblh); this.bottomRight.setWidth(obrw); this.bottomRight.setHeight(obrh); this.topLeftCollection.setWidth(otlw); this.topLeftCollection.setHeight(otlh); this.topRightCollection.setWidth(otrw); this.topRightCollection.setHeight(otrh); this.bottomLeftCollection.setWidth(oblw); this.bottomLeftCollection.setHeight(oblh); this.bottomRightCollection.setWidth(obrw); this.bottomRightCollection.setHeight(obrh); var items = this.contextLayout.attr("items"); items[1].left = regionSize; items[2].top = this._getFreezeHeaderHeight(); items[3].left = regionSize; items[3].top = this._getFreezeHeaderHeight(); this.contextLayout.attr("items", items); this.contextLayout.resize(); var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; var run = function (positions, items, rendered) { BI.each(positions, function (i, item) { var cell = { type: "bi.collection_table_cell", cell: items[item.row][item.col] }; rendered.push(cell); }); }; run(this.topLeftItems, o.header, leftHeader); run(this.topRightItems, o.header, rightHeader); run(this.bottomLeftItems, this._getActualItems(), leftItems); run(this.bottomRightItems, this._getActualItems(), rightItems); this.topLeftCollection.populate(leftHeader); this.topRightCollection.populate(rightHeader); this.bottomLeftCollection.populate(leftItems); this.bottomRightCollection.populate(rightItems); } }); BI.shortcut("bi.quick_collection_table", BI.QuickCollectionTable);/** * * 表格单元格 * * Created by GUY on 2016/1/12. * @class BI.GridTableCell * @extends BI.Widget */ BI.GridTableCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridTableCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-table-cell bi-border-right bi-border-bottom", width: 0, height: 0, _rowIndex: 0, _columnIndex: 0, _left: 0, _top: 0, cell: {} }); }, _init: function () { BI.GridTableCell.superclass._init.apply(this, arguments); var o = this.options; this.cell = BI.createWidget(BI.extend({ type: "bi.label" }, o.cell, { cls: (o.cell.cls || "") + "grid-table-cell-wrapper", width: o.width - (o._columnIndex === 0 ? 1 : 0) - 1, height: o.height - (o._rowIndex === 0 ? 1 : 0) - 1 })); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.cell, left: 0, right: 0, top: 0, bottom: 0 }] }); }, setWidth: function (width) { BI.GridTableCell.superclass.setWidth.apply(this, arguments); var o = this.options; this.cell.setWidth(o.width - (o._columnIndex === 0 ? 1 : 0) - 1); }, setHeight: function (height) { BI.GridTableCell.superclass.setHeight.apply(this, arguments); var o = this.options; this.cell.setHeight(o.height - (o._rowIndex === 0 ? 1 : 0) - 1); } }); BI.shortcut("bi.grid_table_cell", BI.GridTableCell);/** * GridTable * * Created by GUY on 2016/1/12. * @class BI.GridTable * @extends BI.Widget */ BI.GridTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-table", headerRowSize: 25, rowSize: 25, columnSize: [], isNeedFreeze: false, freezeCols: [], header: [], items: [], regionColumnSize: [] }); }, render: function () { var self = this, o = this.options; this._width = 0; this._height = 0; this._scrollBarSize = BI.DOM.getScrollWidth(); var rowHeightGetter = function () { return o.rowSize; }; var columnLeftWidthGetter = function (index) { return o.columnSize[index]; }; var columnRightWidthGetter = function (index) { return o.columnSize[index + self._getFreezeColLength()]; }; this.topLeftGrid = BI.createWidget({ type: "bi.grid_view", rowHeightGetter: rowHeightGetter, columnWidthGetter: columnLeftWidthGetter }); this.topLeftGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) { self.bottomLeftGrid.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.topRightGrid = BI.createWidget({ type: "bi.grid_view", rowHeightGetter: rowHeightGetter, columnWidthGetter: columnRightWidthGetter }); this.topRightGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) { self.bottomRightGrid.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.bottomLeftGrid = BI.createWidget({ type: "bi.grid_view", rowHeightGetter: rowHeightGetter, columnWidthGetter: columnLeftWidthGetter }); this.bottomLeftGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) { self.bottomRightGrid.setScrollTop(scroll.scrollTop); self.topLeftGrid.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.bottomRightGrid = BI.createWidget({ type: "bi.grid_view", rowHeightGetter: rowHeightGetter, columnWidthGetter: columnRightWidthGetter }); this.bottomRightGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) { self.bottomLeftGrid.setScrollTop(scroll.scrollTop); self.topRightGrid.setScrollLeft(scroll.scrollLeft); self._populateScrollbar(); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.topLeft = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.topLeftGrid] }); this.topRight = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.topRightGrid] }); this.bottomLeft = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.bottomLeftGrid] }); this.bottomRight = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.bottomRightGrid] }); this.contextLayout = BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.topLeft, top: 0, left: 0 }, { el: this.topRight, top: 0 }, { el: this.bottomLeft, left: 0 }, { el: this.bottomRight }] }); this.topScrollbar = BI.createWidget({ type: "bi.grid_table_scrollbar", width: BI.GridTableScrollbar.SIZE }); this.topScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollTop) { self.bottomLeftGrid.setScrollTop(scrollTop); self.bottomRightGrid.setScrollTop(scrollTop); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.leftScrollbar = BI.createWidget({ type: "bi.grid_table_horizontal_scrollbar", height: BI.GridTableScrollbar.SIZE }); this.leftScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) { self.topLeftGrid.setScrollLeft(scrollLeft); self.bottomLeftGrid.setScrollLeft(scrollLeft); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.rightScrollbar = BI.createWidget({ type: "bi.grid_table_horizontal_scrollbar", height: BI.GridTableScrollbar.SIZE }); this.rightScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) { self.topRightGrid.setScrollLeft(scrollLeft); self.bottomRightGrid.setScrollLeft(scrollLeft); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.scrollBarLayout = BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.topScrollbar, right: 0, top: 0 }, { el: this.leftScrollbar, left: 0 }, { el: this.rightScrollbar }] }); this._width = o.width - BI.GridTableScrollbar.SIZE; this._height = o.height - BI.GridTableScrollbar.SIZE; this.header = this._getHeader(); this.items = this._getItems(); }, mounted: function () { var o = this.options; if (o.items.length > 0 || o.header.length > 0) { this._populate(); } }, _getFreezeColLength: function () { var o = this.options; return o.isNeedFreeze === true ? BI.clamp(o.freezeCols.length, 0, o.columnSize.length) : 0; }, _getFreezeHeaderHeight: function () { var o = this.options; if (o.header.length * o.headerRowSize >= this._height) { return 0; } return o.header.length * o.headerRowSize; }, _getActualItems: function () { var o = this.options; if (o.header.length * o.headerRowSize >= this._height) { return o.header.concat(o.items); } return o.items; }, _populateScrollbar: function () { var o = this.options; var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = []; BI.each(o.columnSize, function (i, size) { if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { totalLeftColumnSize += size; } else { totalRightColumnSize += size; } totalColumnSize += size; if (i === 0) { summaryColumnSizeArray[i] = size; } else { summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; } }); this.topScrollbar.setContentSize(this._getActualItems().length * o.rowSize); this.topScrollbar.setSize(this._height - this._getFreezeHeaderHeight()); this.topScrollbar.setPosition(Math.min(this.bottomLeftGrid.getScrollTop(), this.bottomRightGrid.getScrollTop())); this.topScrollbar.populate(); this.leftScrollbar.setContentSize(totalLeftColumnSize); this.leftScrollbar.setSize(regionSize); this.leftScrollbar.setPosition(this.bottomLeftGrid.getScrollLeft()); this.leftScrollbar.populate(); this.rightScrollbar.setContentSize(totalRightColumnSize); this.rightScrollbar.setSize(this._width - regionSize); this.rightScrollbar.setPosition(this.bottomRightGrid.getScrollLeft()); this.rightScrollbar.populate(); var items = this.scrollBarLayout.attr("items"); items[0].top = this._getFreezeHeaderHeight(); items[1].top = this._height; items[2].top = this._height; items[2].left = regionSize; this.scrollBarLayout.attr("items", items); this.scrollBarLayout.resize(); }, _getHeader: function () { var o = this.options; var freezeColLength = this._getFreezeColLength(); var leftHeader = [], rightHeader = []; BI.each(o.header, function (i, cols) { leftHeader[i] = []; rightHeader[i] = []; BI.each(cols, function (j, col) { var cell = { type: "bi.grid_table_cell", cell: col }; if (j < freezeColLength) { leftHeader[i].push(cell); } else { rightHeader[i].push(cell); } }); }); return [leftHeader, rightHeader]; }, _getItems: function () { var o = this.options; var freezeColLength = this._getFreezeColLength(); var leftItems = [], rightItems = []; BI.each(this._getActualItems(), function (i, cols) { leftItems[i] = []; rightItems[i] = []; BI.each(cols, function (j, col) { var cell = { type: "bi.grid_table_cell", cell: col }; if (j < freezeColLength) { leftItems[i].push(cell); } else { rightItems[i].push(cell); } }); }); return [leftItems, rightItems]; }, _populateTable: function () { var self = this, o = this.options; var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = []; var freezeColLength = this._getFreezeColLength(); BI.each(o.columnSize, function (i, size) { if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { totalLeftColumnSize += size; } else { totalRightColumnSize += size; } totalColumnSize += size; if (i === 0) { summaryColumnSizeArray[i] = size; } else { summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; } }); var otlw = regionSize; var otlh = this._getFreezeHeaderHeight(); var otrw = this._width - regionSize; var otrh = this._getFreezeHeaderHeight(); var oblw = regionSize; var oblh = this._height - otlh; var obrw = this._width - regionSize; var obrh = this._height - otrh; var tlw = otlw + this._scrollBarSize; var tlh = otlh + this._scrollBarSize; var trw = otrw + this._scrollBarSize; var trh = otrh + this._scrollBarSize; var blw = oblw + this._scrollBarSize; var blh = oblh + this._scrollBarSize; var brw = obrw + this._scrollBarSize; var brh = obrh + this._scrollBarSize; var digest = function (el) { el.element.css({ overflow: "scroll", overflowX: "scroll", overflowY: "scroll" }); }; this.topLeft.setWidth(otlw); this.topLeft.setHeight(otlh); this.topRight.setWidth(otrw); this.topRight.setHeight(otrh); this.bottomLeft.setWidth(oblw); this.bottomLeft.setHeight(oblh); this.bottomRight.setWidth(obrw); this.bottomRight.setHeight(obrh); this.topLeftGrid.setWidth(tlw); this.topLeftGrid.setHeight(tlh); this.topRightGrid.setWidth(trw); this.topRightGrid.setHeight(trh); this.bottomLeftGrid.setWidth(blw); this.bottomLeftGrid.setHeight(blh); this.bottomRightGrid.setWidth(brw); this.bottomRightGrid.setHeight(brh); digest(this.topLeftGrid); digest(this.topRightGrid); digest(this.bottomLeftGrid); digest(this.bottomRightGrid); this.topLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); this.topLeftGrid.setEstimatedRowSize(o.headerRowSize); this.topRightGrid.setEstimatedColumnSize((o.columnSize.length - freezeColLength) > 0 ? (totalRightColumnSize / (o.columnSize.length - freezeColLength)) : 0); this.topRightGrid.setEstimatedRowSize(o.headerRowSize); this.bottomLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); this.bottomLeftGrid.setEstimatedRowSize(o.rowSize); this.bottomRightGrid.setEstimatedColumnSize((o.columnSize.length - freezeColLength) > 0 ? (totalRightColumnSize / (o.columnSize.length - freezeColLength)) : 0); this.bottomRightGrid.setEstimatedRowSize(o.rowSize); this.topLeftGrid.setColumnCount(freezeColLength); this.topRightGrid.setColumnCount(o.columnSize.length - freezeColLength); this.bottomLeftGrid.setColumnCount(freezeColLength); this.bottomRightGrid.setColumnCount(o.columnSize.length - freezeColLength); var items = this.contextLayout.attr("items"); items[1].left = regionSize; items[2].top = this._getFreezeHeaderHeight(); items[3].left = regionSize; items[3].top = this._getFreezeHeaderHeight(); this.contextLayout.attr("items", items); this.contextLayout.resize(); this.topLeftGrid._populate(this.header[0]); this.topRightGrid._populate(this.header[1]); this.bottomLeftGrid._populate(this.items[0]); this.bottomRightGrid._populate(this.items[1]); }, _populate: function () { if (this._width <= 0 || this._height <= 0) { return; } this._populateTable(); this._populateScrollbar(); }, getRegionSize: function () { var o = this.options; var regionSize = o.regionColumnSize[0] || 0; if (o.isNeedFreeze === false || o.freezeCols.length === 0) { return 0; } if (!regionSize) { BI.each(o.freezeCols, function (i, col) { regionSize += o.columnSize[col]; }); } return regionSize; }, setVerticalScroll: function (scrollTop) { this.bottomLeftGrid.setScrollTop(scrollTop); this.bottomRightGrid.setScrollTop(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.topLeftGrid.setScrollLeft(scrollLeft); this.bottomLeftGrid.setScrollLeft(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.topRightGrid.setScrollLeft(scrollLeft); this.bottomRightGrid.setScrollLeft(scrollLeft); }, getVerticalScroll: function () { return this.bottomRightGrid.getScrollTop(); }, getLeftHorizontalScroll: function () { return this.bottomLeftGrid.getScrollLeft(); }, getRightHorizontalScroll: function () { return this.bottomRightGrid.getScrollLeft(); }, setWidth: function (width) { BI.GridTable.superclass.setWidth.apply(this, arguments); this._width = this.options.width - BI.GridTableScrollbar.SIZE; }, setHeight: function (height) { BI.GridTable.superclass.setHeight.apply(this, arguments); this._height = this.options.height - BI.GridTableScrollbar.SIZE; }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; this._isNeedDigest = true; }, setRegionColumnSize: function (regionColumnSize) { this.options.regionColumnSize = regionColumnSize; this._isNeedDigest = true; }, getColumnSize: function () { return this.options.columnSize; }, getRegionColumnSize: function () { return this.options.regionColumnSize; }, populate: function (items, header) { if (items && this.options.items !== items) { this.options.items = items; this.items = this._getItems(); this._restore(); } if (header && this.options.header !== header) { this.options.header = header; this.header = this._getHeader(); this._restore(); } this._populate(); }, _restore: function () { this.topLeftGrid.restore(); this.topRightGrid.restore(); this.bottomLeftGrid.restore(); this.bottomRightGrid.restore(); }, restore: function () { this._restore(); } }); BI.shortcut("bi.grid_table", BI.GridTable);/** * QuickGridTable * * Created by GUY on 2016/1/12. * @class BI.QuickGridTable * @extends BI.GridTable */ BI.QuickGridTable = BI.inherit(BI.GridTable, { _defaultConfig: function () { return BI.extend(BI.QuickGridTable.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-quick-grid-table" }); }, render: function () { BI.QuickGridTable.superclass.render.apply(this, arguments); var self = this, o = this.options; this.topLeftGrid.setOverflowX(false); this.topLeftGrid.setOverflowY(false); this.topRightGrid.setOverflowX(false); this.topRightGrid.setOverflowY(false); this.bottomLeftGrid.setOverflowX(false); this.bottomLeftGrid.setOverflowY(false); this.bottomRightGrid.setOverflowX(false); this.bottomRightGrid.setOverflowY(false); }, mounted: function () { BI.QuickGridTable.superclass.mounted.apply(this, arguments); var self = this; this._topLeftWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelLeft, this), BI.bind(this._shouldHandleLeftX, this), BI.bind(this._shouldHandleY, this) ); this._topRightWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelRight, this), BI.bind(this._shouldHandleRightX, this), BI.bind(this._shouldHandleY, this) ); this._bottomLeftWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelLeft, this), BI.bind(this._shouldHandleLeftX, this), BI.bind(this._shouldHandleY, this) ); this._bottomRightWheelHandler = new BI.WheelHandler( BI.bind(this._onWheelRight, this), BI.bind(this._shouldHandleRightX, this), BI.bind(this._shouldHandleY, this) ); this.topLeftGrid.element.mousewheel(function (e) { self._topLeftWheelHandler.onWheel(e.originalEvent); }); this.topRightGrid.element.mousewheel(function (e) { self._topRightWheelHandler.onWheel(e.originalEvent); }); this.bottomLeftGrid.element.mousewheel(function (e) { self._bottomLeftWheelHandler.onWheel(e.originalEvent); }); this.bottomRightGrid.element.mousewheel(function (e) { self._bottomRightWheelHandler.onWheel(e.originalEvent); }); }, _shouldHandleLeftX: function (delta) { if (delta > 0) { return this.bottomLeftGrid.getScrollLeft() < this.bottomLeftGrid.getMaxScrollLeft(); } return this.bottomLeftGrid.getScrollLeft() > 0; }, _shouldHandleRightX: function (delta) { if (delta > 0) { return this.bottomRightGrid.getScrollLeft() < this.bottomRightGrid.getMaxScrollLeft(); } return this.bottomRightGrid.getScrollLeft() > 0; }, _shouldHandleY: function (delta) { if (delta > 0) { return this.bottomRightGrid.getScrollTop() < this.bottomRightGrid.getMaxScrollTop(); } return this.bottomRightGrid.getScrollTop() > 0; }, _onWheelLeft: function (deltaX, deltaY) { var self = this; var scrollTop = this.bottomLeftGrid.getScrollTop(); var scrollLeft = this.bottomLeftGrid.getScrollLeft(); scrollTop += deltaY; scrollLeft += deltaX; this.bottomLeftGrid.setScrollTop(scrollTop); this.bottomRightGrid.setScrollTop(scrollTop); this.topLeftGrid.setScrollLeft(scrollLeft); this.bottomLeftGrid.setScrollLeft(scrollLeft); self._populateScrollbar(); this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }, _onWheelRight: function (deltaX, deltaY) { var self = this; var scrollTop = this.bottomRightGrid.getScrollTop(); var scrollLeft = this.bottomRightGrid.getScrollLeft(); scrollTop += deltaY; scrollLeft += deltaX; this.bottomLeftGrid.setScrollTop(scrollTop); this.bottomRightGrid.setScrollTop(scrollTop); this.topRightGrid.setScrollLeft(scrollLeft); this.bottomRightGrid.setScrollLeft(scrollLeft); self._populateScrollbar(); this.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }, _populateTable: function () { var self = this, o = this.options; var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0, summaryColumnSizeArray = []; var freezeColLength = this._getFreezeColLength(); BI.each(o.columnSize, function (i, size) { if (o.isNeedFreeze === true && o.freezeCols.contains(i)) { totalLeftColumnSize += size; } else { totalRightColumnSize += size; } totalColumnSize += size; if (i === 0) { summaryColumnSizeArray[i] = size; } else { summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size; } }); var otlw = regionSize; var otlh = this._getFreezeHeaderHeight(); var otrw = this._width - regionSize; var otrh = this._getFreezeHeaderHeight(); var oblw = regionSize; var oblh = this._height - otlh; var obrw = this._width - regionSize; var obrh = this._height - otrh; this.topLeft.setWidth(otlw); this.topLeft.setHeight(otlh); this.topRight.setWidth(otrw); this.topRight.setHeight(otrh); this.bottomLeft.setWidth(oblw); this.bottomLeft.setHeight(oblh); this.bottomRight.setWidth(obrw); this.bottomRight.setHeight(obrh); this.topLeftGrid.setWidth(otlw); this.topLeftGrid.setHeight(otlh); this.topRightGrid.setWidth(otrw); this.topRightGrid.setHeight(otrh); this.bottomLeftGrid.setWidth(oblw); this.bottomLeftGrid.setHeight(oblh); this.bottomRightGrid.setWidth(obrw); this.bottomRightGrid.setHeight(obrh); this.topLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); this.topLeftGrid.setEstimatedRowSize(o.headerRowSize); this.topRightGrid.setEstimatedColumnSize((o.columnSize.length - freezeColLength) > 0 ? (totalRightColumnSize / (o.columnSize.length - freezeColLength)) : 0); this.topRightGrid.setEstimatedRowSize(o.headerRowSize); this.bottomLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0); this.bottomLeftGrid.setEstimatedRowSize(o.rowSize); this.bottomRightGrid.setEstimatedColumnSize((o.columnSize.length - freezeColLength) > 0 ? (totalRightColumnSize / (o.columnSize.length - freezeColLength)) : 0); this.bottomRightGrid.setEstimatedRowSize(o.rowSize); this.topLeftGrid.setColumnCount(freezeColLength); this.topRightGrid.setColumnCount(o.columnSize.length - freezeColLength); this.bottomLeftGrid.setColumnCount(freezeColLength); this.bottomRightGrid.setColumnCount(o.columnSize.length - freezeColLength); var items = this.contextLayout.attr("items"); items[1].left = regionSize; items[2].top = this._getFreezeHeaderHeight(); items[3].left = regionSize; items[3].top = this._getFreezeHeaderHeight(); this.contextLayout.attr("items", items); this.contextLayout.resize(); var leftHeader = [], rightHeader = [], leftItems = [], rightItems = []; BI.each(o.header, function (i, cols) { leftHeader[i] = []; rightHeader[i] = []; BI.each(cols, function (j, col) { var cell = { type: "bi.grid_table_cell", cell: col }; if (j < freezeColLength) { leftHeader[i].push(cell); } else { rightHeader[i].push(cell); } }); }); BI.each(this._getActualItems(), function (i, cols) { leftItems[i] = []; rightItems[i] = []; BI.each(cols, function (j, col) { var cell = { type: "bi.grid_table_cell", cell: col }; if (j < freezeColLength) { leftItems[i].push(cell); } else { rightItems[i].push(cell); } }); }); this.topLeftGrid.populate(leftHeader); this.topRightGrid.populate(rightHeader); this.bottomLeftGrid.populate(leftItems); this.bottomRightGrid.populate(rightItems); } }); BI.shortcut("bi.quick_grid_table", BI.QuickGridTable);/** * * 表格滚动条 * * Created by GUY on 2016/1/12. * @class BI.GridTableScrollbar * @extends BI.Widget */ BI.GridTableScrollbar = BI.inherit(BI.Widget, { _const: { FACE_MARGIN: 4, FACE_MARGIN_2: 4 * 2, FACE_SIZE_MIN: 30, KEYBOARD_SCROLL_AMOUNT: 40 }, _defaultConfig: function () { return BI.extend(BI.GridTableScrollbar.superclass._defaultConfig.apply(this, arguments), { baseCls: "scrollbar-layout-main public-scrollbar-main", attributes: { tabIndex: 0 }, contentSize: 0, defaultPosition: 0, isOpaque: false, orientation: "vertical", position: 0, size: 0 }); }, render: function () { var self = this, o = this.options; this.focused = false; this.isDragging = false; this.face = BI.createWidget({ type: "bi.layout", cls: "scrollbar-layout-face public-scrollbar-face " + (this._isHorizontal() ? "scrollbar-layout-face-horizontal" : "scrollbar-layout-face-vertical") }); this.contextLayout = BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.face, left: 0, top: 0 }] }); }, mounted: function () { var self = this, o = this.options; var onWheel = o.orientation === "horizontal" ? this._onWheelX : this._onWheelY; this._wheelHandler = new BI.WheelHandler( BI.bind(onWheel, this), BI.bind(this._shouldHandleX, this), BI.bind(this._shouldHandleY, this) ); this._mouseMoveTracker = new BI.MouseMoveTracker( BI.bind(this._onMouseMove, this), BI.bind(this._onMouseMoveEnd, this), document ); this.element.on("mousedown", BI.bind(this._onMouseDown, this)); this.element.on("mousewheel", function (e) { self._wheelHandler.onWheel(e.originalEvent); }); this.element.on("keydown", BI.bind(this._onKeyDown, this)); this.element.on("focus", function () { self.focused = true; self._populate(); }); this.element.on("blur", function () { self.focused = false; self._populate(); }); if (this._isHorizontal()) { this.element.addClass("scrollbar-layout-main-horizontal"); } else { this.element.addClass("scrollbar-layout-main-vertical"); } this._populate(); }, _isHorizontal: function () { return this.options.orientation === "horizontal"; }, _getScale: function () { var o = this.options; var scale = o.size / o.contentSize; var faceSize = o.size * scale; if (faceSize < this._const.FACE_SIZE_MIN) { scale = (o.size - this._const.FACE_SIZE_MIN) / (o.contentSize - o.size); } return scale; }, _getFaceSize: function () { var o = this.options; var scale = o.size / o.contentSize; var faceSize = o.size * scale; if (faceSize < this._const.FACE_SIZE_MIN) { faceSize = this._const.FACE_SIZE_MIN; } return faceSize; }, _shouldHandleX: function (delta) { return this.options.orientation === "horizontal" ? this._shouldHandleChange(delta) : false; }, _shouldHandleY: function (delta) { return this.options.orientation !== "horizontal" ? this._shouldHandleChange(delta) : false; }, _shouldHandleChange: function (delta) { return this.options.position + delta !== this.options.position; }, _onWheelY: function (deltaX, deltaY) { this._onWheel(deltaY); }, _onWheelX: function (deltaX, deltaY) { this._onWheel(deltaX); }, _onWheel: function (delta) { var maxPosition = this.options.contentSize - this.options.size; this.options.position += delta; if (this.options.position < 0) { this.options.position = 0; } else if (this.options.position > maxPosition) { this.options.position = maxPosition; } this._populate(); this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); }, _onMouseDown: function (e) { if (e.target !== this.face.element[0]) { var position = this._isHorizontal() ? e.offsetX : e.offsetY; position /= this._getScale(); this.options.position = BI.clamp(position - (this._getFaceSize() * 0.5 / this._getScale()), 0, this.options.contentSize - this.options.size); this._populate(); this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); } else { this._mouseMoveTracker.captureMouseMoves(e); } try { this.element[0].focus(); } catch (e) { } }, _onMouseMove: function (deltaX, deltaY) { var delta = this._isHorizontal() ? deltaX : deltaY; delta /= this._getScale(); this.options.position = BI.clamp(this.options.position + delta, 0, this.options.contentSize - this.options.size); this.isDragging = this._mouseMoveTracker.isDragging(); this._populate(); this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); }, _onMouseMoveEnd: function (event) { this._mouseMoveTracker.releaseMouseMoves(); if (this.isDragging === true) { this.isDragging = false; this._populate(); } }, _onKeyDown: function (event) { var Keys = { BACKSPACE: 8, TAB: 9, RETURN: 13, ALT: 18, ESC: 27, SPACE: 32, PAGE_UP: 33, PAGE_DOWN: 34, END: 35, HOME: 36, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, DELETE: 46, COMMA: 188, PERIOD: 190, A: 65, Z: 90, ZERO: 48, NUMPAD_0: 96, NUMPAD_9: 105 }; var keyCode = event.keyCode; if (keyCode === Keys.TAB) { return; } var distance = 40; var direction = 0; if (this._isHorizontal()) { switch (keyCode) { case Keys.HOME: direction = -1; distance = this.options.contentSize; break; case Keys.LEFT: direction = -1; break; case Keys.RIGHT: direction = 1; break; default: return; } } if (!this._isHorizontal()) { switch (keyCode) { case Keys.SPACE: if (event.shiftKey) { direction = -1; } else { direction = 1; } break; case Keys.HOME: direction = -1; distance = this.options.contentSize; break; case Keys.UP: direction = -1; break; case Keys.DOWN: direction = 1; break; case Keys.PAGE_UP: direction = -1; distance = this.options.size; break; case Keys.PAGE_DOWN: direction = 1; distance = this.options.size; break; default: return; } } this.options.position = BI.clamp(this.options.position + (distance * direction), 0, this.options.contentSize - this.options.size); event.preventDefault(); this._populate(); this.fireEvent(BI.GridTableScrollbar.EVENT_SCROLL, this.options.position); }, _populate: function () { var self = this, o = this.options; if (o.size < 1 || o.contentSize <= o.size) { this.setVisible(false); return; } this.setVisible(true); var size = o.size; var isHorizontal = this._isHorizontal(); var isActive = this.focused || this.isDragging; var faceSize = this._getFaceSize(); var isOpaque = o.isOpaque; this.element[isOpaque === true ? "addClass" : "removeClass"]("public-scrollbar-main-opaque"); this.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-main-active"); this.face.element[isActive === true ? "addClass" : "removeClass"]("public-scrollbar-face-active"); var position = o.position * this._getScale() + this._const.FACE_MARGIN; var items = this.contextLayout.attr("items"); if (isHorizontal) { this.setWidth(size); this.face.setWidth(faceSize - this._const.FACE_MARGIN_2); items[0].left = position; items[0].top = 0; } else { this.setHeight(size); this.face.setHeight(faceSize - this._const.FACE_MARGIN_2); items[0].left = 0; items[0].top = position; } this.contextLayout.attr("items", items); this.contextLayout.resize(); }, setContentSize: function (contentSize) { this.options.contentSize = contentSize; }, setPosition: function (position) { this.options.position = position; }, setSize: function (size) { this.options.size = size; }, populate: function () { this._populate(); } }); BI.GridTableScrollbar.SIZE = 10; BI.GridTableScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; BI.shortcut("bi.grid_table_scrollbar", BI.GridTableScrollbar); BI.GridTableHorizontalScrollbar = BI.inherit(BI.Widget, { _const: { FACE_MARGIN: 4, FACE_MARGIN_2: 4 * 2, FACE_SIZE_MIN: 30, KEYBOARD_SCROLL_AMOUNT: 40 }, _defaultConfig: function () { return BI.extend(BI.GridTableHorizontalScrollbar.superclass._defaultConfig.apply(this, arguments), { attributes: { tabIndex: 0 }, contentSize: 0, position: 0, size: 0 }); }, _init: function () { BI.GridTableHorizontalScrollbar.superclass._init.apply(this, arguments); var self = this, o = this.options; this.scrollbar = BI.createWidget({ type: "bi.grid_table_scrollbar", orientation: "horizontal", isOpaque: true, position: o.position, contentSize: o.contentSize, size: o.size }); this.scrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function () { self.fireEvent(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, arguments); }); BI.createWidget({ type: "bi.absolute", cls: "horizontal-scrollbar", element: this, width: o.size, height: BI.GridTableScrollbar.SIZE, items: [{ el: { type: "bi.absolute", scrollable: false, height: BI.GridTableScrollbar.SIZE, items: [{ el: this.scrollbar, left: 0, top: 0 }] }, top: 0, left: 0, right: 0 }] }); }, setContentSize: function (contentSize) { this.options.contentSize = contentSize; this.scrollbar.setContentSize(contentSize); }, setPosition: function (position) { this.options.position = position; this.scrollbar.setPosition(position); }, setSize: function (size) { this.setWidth(size); this.options.size = size; this.scrollbar.setSize(size); }, populate: function () { this.scrollbar.populate(); var o = this.options; if (o.size < 1 || o.contentSize <= o.size) { this.setVisible(false); return; } this.setVisible(true); } }); BI.GridTableHorizontalScrollbar.EVENT_SCROLL = "EVENT_SCROLL"; BI.shortcut("bi.grid_table_horizontal_scrollbar", BI.GridTableHorizontalScrollbar);/** * * 表格 * * Created by GUY on 2015/9/22. * @class BI.TableHeaderCell * @extends BI.Single */ BI.TableHeaderCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.TableHeaderCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-table-header-cell", text: "" }); }, _init: function () { BI.TableHeaderCell.superclass._init.apply(this, arguments); BI.createWidget({ type: "bi.label", element: this, textAlign: "center", height: this.options.height, text: this.options.text, value: this.options.value }); } }); BI.shortcut("bi.table_header_cell", BI.TableHeaderCell);/** * * 表格 * * 能处理静态宽度以及动态宽度的表, 百分比宽度的表请使用PreviewTable * * Created by GUY on 2015/9/22. * @class BI.Table * @extends BI.Widget */ BI.Table = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.Table.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-table", logic: { // 冻结的页面布局逻辑 dynamic: false }, isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为true时生效 isNeedMerge: false, // 是否需要合并单元格 mergeCols: [], // 合并的单元格列号 mergeRule: function (row1, row2) { // 合并规则, 默认相等时合并 return BI.isEqual(row1, row2); }, columnSize: [], headerRowSize: 25, footerRowSize: 25, rowSize: 25, regionColumnSize: false, header: [], footer: false, items: [] // 二维数组 }); }, _calculateWidth: function (width) { if (!width || width === "0") { return ""; } width = BI.parseFloat(width); if (width < 0) { width = 0; } return width > 1.01 ? width : (width * 100 + "%"); }, _calculateHeight: function (height) { return height ? height : ""; }, _isRightFreeze: function () { return BI.isNotEmptyArray(this.options.freezeCols) && BI.first(this.options.freezeCols) !== 0; }, _createTopLeft: function () { var o = this.options, isRight = this._isRightFreeze(); this.topLeftColGroupTds = {}; this.topLeftBodyTds = {}; this.topLeftBodyItems = {}; var table = this._table(); var colgroup = this._createColGroup(this.columnLeft, this.topLeftColGroupTds); var body = this.topLeftBody = this._body(); body.element.append(this._createHeaderCells(this.topLeftItems, this.columnLeft, this.mergeLeft, this.topLeftBodyTds, this.topLeftBodyItems)); BI.createWidget({ type: "bi.adaptive", element: table, items: [colgroup, body] }); if (isRight) { var w = 0; BI.each(o.columnSize, function (i, col) { if (!o.freezeCols.contains(i)) { w += col; } }); if (BI.isNumeric(w) && w > 1) { w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; } } return (this.topLeftContainer = BI.createWidget({ type: "bi.adaptive", width: this._calculateWidth(w), items: [table] })); }, _createTopRight: function () { var o = this.options, isRight = this._isRightFreeze(); this.topRightColGroupTds = {}; this.topRightBodyTds = {}; this.topRightBodyItems = {}; var table = this._table(); var colgroup = this._createColGroup(this.columnRight, this.topRightColGroupTds); var body = this.topRightBody = this._body(); body.element.append(this._createHeaderCells(this.topRightItems, this.columnRight, this.mergeRight, this.topRightBodyTds, this.topRightBodyItems, this.columnLeft.length)); BI.createWidget({ type: "bi.adaptive", element: table, items: [colgroup, body] }); if (!isRight) { var w = 0; BI.each(o.columnSize, function (i, col) { if (!o.freezeCols.contains(i)) { w += col; } }); if (BI.isNumeric(w)) { w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; } } return (this.topRightContainer = BI.createWidget({ type: "bi.adaptive", width: w || undefined, items: [table] })); }, _createBottomLeft: function () { var o = this.options, isRight = this._isRightFreeze(); this.bottomLeftColGroupTds = {}; this.bottomLeftBodyTds = {}; this.bottomLeftBodyItems = {}; var table = this._table(); var colgroup = this._createColGroup(this.columnLeft, this.bottomLeftColGroupTds); var body = this._createBottomLeftBody(); BI.createWidget({ type: "bi.adaptive", element: table, items: [colgroup, body] }); if (isRight) { var w = 0; BI.each(o.columnSize, function (i, col) { if (!o.freezeCols.contains(i)) { w += col; } }); if (BI.isNumeric(w) && w > 1) { w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; } } return (this.bottomLeftContainer = BI.createWidget({ type: "bi.adaptive", width: this._calculateWidth(w), items: [table] })); }, _createBottomLeftBody: function () { var body = this.bottomLeftBody = this._body(); body.element.append(this._createCells(this.bottomLeftItems, this.columnLeft, this.mergeLeft, this.bottomLeftBodyTds, this.bottomLeftBodyItems)); return body; }, _createBottomRight: function () { var o = this.options, isRight = this._isRightFreeze(); this.bottomRightColGroupTds = {}; this.bottomRightBodyTds = {}; this.bottomRightBodyItems = {}; var table = this._table(); var colgroup = this._createColGroup(this.columnRight, this.bottomRightColGroupTds); var body = this._createBottomRightBody(); BI.createWidget({ type: "bi.adaptive", element: table, items: [colgroup, body] }); if (!isRight) { var w = 0; BI.each(o.columnSize, function (i, col) { if (!o.freezeCols.contains(i)) { w += col; } }); if (BI.isNumeric(w) && w > 1) { w = BI.parseFloat(w) + o.columnSize.length - o.freezeCols.length; } } return (this.bottomRightContainer = BI.createWidget({ type: "bi.adaptive", width: this._calculateWidth(w), items: [table] })); }, _createBottomRightBody: function () { var body = this.bottomRightBody = this._body(); body.element.append(this._createCells(this.bottomRightItems, this.columnRight, this.mergeRight, this.bottomRightBodyTds, this.bottomRightBodyItems, this.columnLeft.length)); return body; }, _createFreezeTable: function () { var self = this, o = this.options; var isRight = this._isRightFreeze(); var split = this._split(o.header); this.topLeftItems = split.left; this.topRightItems = split.right; split = this._split(o.items); this.bottomLeftItems = split.left; this.bottomRightItems = split.right; this.columnLeft = []; this.columnRight = []; BI.each(o.columnSize, function (i, size) { if (o.freezeCols.contains(i)) { self[isRight ? "columnRight" : "columnLeft"].push(size); } else { self[isRight ? "columnLeft" : "columnRight"].push(size); } }); this.mergeLeft = []; this.mergeRight = []; BI.each(o.mergeCols, function (i, col) { if (o.freezeCols.contains(col)) { self[isRight ? "mergeRight" : "mergeLeft"].push(col); } else { self[isRight ? "mergeLeft" : "mergeRight"].push(col); } }); var topLeft = this._createTopLeft(); var topRight = this._createTopRight(); var bottomLeft = this._createBottomLeft(); var bottomRight = this._createBottomRight(); this.scrollTopLeft = BI.createWidget({ type: "bi.adaptive", cls: "scroll-top-left", width: "100%", height: "100%", scrollable: false, items: [topLeft] }); this.scrollTopRight = BI.createWidget({ type: "bi.adaptive", cls: "scroll-top-right", width: "100%", height: "100%", scrollable: false, items: [topRight] }); this.scrollBottomLeft = BI.createWidget({ type: "bi.adaptive", cls: "scroll-bottom-left", width: "100%", height: "100%", scrollable: isRight || null, scrollx: !isRight, items: [bottomLeft] }); this.scrollBottomRight = BI.createWidget({ type: "bi.adaptive", cls: "scroll-bottom-right", width: "100%", height: "100%", scrollable: !isRight || null, scrollx: isRight, items: [bottomRight] }); this.topLeft = BI.createWidget({ type: "bi.adaptive", cls: "top-left", scrollable: false, items: [this.scrollTopLeft] }); this.topRight = BI.createWidget({ type: "bi.adaptive", cls: "top-right", scrollable: false, items: [this.scrollTopRight] }); this.bottomLeft = BI.createWidget({ type: "bi.adaptive", cls: "bottom-left", // scrollable: false, items: [this.scrollBottomLeft] }); this.bottomRight = BI.createWidget({ type: "bi.adaptive", cls: "bottom-right", scrollable: false, items: [this.scrollBottomRight] }); var headerHeight = o.header.length * ((o.headerRowSize || o.rowSize) + 1) + 1; var leftWidth = BI.sum(o.freezeCols, function (i, col) { return o.columnSize[col] > 1 ? o.columnSize[col] + 1 : o.columnSize[col]; }); this._resize = function () { if (self.scrollBottomLeft.element.is(":visible")) { self.scrollBottomLeft.element.css({"overflow-x": "auto"}); self.scrollBottomRight.element.css({"overflow-x": "auto"}); self.setColumnSize(o.columnSize); if (isRight) { self.scrollBottomLeft.element.css({"overflow-y": "auto"}); } else { self.scrollBottomRight.element.css({"overflow-y": "auto"}); } if (self.scrollBottomLeft.element.hasHorizonScroll() || self.scrollBottomRight.element.hasHorizonScroll()) { self.scrollBottomLeft.element.css("overflow-x", "scroll"); self.scrollBottomRight.element.css("overflow-x", "scroll"); } if (self.scrollBottomRight.element.hasVerticalScroll()) { self.scrollTopRight.element.css("overflow-y", "scroll"); } else { self.scrollTopRight.element.css("overflow-y", "hidden"); } if (self.scrollBottomLeft.element.hasVerticalScroll()) { self.scrollTopLeft.element.css("overflow-y", "scroll"); } else { self.scrollTopLeft.element.css("overflow-y", "hidden"); } self.scrollTopLeft.element[0].scrollLeft = self.scrollBottomLeft.element[0].scrollLeft; self.scrollTopRight.element[0].scrollLeft = self.scrollBottomRight.element[0].scrollLeft; self.scrollBottomLeft.element[0].scrollTop = self.scrollBottomRight.element[0].scrollTop; } }; var regionColumnSize = o.regionColumnSize; if (o.freezeCols.length === 0) { regionColumnSize = isRight ? ["fill", 0] : [0, "fill"]; } else if (o.freezeCols.length >= o.columnSize.length) { regionColumnSize = isRight ? [0, "fill"] : ["fill", 0]; } this.partitions = BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic("table", BI.extend({}, o.logic, { rows: 2, columns: 2, columnSize: regionColumnSize || (isRight ? ["fill", leftWidth] : [leftWidth, "fill"]), rowSize: [headerHeight, "fill"], items: [[{ el: this.topLeft }, { el: this.topRight }], [{ el: this.bottomLeft }, { el: this.bottomRight }]] })))); this._initFreezeScroll(); BI.ResizeDetector.addResizeListener(this, function () { self._resize(); self.fireEvent(BI.Table.EVENT_TABLE_RESIZE); }); }, mounted: function () { this._resize && this._resize(); this.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT); }, _initFreezeScroll: function () { var self = this, o = this.options; scroll(this.scrollBottomRight.element, this.scrollTopRight.element, this.scrollBottomLeft.element); // scroll(this.scrollBottomLeft.element, this.scrollTopLeft.element, this.scrollBottomRight.element); function scroll (scrollElement, scrollTopElement, otherElement) { scrollElement.scroll(function (e) { otherElement.scrollTop(scrollElement.scrollTop()); scrollTopElement.scrollLeft(scrollElement.scrollLeft()); self.fireEvent(BI.Table.EVENT_TABLE_SCROLL); }); } }, resize: function () { this._resize && this._resize(); }, _createCells: function (items, columnSize, mergeCols, TDs, Ws, start, rowSize) { var self = this, o = this.options, preCol = {}, preRow = {}, preRW = {}, preCW = {}, map = {}; columnSize = columnSize || o.columnSize; mergeCols = mergeCols || o.mergeCols; TDs = TDs || {}; Ws = Ws || {}; start = start || 0; rowSize || (rowSize = o.rowSize); var frag = document.createDocumentFragment(); BI.each(items, function (i, rows) { var tr = $("<tr>").addClass((i & 1) === 0 ? "odd" : "even"); BI.each(rows, function (j, row) { if (!map[i]) { map[i] = {}; } if (!TDs[i]) { TDs[i] = {}; } if (!Ws[i]) { Ws[i] = {}; } map[i][j] = row; if (o.isNeedMerge && mergeCols.contains(j)) { if (i === 0 && j === 0) { createOneEl(0, 0); } else if (j === 0 && i > 0) { var isNeedMergeRow = o.mergeRule(map[i][j], map[i - 1][j]); if (isNeedMergeRow === true) { mergeRow(i, j); preRow[i] = preCol[j]; preRW[i] = preCW[j]; } else { createOneEl(i, j); } } else if (i === 0 && j > 0) { var isNeedMergeCol = o.mergeRule(map[i][j], map[i][j - 1]); if (isNeedMergeCol === true) { mergeCol(i, j); preCol[j] = preRow[i]; preCW[j] = preRW[i]; } else { createOneEl(i, j); } } else { var isNeedMergeRow = o.mergeRule(map[i][j], map[i - 1][j]); var isNeedMergeCol = o.mergeRule(map[i][j], map[i][j - 1]); if (isNeedMergeCol && isNeedMergeRow) { return; } if (isNeedMergeCol) { mergeCol(i, j); } if (isNeedMergeRow) { mergeRow(i, j); } if (!isNeedMergeCol && !isNeedMergeRow) { createOneEl(i, j); } } } else { createOneEl(i, j); } }); function mergeRow (i, j) { var height = (preCol[j].attr("height") | 0) + rowSize + 1; preCol[j].attr("height", height).css("height", height); // preCW[j].element.css("height", height); var rowspan = ((preCol[j].attr("rowspan") || 1) | 0) + 1; preCol[j].attr("rowspan", rowspan); preCol[j].__mergeRows.pushDistinct(i); TDs[i][j] = preCol[j]; Ws[i][j] = preCW[j]; } function mergeCol (i, j) { if (columnSize[j]) { var width = preRow[i].attr("width") | 0; if (width > 1.05 && columnSize[j]) { width = width + columnSize[j] + 1; if (j === columnSize.length - 1) { width--; } } else { width = width + columnSize[j]; } width = self._calculateWidth(width); preRow[i].attr("width", width).css("width", width); preRW[i].element.width(width); } var colspan = ((preRow[i].attr("colspan") || 1) | 0) + 1; preRow[i].attr("colspan", colspan); preRow[i].__mergeCols.pushDistinct(j); TDs[i][j] = preRow[i]; Ws[i][j] = preRW[i]; } function createOneEl (r, c) { var width = self._calculateWidth(columnSize[c]); if (width > 1.05 && c === columnSize.length - 1) { width--; } var height = self._calculateHeight(rowSize); var td = $("<td>").attr("height", height) .attr("width", width).css({width: width, height: height, position: "relative"}) .addClass((c & 1) === 0 ? "odd-col" : "even-col") .addClass(r === 0 ? "first-row" : "") .addClass(c === 0 ? "first-col" : "") .addClass(c === rows.length - 1 ? "last-col" : ""); var w = BI.createWidget(map[r][c], { type: "bi.table_cell", textAlign: "left", width: BI.isNumeric(width) ? width : "", height: BI.isNumeric(height) ? height : "", _row: r, _col: c + start }); self.addWidget(w.getName(), w); w._mount(); w.element.css("position", "relative"); td.append(w.element); tr.append(td); preCol[c] = td; preCol[c].__mergeRows = [r]; preCW[c] = w; preRow[r] = td; preRow[r].__mergeCols = [c]; preRW[r] = w; TDs[r][c] = td; Ws[r][c] = w; } frag.appendChild(tr[0]); }); return frag; }, _createColGroupCells: function (columnSize, store) { var self = this, o = this.options; columnSize = columnSize || o.columnSize; store = store || {}; var frag = document.createDocumentFragment(); BI.each(columnSize, function (i, size) { var width = self._calculateWidth(size); var col = $("<col>").attr("width", width).css("width", width); store[i] = col; frag.appendChild(col[0]); }); return frag; }, _createHeaderCells: function (items, columnSize, mergeCols, TDs, Ws, start) { var self = this, o = this.options; start || (start = 0); var frag = this._createCells(items, columnSize, BI.range(o.columnSize.length), TDs, Ws, start, o.headerRowSize || o.rowSize); return frag; }, _createFooterCells: function (items, columnSize, TDs, Ws) { var o = this.options; var frag = this._createCells(items, columnSize, [], TDs, Ws, 0); return frag; }, _createColGroup: function (columnSize, store, widgets) { var self = this, o = this.options; this.colgroup = this._colgroup(); this.colgroup.element.append(this._createColGroupCells(columnSize, store, widgets)); return this.colgroup; }, _createHeader: function () { var self = this, o = this.options; if (o.header === false) { return; } this.header = this._header(); this.header.element.append(this._createHeaderCells(o.header, null, null, this.headerTds, this.headerItems)); return this.header; }, _createFooter: function (columnSize, store, widgets) { var self = this, o = this.options; if (o.footer === false) { return; } this.footer = this._footer(); this.footer.element.append(this._createFooterCells(o.footer, null, this.footerTds, this.footerItems)); return this.footer; }, _createBody: function () { var self = this, o = this.options; this.body = this._body(); this.body.element.append(this._createCells(o.items, null, null, this.bodyTds, this.bodyItems)); return this.body; }, _createNormalTable: function () { var self = this, o = this.options, table = this._table(); this.colgroupTds = {}; this.headerTds = {}; this.footerTds = {}; this.bodyTds = {}; this.headerItems = {}; this.footerItems = {}; this.bodyItems = {}; var colgroup = this._createColGroup(null, this.colgroupTds); var header = this._createHeader(); var footer = this._createFooter(); var body = this._createBody(); BI.createWidget({ type: "bi.adaptive", element: table, items: [colgroup, header, footer, body] }); var w = BI.sum(this.options.columnSize) || undefined; w = this._calculateWidth(w); if (BI.isNumeric(w) && w > 1) { w += o.columnSize.length; } this.tableContainer = BI.createWidget({ type: "bi.adaptive", width: this._calculateWidth(w), items: [table] }); this.scrollBottomRight = BI.createWidget({ type: "bi.adaptive", width: "100%", height: "100%", cls: "scroll-bottom-right", scrollable: true, items: [this.tableContainer] }); BI.createWidget({ type: "bi.adaptive", cls: "bottom-right", element: this, scrollable: false, items: [this.scrollBottomRight] }); this._initNormalScroll(); BI.nextTick(function () { if (self.element.is(":visible")) { self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT); } }); }, _initNormalScroll: function () { var self = this; this.scrollBottomRight.element.scroll(function (e) { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL); }); }, _split: function (items) { var o = this.options, left = [], right = [], isRight = this._isRightFreeze(); BI.each(items, function (i, rows) { left.push([]); right.push([]); BI.each(rows, function (j, cell) { if (o.freezeCols.contains(j)) { (isRight ? right : left)[i].push(cell); } else { (isRight ? left : right)[i].push(cell); } }); }); return { left: left, right: right }; }, _table: function () { return BI.createWidget({ type: "bi.layout", tagName: "table", cls: "table", attribute: {cellspacing: 0, cellpadding: 0} }); }, _header: function () { return BI.createWidget({ type: "bi.layout", cls: "header", tagName: "thead" }); }, _footer: function () { return BI.createWidget({ type: "bi.layout", cls: "footer", tagName: "tfoot" }); }, _body: function () { return BI.createWidget({ type: "bi.layout", tagName: "tbody", cls: "body" }); }, _colgroup: function () { return BI.createWidget({ type: "bi.layout", tagName: "colgroup" }); }, render: function () { this.populate(this.options.items); }, setColumnSize: function (columnSize) { var self = this, o = this.options; var isRight = this._isRightFreeze(); o.columnSize = columnSize || []; if (o.isNeedFreeze) { var columnLeft = []; var columnRight = []; BI.each(o.columnSize, function (i, size) { if (o.freezeCols.contains(i)) { isRight ? columnRight.push(size) : columnLeft.push(size); } else { isRight ? columnLeft.push(size) : columnRight.push(size); } }); var topleft = 0, topright = 1, bottomleft = 2, bottomright = 3; var run = function (direction) { var colgroupTds, bodyTds, bodyItems, sizes; switch (direction) { case topleft: colgroupTds = self.topLeftColGroupTds; bodyTds = self.topLeftBodyTds; bodyItems = self.topLeftBodyItems; sizes = columnLeft; break; case topright: colgroupTds = self.topRightColGroupTds; bodyTds = self.topRightBodyTds; bodyItems = self.topRightBodyItems; sizes = columnRight; break; case bottomleft: colgroupTds = self.bottomLeftColGroupTds; bodyTds = self.bottomLeftBodyTds; bodyItems = self.bottomLeftBodyItems; sizes = columnLeft; break; case bottomright: colgroupTds = self.bottomRightColGroupTds; bodyTds = self.bottomRightBodyTds; bodyItems = self.bottomRightBodyItems; sizes = columnRight; break; } BI.each(colgroupTds, function (i, colgroup) { var width = colgroup.attr("width") | 0; if (sizes[i] !== "" && width !== sizes[i]) { var w = self._calculateWidth(sizes[i]); colgroup.attr("width", w).css("width", w); BI.each(bodyTds, function (j, items) { if (items[i]) { if (items[i].__mergeCols.length > 1) { var wid = 0; BI.each(sizes, function (t, s) { if (items[i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += items[i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].attr("width", wid - 1).css("width", wid - 1); } else { items[i].attr("width", wid).css("width", wid); } } else { items[i].attr("width", "").css("width", ""); } } else { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } } }); BI.each(bodyItems, function (j, items) { if (items[i]) { if (bodyTds[j][i].__mergeCols.length > 1) { var wid = 0; BI.each(sizes, function (t, s) { if (bodyTds[j][i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += bodyTds[j][i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", wid - 1).css("width", wid - 1); } else { items[i].element.attr("width", wid).css("width", wid); } } else { items[i].element.attr("width", "").css("width", ""); } } else { if (BI.isNumeric(w)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", w - 1).css("width", w - 1); } else { items[i].element.attr("width", w).css("width", w); } } else { items[i].element.attr("width", "").css("width", ""); } } } }); } }); }; run(topleft); run(topright); run(bottomleft); run(bottomright); var lw = 0, rw = 0; this.columnLeft = []; this.columnRight = []; BI.each(o.columnSize, function (i, size) { if (o.freezeCols.contains(i)) { lw += size; self[isRight ? "columnRight" : "columnLeft"].push(size); } else { rw += size; self[isRight ? "columnLeft" : "columnRight"].push(size); } }); lw = this._calculateWidth(lw); rw = this._calculateWidth(rw); if (BI.isNumeric(lw)) { lw = BI.parseFloat(lw) + o.freezeCols.length; } if (BI.isNumeric(rw)) { rw = BI.parseFloat(rw) + o.columnSize.length - o.freezeCols.length; } this.topLeftContainer.element.width(isRight ? rw : lw); this.bottomLeftContainer.element.width(isRight ? rw : lw); this.topRightContainer.element.width(isRight ? lw : rw); this.bottomRightContainer.element.width(isRight ? lw : rw); this.scrollTopLeft.element[0].scrollLeft = this.scrollBottomLeft.element[0].scrollLeft; this.scrollTopRight.element[0].scrollLeft = this.scrollBottomRight.element[0].scrollLeft; } else { BI.each(this.colgroupTds, function (i, colgroup) { var width = colgroup.attr("width") | 0; if (o.columnSize[i] !== "" && width !== o.columnSize[i]) { var w = self._calculateWidth(o.columnSize[i]); colgroup.attr("width", w).css("width", w); BI.each(self.bodyTds, function (j, items) { if (items[i]) { if (items[i].__mergeCols.length > 1) { var wid = 0; BI.each(o.columnSize, function (t, s) { if (items[i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += items[i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } else { items[i].attr("width", "").css("width", ""); } } else { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } } }); BI.each(self.headerTds, function (j, items) { if (items[i]) { if (items[i].__mergeCols.length > 1) { var wid = 0; BI.each(o.columnSize, function (t, s) { if (items[i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += items[i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } else { items[i].attr("width", "").css("width", ""); } } else { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } } }); BI.each(self.footerTds, function (j, items) { if (items[i]) { if (items[i].__mergeCols.length > 1) { var wid = 0; BI.each(o.columnSize, function (t, s) { if (items[i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += items[i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } else { items[i].attr("width", "").css("width", ""); } } else { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } } }); BI.each(self.bodyItems, function (j, items) { if (items[i]) { if (self.bodyTds[j][i].__mergeCols.length > 1) { var wid = 0; BI.each(o.columnSize, function (t, s) { if (self.bodyTds[j][i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += self.bodyTds[j][i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", wid - 1).css("width", wid - 1); } else { items[i].element.attr("width", wid).css("width", wid); } } else { items[i].element.attr("width", "").css("width", ""); } } else { if (BI.isNumeric(w)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", w - 1).css("width", w - 1); } else { items[i].element.attr("width", w).css("width", w); } } else { items[i].element.attr("width", "").css("width", ""); } } } }); BI.each(self.headerItems, function (j, items) { if (items[i]) { if (self.headerTds[j][i].__mergeCols.length > 1) { var wid = 0; BI.each(o.columnSize, function (t, s) { if (self.headerTds[j][i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += self.headerTds[j][i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", wid - 1).css("width", wid - 1); } else { items[i].element.attr("width", wid).css("width", wid); } } else { items[i].element.attr("width", "").css("width", ""); } } else { if (BI.isNumeric(w)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", w - 1).css("width", w - 1); } else { items[i].element.attr("width", w).css("width", w); } } else { items[i].element.attr("width", "").css("width", ""); } } } }); BI.each(self.footerItems, function (j, items) { if (items[i]) { if (self.footerTds[j][i].__mergeCols.length > 1) { var wid = 0; BI.each(o.columnSize, function (t, s) { if (self.footerTds[j][i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += self.footerTds[j][i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", wid - 1).css("width", wid - 1); } else { items[i].element.attr("width", wid).css("width", wid); } } else { items[i].element.attr("width", "").css("width", ""); } } else { if (BI.isNumeric(w)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", w - 1).css("width", w - 1); } else { items[i].element.attr("width", w).css("width", w); } } else { items[i].element.attr("width", "").css("width", ""); } } } }); } }); var w = this._calculateWidth(BI.sum(o.columnSize)); if (w > 1.05) { w += o.columnSize.length; } if (w > 1.05) { this.tableContainer.element.width(w); } } }, getColumnSize: function () { return this.options.columnSize; }, getCalculateColumnSize: function () { var self = this, o = this.options; var columnSize = []; if (o.isNeedFreeze === true) { if (BI.size(this.bottomLeftBodyTds) > 0 || BI.size(this.bottomRightBodyTds) > 0) { if (!BI.any(this.bottomLeftBodyTds, function (i, tds) { if (!BI.any(tds, function (i, item) { if (item.__mergeCols.length > 1) { return true; } })) { BI.each(tds, function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(tds) - 1) { width++; } columnSize.push(width); }); return true; } })) { BI.each(this.bottomLeftBodyTds[0], function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(self.bottomLeftBodyTds[0]) - 1) { width++; } columnSize.push(width); }); } if (!BI.any(this.bottomRightBodyTds, function (i, tds) { if (!BI.any(tds, function (i, item) { if (item.__mergeCols.length > 1) { return true; } })) { BI.each(tds, function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(tds) - 1) { width++; } columnSize.push(width); }); return true; } })) { BI.each(this.bottomRightBodyTds[0], function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(self.bottomRightBodyTds[0]) - 1) { width++; } columnSize.push(width); }); } return columnSize; } if (!BI.any(this.topLeftBodyTds, function (i, tds) { if (!BI.any(tds, function (i, item) { if (item.__mergeCols.length > 1) { return true; } })) { BI.each(tds, function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(tds) - 1) { width++; } columnSize.push(width); }); return true; } })) { BI.each(this.topLeftBodyTds[BI.size(this.topLeftBodyTds) - 1], function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(self.topLeftBodyTds[BI.size(self.topLeftBodyTds) - 1]) - 1) { width++; } columnSize.push(width); }); } if (!BI.any(this.topRightBodyTds, function (i, tds) { if (!BI.any(tds, function (i, item) { if (item.__mergeCols.length > 1) { return true; } })) { BI.each(tds, function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(tds) - 1) { width++; } columnSize.push(width); }); return true; } })) { BI.each(this.topRightBodyTds[BI.size(this.topRightBodyTds) - 1], function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(self.topRightBodyTds[BI.size(self.topRightBodyTds) - 1]) - 1) { width++; } columnSize.push(width); }); } } else { BI.each(this.headerTds[BI.size(this.headerTds) - 1], function (i, item) { var width = item.width() / item.__mergeCols.length; if (i == BI.size(self.headerTds[BI.size(self.headerTds) - 1]) - 1) { width++; } columnSize.push(width); }); } return columnSize; }, setHeaderColumnSize: function (columnSize) { var self = this, o = this.options; var isRight = this._isRightFreeze(); if (o.isNeedFreeze) { var columnLeft = []; var columnRight = []; BI.each(columnSize, function (i, size) { if (o.freezeCols.contains(i)) { isRight ? columnRight.push(size) : columnLeft.push(size); } else { isRight ? columnLeft.push(size) : columnRight.push(size); } }); var topleft = 0, topright = 1; var run = function (direction) { var colgroupTds, bodyTds, bodyItems, sizes; switch (direction) { case topleft: colgroupTds = self.topLeftColGroupTds; bodyTds = self.topLeftBodyTds; bodyItems = self.topLeftBodyItems; sizes = columnLeft; break; case topright: colgroupTds = self.topRightColGroupTds; bodyTds = self.topRightBodyTds; bodyItems = self.topRightBodyItems; sizes = columnRight; break; } BI.each(colgroupTds, function (i, colgroup) { var width = colgroup.attr("width") | 0; if (width !== sizes[i]) { var w = self._calculateWidth(sizes[i]); colgroup.attr("width", w).css("width", w); BI.each(bodyTds, function (j, items) { if (items[i]) { if (items[i].__mergeCols.length > 1) { var wid = 0; BI.each(sizes, function (t, s) { if (items[i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += items[i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].attr("width", wid - 1).css("width", wid - 1); } else { items[i].attr("width", wid).css("width", wid); } } else { items[i].attr("width", "").css("width", ""); } } else { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } } }); BI.each(bodyItems, function (j, items) { if (items[i]) { if (bodyTds[j][i].__mergeCols.length > 1) { var wid = 0; BI.each(sizes, function (t, s) { if (bodyTds[j][i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += bodyTds[j][i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", wid - 1).css("width", wid - 1); } else { items[i].element.attr("width", wid).css("width", wid); } } else { items[i].element.attr("width", "").css("width", ""); } } else { if (BI.isNumeric(w)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", w - 1).css("width", w - 1); } else { items[i].element.attr("width", w).css("width", w); } } else { items[i].element.attr("width", "").css("width", ""); } } } }); } }); }; run(topleft); run(topright); var lw = 0, rw = 0; BI.each(columnSize, function (i, size) { if (o.freezeCols.contains(i)) { lw += size; } else { rw += size; } }); lw = this._calculateWidth(lw); rw = this._calculateWidth(rw); if (BI.isNumeric(lw)) { lw = BI.parseFloat(lw) + o.freezeCols.length; } if (BI.isNumeric(rw)) { rw = BI.parseFloat(rw) + columnSize.length - o.freezeCols.length; } this.topLeftContainer.element.width(isRight ? rw : lw); this.topRightContainer.element.width(isRight ? lw : rw); this.scrollTopLeft.element[0].scrollLeft = this.scrollBottomLeft.element[0].scrollLeft; this.scrollTopRight.element[0].scrollLeft = this.scrollBottomRight.element[0].scrollLeft; } else { BI.each(this.colgroupTds, function (i, colgroup) { var width = colgroup.attr("width") | 0; if (width !== columnSize[i]) { var w = self._calculateWidth(columnSize[i]); colgroup.attr("width", w).css("width", w); BI.each(self.headerTds, function (j, items) { if (items[i]) { if (items[i].__mergeCols.length > 1) { var wid = 0; BI.each(columnSize, function (t, s) { if (items[i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += items[i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", wid - 1).css("width", wid - 1); } else { items[i].element.attr("width", wid).css("width", wid); } } else { items[i].attr("width", "").css("width", ""); } } else { if (i == BI.size(items) - 1) { items[i].attr("width", w - 1).css("width", w - 1); } else { items[i].attr("width", w).css("width", w); } } } }); BI.each(self.headerItems, function (j, items) { if (items[i]) { if (self.headerTds[j][i].__mergeCols.length > 1) { var wid = 0; BI.each(columnSize, function (t, s) { if (self.headerTds[j][i].__mergeCols.contains(t)) { wid += s; } }); wid = self._calculateWidth(wid); if (wid > 1) { wid += self.headerTds[j][i].__mergeCols.length - 1; } if (BI.isNumeric(wid)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", wid - 1).css("width", wid - 1); } else { items[i].element.attr("width", wid).css("width", wid); } } else { items[i].element.attr("width", "").css("width", ""); } } else { if (BI.isNumeric(w)) { if (i == BI.size(items) - 1) { items[i].element.attr("width", w - 1).css("width", w - 1); } else { items[i].element.attr("width", w).css("width", w); } } else { items[i].element.attr("width", "").css("width", ""); } } } }); } }); var cW = this._calculateWidth(BI.sum(columnSize)); if (cW > 1.05) { cW = cW + columnSize.length; } this.tableContainer.element.width(cW); } }, setRegionColumnSize: function (columnSize) { var self = this, o = this.options; o.regionColumnSize = columnSize; if (o.freezeCols.length === 0) { if (o.isNeedFreeze) { this.partitions.attr("columnSize", this._isRightFreeze() ? ["fill", 0] : [0, "fill"]); this.partitions.resize(); } else { this.tableContainer.element.width(columnSize[0]); } } else if (o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) { if (o.isNeedFreeze) { this.partitions.attr("columnSize", columnSize); this.partitions.resize(); } else { this.tableContainer.element.width(columnSize[0]); } } else { if (o.isNeedFreeze) { this.partitions.attr("columnSize", this._isRightFreeze() ? [0, "fill"] : ["fill", 0]); this.partitions.resize(); } else { this.tableContainer.element.width(columnSize[0]); } } }, getRegionColumnSize: function () { return this.options.regionColumnSize; }, getCalculateRegionColumnSize: function () { var o = this.options; if (o.isNeedFreeze) { return [this.scrollBottomLeft.element.width(), this.scrollBottomRight.element.width()]; } return [this.scrollBottomRight.element.width()]; }, getCalculateRegionRowSize: function () { var o = this.options; if (o.isNeedFreeze) { return [this.scrollTopRight.element.height(), this.scrollBottomRight.element.height()]; } return [this.scrollBottomRight.element.height()]; }, getClientRegionColumnSize: function () { var o = this.options; if (o.isNeedFreeze) { return [this.scrollBottomLeft.element[0].clientWidth, this.scrollBottomRight.element[0].clientWidth]; } return [this.scrollBottomRight.element[0].clientWidth]; }, getClientRegionRowSize: function () { var o = this.options; if (o.isNeedFreeze) { return [this.scrollBottomLeft.element[0].clientHeight, this.scrollBottomRight.element[0].clientHeight]; } return [this.scrollBottomRight.element[0].clientHeight]; }, getScrollRegionColumnSize: function () { var o = this.options; if (o.isNeedFreeze) { return [this.scrollBottomLeft.element[0].scrollWidth, this.scrollBottomRight.element[0].scrollWidth]; } return [this.scrollBottomRight.element[0].scrollWidth]; }, getScrollRegionRowSize: function () { var o = this.options; if (o.isNeedFreeze) { if (o.freezeCols.length < o.columnSize.length) { return [this.scrollTopRight.element[0].scrollHeight, this.scrollBottomRight.element[0].scrollHeight]; } return [this.scrollTopLeft.element[0].scrollHeight, this.scrollBottomLeft.element[0].scrollHeight]; } return [this.scrollBottomRight.element[0].scrollHeight]; }, hasVerticalScroll: function () { var o = this.options; if (o.isNeedFreeze) { return this.scrollBottomRight.element.hasVerticalScroll() || this.scrollBottomLeft.element.hasVerticalScroll(); } return this.scrollBottomRight.element.hasVerticalScroll(); }, setVerticalScroll: function (scrollTop) { var o = this.options; if (o.isNeedFreeze) { if (this.scrollBottomRight.element[0].scrollTop !== scrollTop) { this.scrollBottomRight.element[0].scrollTop = scrollTop; } if (this.scrollBottomLeft.element[0].scrollTop !== scrollTop) { this.scrollBottomLeft.element[0].scrollTop = scrollTop; } } else { if (this.scrollBottomRight.element[0].scrollTop !== scrollTop) { this.scrollBottomRight.element[0].scrollTop = scrollTop; } } }, setLeftHorizontalScroll: function (scrollLeft) { var o = this.options; if (o.isNeedFreeze) { if (this.scrollBottomLeft.element[0].scrollLeft !== scrollLeft) { this.scrollBottomLeft.element[0].scrollLeft = scrollLeft; } if (this.scrollTopLeft.element[0].scrollLeft !== scrollLeft) { this.scrollTopLeft.element[0].scrollLeft = scrollLeft; } } else { if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { this.scrollBottomRight.element[0].scrollLeft = scrollLeft; } } }, setRightHorizontalScroll: function (scrollLeft) { var o = this.options; if (o.isNeedFreeze) { if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { this.scrollBottomRight.element[0].scrollLeft = scrollLeft; } if (this.scrollTopRight.element[0].scrollLeft !== scrollLeft) { this.scrollTopRight.element[0].scrollLeft = scrollLeft; } } else { if (this.scrollBottomRight.element[0].scrollLeft !== scrollLeft) { this.scrollBottomRight.element[0].scrollLeft = scrollLeft; } } }, getVerticalScroll: function () { var o = this.options; if (o.isNeedFreeze) { return this.scrollBottomRight.element[0].scrollTop || this.scrollBottomLeft.element[0].scrollTop; } return this.scrollBottomRight.element[0].scrollTop; }, getLeftHorizontalScroll: function () { var o = this.options; if (o.isNeedFreeze) { return this.scrollBottomLeft.element[0].scrollLeft; } return this.scrollBottomRight.element[0].scrollLeft; }, getRightHorizontalScroll: function () { var o = this.options; if (o.isNeedFreeze) { return this.scrollBottomRight.element[0].scrollLeft; } return this.scrollBottomRight.element[0].scrollLeft; }, getColumns: function () { var o = this.options; if (o.isNeedFreeze) { return { topLeft: this.topLeftBodyItems, topRight: this.topRightBodyItems, bottomLeft: this.bottomLeftBodyItems, bottomRight: this.bottomRightBodyItems }; } return { header: this.headerItems, body: this.bodyItems, footer: this.footerItems }; }, populate: function (items, header) { this.options.items = items || []; if (header) { this.options.header = header; } this.empty(); if (this.options.isNeedFreeze) { this._createFreezeTable(); } else { this._createNormalTable(); } } }) ; BI.Table.EVENT_TABLE_AFTER_INIT = "EVENT_TABLE_AFTER_INIT"; BI.Table.EVENT_TABLE_RESIZE = "EVENT_TABLE_RESIZE"; BI.Table.EVENT_TABLE_SCROLL = "EVENT_TABLE_SCROLL"; BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE = "EVENT_TABLE_BEFORE_COLUMN_RESIZE"; BI.Table.EVENT_TABLE_COLUMN_RESIZE = "EVENT_TABLE_COLUMN_RESIZE"; BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE = "EVENT_TABLE_AFTER_COLUMN_RESIZE"; BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE = "EVENT_TABLE_BEFORE_REGION_RESIZE"; BI.Table.EVENT_TABLE_REGION_RESIZE = "EVENT_TABLE_REGION_RESIZE"; BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE = "EVENT_TABLE_AFTER_REGION_RESIZE"; BI.shortcut("bi.table_view", BI.Table); /** * * 表格单元格 * * Created by GUY on 2016/1/12. * @class BI.ResizableTableCell * @extends BI.Widget */ BI.ResizableTableCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ResizableTableCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-resizable-table-cell", cell: {}, minSize: 15, // suitableSize, maxSize: Number.MAX_VALUE, start: BI.emptyFn, resize: BI.emptyFn, stop: BI.emptyFn }); }, _init: function () { BI.ResizableTableCell.superclass._init.apply(this, arguments); var self = this, o = this.options; this.cell = BI.createWidget(BI.extend({type: "bi.label"}, o.cell, {width: o.width, height: o.height})); var startDrag = false; var size = 0, offset = 0, defaultSize = o.width; function optimizeSize (s) { var optSize = BI.clamp(s, o.minSize, o.maxSize || Number.MAX_VALUE); // if (o.suitableSize) { // if (Math.abs(o.suitableSize - optSize) < 5) { // optSize = o.suitableSize; // self.handler.element.addClass("suitable"); // } else { // self.handler.element.removeClass("suitable"); // } // } return optSize; } var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { if (mouseMoveTracker.isDragging()) { startDrag = true; offset += deltaX; size = optimizeSize(defaultSize + offset); self.handler.element.addClass("dragging"); o.resize(size); } }, function () { if (startDrag === true) { size = optimizeSize(size); o.stop(size); size = 0; offset = 0; defaultSize = o.width; startDrag = false; } self.handler.element.removeClass("dragging"); self.handler.element.removeClass("suitable"); mouseMoveTracker.releaseMouseMoves(); }, document); this.handler = BI.createWidget({ type: "bi.absolute", cls: "resizable-table-cell-resizer-container", width: 6, items: [{ el: { type: "bi.layout", cls: "resizable-table-cell-resizer-knob", width: 4 }, right: 0, top: 0, bottom: 0 }] }); this.handler.element.on("mousedown", function (event) { defaultSize = o.width; optimizeSize(defaultSize); mouseMoveTracker.captureMouseMoves(event); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.cell, left: 0, right: 0, top: 0, bottom: 0 }, { el: this.handler, right: 0, top: 0, bottom: 0 }] }); }, setWidth: function (width) { BI.ResizableTableCell.superclass.setWidth.apply(this, arguments); var o = this.options; this.cell.setWidth(o.width); }, setHeight: function (height) { BI.ResizableTableCell.superclass.setHeight.apply(this, arguments); var o = this.options; this.cell.setHeight(o.height); } }); BI.shortcut("bi.resizable_table_cell", BI.ResizableTableCell);/** * * 可调整列宽的grid表格 * * Created by GUY on 2016/1/12. * @class BI.ResizableTable * @extends BI.Widget */ BI.ResizableTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ResizableTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-resizable-table", el: { type: "bi.grid_table" }, isNeedFreeze: false, isNeedResize: true, isResizeAdapt: false, headerRowSize: 25, rowSize: 25, isNeedMerge: true, // 是否需要合并单元格 mergeCols: [], mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], freezeCols: [], header: [], items: [], regionColumnSize: [] }); }, _init: function () { BI.ResizableTable.superclass._init.apply(this, arguments); var self = this, o = this.options; this.resizer = BI.createWidget({ type: "bi.layout", cls: "resizable-table-resizer", invisible: true, width: 2 }); this.regionResizerHandler = this._createResizerHandler(); this.table = BI.createWidget(o.el, { type: "bi.grid_table", element: this, width: o.width, height: o.height, headerRowSize: o.headerRowSize, rowSize: o.rowSize, columnSize: o.columnSize, isNeedFreeze: o.isNeedFreeze, freezeCols: o.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: o.mergeCols, mergeRule: BI.bind(this._mergeRule, this), header: this._formatHeader(o.header), items: o.items, regionColumnSize: o.regionColumnSize }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.regionResizerHandler, left: 0, top: 0, bottom: 0 }, { el: this.resizer, left: 0, top: 0 }] }); this._populate(); }, _mergeRule: function (row1, row2) { var o = this.options; if (row1.type === "bi.resizable_table_cell") { row1 = row1.cell; } if (row2.type === "bi.resizable_table_cell") { row2 = row2.cell; } return o.mergeRule(row1, row2); }, _createResizerHandler: function () { var self = this, o = this.options; var regionResizerHandler = BI.createWidget({ type: "bi.absolute", cls: "resizable-table-region-resizer", invisible: true, width: 6, items: [{ el: { type: "bi.layout", width: 2, cls: "resizable-table-region-resizer-knob" }, left: 2, top: 0, bottom: 0 }] }); var size = 0, offset = 0, defaultSize = 0, start = false; var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX, deltaY) { if (mouseMoveTracker.isDragging()) { start = true; offset += deltaX; size = BI.clamp(defaultSize + offset, 15, o.width - 15); self.regionResizerHandler.element.addClass("dragging"); self._setRegionResizerHandlerPosition(size - 3, 0); } }, function () { if (start === true) { o.regionColumnSize[0] = BI.clamp(size, 15, o.width - 15); self.table.setRegionColumnSize(o.regionColumnSize); if (o.isResizeAdapt === true) { var freezeColumnSize = self._getFreezeColumnSize(); o.columnSize[self._getFreezeColLength() - 1] += o.regionColumnSize[0] - freezeColumnSize; self.table.setColumnSize(o.columnSize); } // self.table.populate(); self._populate(); self.regionResizerHandler.element.removeClass("dragging"); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE); start = false; } mouseMoveTracker.releaseMouseMoves(); }, document); regionResizerHandler.element.on("mousedown", function (event) { defaultSize = size = self._getRegionSize(); offset = 0; self._setResizerPosition(0, 0); mouseMoveTracker.captureMouseMoves(event); }); return regionResizerHandler; }, _setResizerPosition: function (left, top) { this.resizer.element.css({ left: left + "px", top: top + "px" }); }, _setRegionResizerHandlerPosition: function (left, top) { this.regionResizerHandler.element.css({ left: left + "px", top: top + "px" }); }, _getRegionSize: function () { var o = this.options; var regionSize = o.regionColumnSize[0] || 0; if (o.isNeedFreeze === false || o.freezeCols.length === 0) { return 0; } if (!regionSize) { BI.each(o.freezeCols, function (i, col) { regionSize += o.columnSize[col]; }); } return regionSize; }, _getRegionRowSize: function () { var o = this.options; return [o.header.length * o.headerRowSize, Math.min(o.height - o.header.length * o.headerRowSize, o.items.length * o.rowSize)]; }, _getFreezeColLength: function () { var o = this.options; return o.isNeedFreeze === true ? BI.clamp(o.freezeCols.length, 0, o.columnSize.length) : 0; }, _getFreezeColumnSize: function () { var columnSize = this.options.columnSize; var sum = 0; for (var i = 0, len = this._getFreezeColLength(); i < len; i++) { sum += columnSize[i]; } return sum; }, _getResizerLeft: function (j) { var left = 0; var columnSize = this.options.columnSize; var freezeColLength = this._getFreezeColLength(); for (var i = (j >= freezeColLength ? freezeColLength : 0); i < j; i++) { left += columnSize[i] || 0; } if (j >= freezeColLength) { left += this.table.getRegionSize(); left -= this.table.getRightHorizontalScroll(); } else { left -= this.table.getLeftHorizontalScroll(); } return left; }, _formatHeader: function (header) { var self = this, o = this.options; var result = []; var resize = function (j, size) { self.resizer.setVisible(true); var height = o.headerRowSize + self._getRegionRowSize()[1]; self.resizer.setHeight(height); // TODO 不知道为什么加入这段代码会使得列宽调整出问题 // if (o.minColumnSize[j]) { // if (size === o.minColumnSize[j]) { // self.resizer.element.addClass("suitable"); // } else { // self.resizer.element.removeClass("suitable"); // } // } self._setResizerPosition(self._getResizerLeft(j) + size, (o.header.length - 1) * o.headerRowSize); }; var stop = function (j, size) { self.resizer.setVisible(false); var columnSize = o.columnSize.slice(); columnSize[j] = size; o.columnSize = columnSize; self.table.setColumnSize(columnSize); // self.table.populate(); self._populate(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE); }; BI.each(header, function (i, cols) { if (i === header.length - 1) { result[i] = []; BI.each(cols, function (j, col) { if (j === self._getFreezeColLength() - 1 || j === cols.length - 1) { result[i][j] = col; } else { result[i][j] = { type: "bi.resizable_table_cell", cell: col, suitableSize: o.minColumnSize[j], maxSize: o.maxColumnSize[j], resize: BI.bind(resize, null, j), stop: BI.bind(stop, null, j) }; if (o.isNeedMerge) { var r = i; while (r > 0 && self._mergeRule(result[r][j], result[r - 1][j])) { result[r - 1][j] = { type: "bi.resizable_table_cell", cell: result[r - 1][j], suitableSize: o.minColumnSize[j], maxSize: o.maxColumnSize[j], resize: BI.bind(resize, null, j), stop: BI.bind(stop, null, j) }; r--; } } } }); } else { result.push(cols); } }); return result; }, _populate: function () { var o = this.options; var regionSize = this._getRegionSize(); if (regionSize > 0) { this.regionResizerHandler.setVisible(true); this._setRegionResizerHandlerPosition(regionSize - 3, 0); } else { this.regionResizerHandler.setVisible(false); } }, setWidth: function (width) { BI.ResizableTable.superclass.setWidth.apply(this, arguments); this.table.setWidth(width); }, setHeight: function (height) { BI.ResizableTable.superclass.setHeight.apply(this, arguments); this.table.setHeight(height); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; this.table.setColumnSize(columnSize); }, getColumnSize: function () { return this.table.getColumnSize(); }, setRegionColumnSize: function (columnSize) { this.options.regionColumnSize = columnSize; this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, attr: function () { BI.ResizableTable.superclass.attr.apply(this, arguments); this.table.attr.apply(this.table, arguments); }, restore: function () { this.table.restore(); }, populate: function (items, header) { if (items) { this.options.items = items; } if (header) { this.options.header = header; if (this.options.isNeedResize) { header = this._formatHeader(header); } } this.table.populate(items, header); this._populate(); } }); BI.shortcut("bi.resizable_table", BI.ResizableTable);/** * * 自定义树 * * Created by GUY on 2015/9/7. * @class BI.CustomTree * @extends BI.Single */ BI.CustomTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CustomTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-custom-tree", expander: { el: {}, popup: { type: "bi.custom_tree" } }, items: [], itemsCreator: BI.emptyFn, el: { type: "bi.button_tree", chooseType: 0, layouts: [{ type: "bi.vertical" }] } }); }, _init: function () { BI.CustomTree.superclass._init.apply(this, arguments); this.initTree(this.options.items); }, _formatItems: function (nodes) { var self = this, o = this.options; nodes = BI.Tree.transformToTreeFormat(nodes); var items = []; BI.each(nodes, function (i, node) { if (BI.isNotEmptyArray(node.children) || node.isParent === true) { var item = BI.extend({ type: "bi.expander", el: {}, popup: {type: "bi.custom_tree"} }, BI.deepClone(o.expander), { id: node.id, pId: node.pId, value: node.value }); var el = BI.stripEL(node); if (!BI.isWidget(el)) { el = BI.clone(el); delete el.children; BI.extend(item.el, el); } else { item.el = el; } item.popup.expander = BI.deepClone(o.expander); item.items = item.popup.items = node.children; item.itemsCreator = item.popup.itemsCreator = function (op) { if (BI.isNotNull(op.node)) {// 从子节点传过来的itemsCreator直接向上传递 return o.itemsCreator.apply(self, arguments); } var args = Array.prototype.slice.call(arguments, 0); args[0].node = node; return o.itemsCreator.apply(self, args); }; BI.isNull(item.popup.el) && (item.popup.el = BI.deepClone(o.el)); items.push(item); } else { items.push(node); } }); return items; }, // 构造树结构, initTree: function (nodes) { var self = this, o = this.options; this.tree = BI.createWidget(o.el, { element: this, items: this._formatItems(nodes), itemsCreator: function (op, callback) { o.itemsCreator.apply(this, [op, function (items) { var args = Array.prototype.slice.call(arguments, 0); args[0] = self._formatItems(items); callback.apply(null, args); }]); } }); this.tree.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.CustomTree.EVENT_CHANGE, val, obj); } }); }, // 生成树方法 stroke: function (nodes) { this.populate.apply(this, arguments); }, populate: function (nodes) { var args = Array.prototype.slice.call(arguments, 0); if (arguments.length > 0) { args[0] = this._formatItems(nodes); } this.tree.populate.apply(this.tree, args); }, setValue: function (v) { this.tree && this.tree.setValue(v); }, getValue: function () { return this.tree ? this.tree.getValue() : []; }, getAllButtons: function () { return this.tree ? this.tree.getAllButtons() : []; }, getAllLeaves: function () { return this.tree ? this.tree.getAllLeaves() : []; }, getNodeById: function (id) { return this.tree && this.tree.getNodeById(id); }, getNodeByValue: function (id) { return this.tree && this.tree.getNodeByValue(id); }, empty: function () { this.tree.empty(); } }); BI.CustomTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.custom_tree", BI.CustomTree);/* * JQuery zTree core v3.5.18 * http://zTree.me/ * * Copyright (c) 2010 Hunter.z * * Licensed same as jquery - MIT License * http://www.opensource.org/licenses/mit-license.php * * email: hunter.z@263.net * Date: 2015-06-18 */ (function($){ var settings = {}, roots = {}, caches = {}, //default consts of core _consts = { className: { BUTTON: "button", LEVEL: "level", ICO_LOADING: "ico_loading", SWITCH: "switch" }, event: { NODECREATED: "ztree_nodeCreated", CLICK: "ztree_click", EXPAND: "ztree_expand", COLLAPSE: "ztree_collapse", ASYNC_SUCCESS: "ztree_async_success", ASYNC_ERROR: "ztree_async_error", REMOVE: "ztree_remove", SELECTED: "ztree_selected", UNSELECTED: "ztree_unselected" }, id: { A: "_a", ICON: "_ico", SPAN: "_span", SWITCH: "_switch", UL: "_ul" }, line: { ROOT: "root", ROOTS: "roots", CENTER: "center", BOTTOM: "bottom", NOLINE: "noline", LINE: "line" }, folder: { OPEN: "open", CLOSE: "close", DOCU: "docu" }, node: { CURSELECTED: "curSelectedNode" } }, //default setting of core _setting = { treeId: "", treeObj: null, view: { addDiyDom: null, autoCancelSelected: true, dblClickExpand: true, expandSpeed: "fast", fontCss: {}, nameIsHTML: false, selectedMulti: true, showIcon: true, showLine: true, showTitle: true, txtSelectedEnable: false }, data: { key: { children: "children", name: "name", title: "", url: "url" }, simpleData: { enable: false, idKey: "id", pIdKey: "pId", rootPId: null }, keep: { parent: false, leaf: false } }, async: { enable: false, contentType: "application/x-www-form-urlencoded", type: "post", dataType: "text", url: "", autoParam: [], otherParam: [], dataFilter: null }, callback: { beforeAsync:null, beforeClick:null, beforeDblClick:null, beforeRightClick:null, beforeMouseDown:null, beforeMouseUp:null, beforeExpand:null, beforeCollapse:null, beforeRemove:null, onAsyncError:null, onAsyncSuccess:null, onNodeCreated:null, onClick:null, onDblClick:null, onRightClick:null, onMouseDown:null, onMouseUp:null, onExpand:null, onCollapse:null, onRemove:null } }, //default root of core //zTree use root to save full data _initRoot = function (setting) { var r = data.getRoot(setting); if (!r) { r = {}; data.setRoot(setting, r); } r[setting.data.key.children] = []; r.expandTriggerFlag = false; r.curSelectedList = []; r.noSelection = true; r.createdNodes = []; r.zId = 0; r._ver = (new Date()).getTime(); }, //default cache of core _initCache = function(setting) { var c = data.getCache(setting); if (!c) { c = {}; data.setCache(setting, c); } c.nodes = []; c.doms = []; }, //default bindEvent of core _bindEvent = function(setting) { var o = setting.treeObj, c = consts.event; o.bind(c.NODECREATED, function (event, treeId, node) { tools.apply(setting.callback.onNodeCreated, [event, treeId, node]); }); o.bind(c.CLICK, function (event, srcEvent, treeId, node, clickFlag) { tools.apply(setting.callback.onClick, [srcEvent, treeId, node, clickFlag]); }); o.bind(c.EXPAND, function (event, treeId, node) { tools.apply(setting.callback.onExpand, [event, treeId, node]); }); o.bind(c.COLLAPSE, function (event, treeId, node) { tools.apply(setting.callback.onCollapse, [event, treeId, node]); }); o.bind(c.ASYNC_SUCCESS, function (event, treeId, node, msg) { tools.apply(setting.callback.onAsyncSuccess, [event, treeId, node, msg]); }); o.bind(c.ASYNC_ERROR, function (event, treeId, node, XMLHttpRequest, textStatus, errorThrown) { tools.apply(setting.callback.onAsyncError, [event, treeId, node, XMLHttpRequest, textStatus, errorThrown]); }); o.bind(c.REMOVE, function (event, treeId, treeNode) { tools.apply(setting.callback.onRemove, [event, treeId, treeNode]); }); o.bind(c.SELECTED, function (event, srcEvent, treeId, node) { tools.apply(setting.callback.onSelected, [srcEvent, treeId, node]); }); o.bind(c.UNSELECTED, function (event, srcEvent, treeId, node) { tools.apply(setting.callback.onUnSelected, [srcEvent, treeId, node]); }); }, _unbindEvent = function(setting) { var o = setting.treeObj, c = consts.event; o.unbind(c.NODECREATED) .unbind(c.CLICK) .unbind(c.EXPAND) .unbind(c.COLLAPSE) .unbind(c.ASYNC_SUCCESS) .unbind(c.ASYNC_ERROR) .unbind(c.REMOVE) .unbind(c.SELECTED) .unbind(c.UNSELECTED); }, //default event proxy of core _eventProxy = function(event) { var target = event.target, setting = data.getSetting(event.data.treeId), tId = "", node = null, nodeEventType = "", treeEventType = "", nodeEventCallback = null, treeEventCallback = null, tmp = null; if (tools.eqs(event.type, "mousedown")) { treeEventType = "mousedown"; } else if (tools.eqs(event.type, "mouseup")) { treeEventType = "mouseup"; } else if (tools.eqs(event.type, "contextmenu")) { treeEventType = "contextmenu"; } else if (tools.eqs(event.type, "click")) { if (tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.SWITCH) !== null) { tId = tools.getNodeMainDom(target).id; nodeEventType = "switchNode"; } else { tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); if (tmp) { tId = tools.getNodeMainDom(tmp).id; nodeEventType = "clickNode"; } } } else if (tools.eqs(event.type, "dblclick")) { treeEventType = "dblclick"; tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); if (tmp) { tId = tools.getNodeMainDom(tmp).id; nodeEventType = "switchNode"; } } if (treeEventType.length > 0 && tId.length == 0) { tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); if (tmp) {tId = tools.getNodeMainDom(tmp).id;} } // event to node if (tId.length>0) { node = data.getNodeCache(setting, tId); switch (nodeEventType) { case "switchNode" : if (!node.isParent) { nodeEventType = ""; } else if (tools.eqs(event.type, "click") || (tools.eqs(event.type, "dblclick") && tools.apply(setting.view.dblClickExpand, [setting.treeId, node], setting.view.dblClickExpand))) { nodeEventCallback = handler.onSwitchNode; } else { nodeEventType = ""; } break; case "clickNode" : nodeEventCallback = handler.onClickNode; break; } } // event to zTree switch (treeEventType) { case "mousedown" : treeEventCallback = handler.onZTreeMousedown; break; case "mouseup" : treeEventCallback = handler.onZTreeMouseup; break; case "dblclick" : treeEventCallback = handler.onZTreeDblclick; break; case "contextmenu" : treeEventCallback = handler.onZTreeContextmenu; break; } var proxyResult = { stop: false, node: node, nodeEventType: nodeEventType, nodeEventCallback: nodeEventCallback, treeEventType: treeEventType, treeEventCallback: treeEventCallback }; return proxyResult }, //default init node of core _initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { if (!n) return; var r = data.getRoot(setting), childKey = setting.data.key.children; n.level = level; n.tId = setting.treeId + "_" + (++r.zId); n.parentTId = parentNode ? parentNode.tId : null; n.open = (typeof n.open == "string") ? tools.eqs(n.open, "true") : !!n.open; if (n[childKey] && n[childKey].length > 0) { n.isParent = true; n.zAsync = true; } else { n.isParent = (typeof n.isParent == "string") ? tools.eqs(n.isParent, "true") : !!n.isParent; n.open = (n.isParent && !setting.async.enable) ? n.open : false; n.zAsync = !n.isParent; } n.isFirstNode = isFirstNode; n.isLastNode = isLastNode; n.getParentNode = function() {return data.getNodeCache(setting, n.parentTId);}; n.getPreNode = function() {return data.getPreNode(setting, n);}; n.getNextNode = function() {return data.getNextNode(setting, n);}; n.isAjaxing = false; data.fixPIdKeyValue(setting, n); }, _init = { bind: [_bindEvent], unbind: [_unbindEvent], caches: [_initCache], nodes: [_initNode], proxys: [_eventProxy], roots: [_initRoot], beforeA: [], afterA: [], innerBeforeA: [], innerAfterA: [], zTreeTools: [] }, //method of operate data data = { addNodeCache: function(setting, node) { data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = node; }, getNodeCacheId: function(tId) { return tId.substring(tId.lastIndexOf("_")+1); }, addAfterA: function(afterA) { _init.afterA.push(afterA); }, addBeforeA: function(beforeA) { _init.beforeA.push(beforeA); }, addInnerAfterA: function(innerAfterA) { _init.innerAfterA.push(innerAfterA); }, addInnerBeforeA: function(innerBeforeA) { _init.innerBeforeA.push(innerBeforeA); }, addInitBind: function(bindEvent) { _init.bind.push(bindEvent); }, addInitUnBind: function(unbindEvent) { _init.unbind.push(unbindEvent); }, addInitCache: function(initCache) { _init.caches.push(initCache); }, addInitNode: function(initNode) { _init.nodes.push(initNode); }, addInitProxy: function(initProxy, isFirst) { if (!!isFirst) { _init.proxys.splice(0,0,initProxy); } else { _init.proxys.push(initProxy); } }, addInitRoot: function(initRoot) { _init.roots.push(initRoot); }, addNodesData: function(setting, parentNode, nodes) { var childKey = setting.data.key.children; if (!parentNode[childKey]) parentNode[childKey] = []; if (parentNode[childKey].length > 0) { parentNode[childKey][parentNode[childKey].length - 1].isLastNode = false; view.setNodeLineIcos(setting, parentNode[childKey][parentNode[childKey].length - 1]); } parentNode.isParent = true; parentNode[childKey] = parentNode[childKey].concat(nodes); }, addSelectedNode: function(setting, node) { var root = data.getRoot(setting); if (!data.isSelectedNode(setting, node)) { root.curSelectedList.push(node); } }, addCreatedNode: function(setting, node) { if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { var root = data.getRoot(setting); root.createdNodes.push(node); } }, addZTreeTools: function(zTreeTools) { _init.zTreeTools.push(zTreeTools); }, exSetting: function(s) { $.extend(true, _setting, s); }, fixPIdKeyValue: function(setting, node) { if (setting.data.simpleData.enable) { node[setting.data.simpleData.pIdKey] = node.parentTId ? node.getParentNode()[setting.data.simpleData.idKey] : setting.data.simpleData.rootPId; } }, getAfterA: function(setting, node, array) { for (var i=0, j=_init.afterA.length; i<j; i++) { _init.afterA[i].apply(this, arguments); } }, getBeforeA: function(setting, node, array) { for (var i=0, j=_init.beforeA.length; i<j; i++) { _init.beforeA[i].apply(this, arguments); } }, getInnerAfterA: function(setting, node, array) { for (var i=0, j=_init.innerAfterA.length; i<j; i++) { _init.innerAfterA[i].apply(this, arguments); } }, getInnerBeforeA: function(setting, node, array) { for (var i=0, j=_init.innerBeforeA.length; i<j; i++) { _init.innerBeforeA[i].apply(this, arguments); } }, getCache: function(setting) { return caches[setting.treeId]; }, getNextNode: function(setting, node) { if (!node) return null; var childKey = setting.data.key.children, p = node.parentTId ? node.getParentNode() : data.getRoot(setting); for (var i=0, l=p[childKey].length-1; i<=l; i++) { if (p[childKey][i] === node) { return (i==l ? null : p[childKey][i+1]); } } return null; }, getNodeByParam: function(setting, nodes, key, value) { if (!nodes || !key) return null; var childKey = setting.data.key.children; for (var i = 0, l = nodes.length; i < l; i++) { if (nodes[i][key] == value) { return nodes[i]; } var tmp = data.getNodeByParam(setting, nodes[i][childKey], key, value); if (tmp) return tmp; } return null; }, getNodeCache: function(setting, tId) { if (!tId) return null; var n = caches[setting.treeId].nodes[data.getNodeCacheId(tId)]; return n ? n : null; }, getNodeName: function(setting, node) { var nameKey = setting.data.key.name; return "" + node[nameKey]; }, getNodeTitle: function(setting, node) { var t = setting.data.key.title === "" ? setting.data.key.name : setting.data.key.title; return "" + node[t]; }, getNodes: function(setting) { return data.getRoot(setting)[setting.data.key.children]; }, getNodesByParam: function(setting, nodes, key, value) { if (!nodes || !key) return []; var childKey = setting.data.key.children, result = []; for (var i = 0, l = nodes.length; i < l; i++) { if (nodes[i][key] == value) { result.push(nodes[i]); } result = result.concat(data.getNodesByParam(setting, nodes[i][childKey], key, value)); } return result; }, getNodesByParamFuzzy: function(setting, nodes, key, value) { if (!nodes || !key) return []; var childKey = setting.data.key.children, result = []; value = value.toLowerCase(); for (var i = 0, l = nodes.length; i < l; i++) { if (typeof nodes[i][key] == "string" && nodes[i][key].toLowerCase().indexOf(value)>-1) { result.push(nodes[i]); } result = result.concat(data.getNodesByParamFuzzy(setting, nodes[i][childKey], key, value)); } return result; }, getNodesByFilter: function(setting, nodes, filter, isSingle, invokeParam) { if (!nodes) return (isSingle ? null : []); var childKey = setting.data.key.children, result = isSingle ? null : []; for (var i = 0, l = nodes.length; i < l; i++) { if (tools.apply(filter, [nodes[i], invokeParam], false)) { if (isSingle) {return nodes[i];} result.push(nodes[i]); } var tmpResult = data.getNodesByFilter(setting, nodes[i][childKey], filter, isSingle, invokeParam); if (isSingle && !!tmpResult) {return tmpResult;} result = isSingle ? tmpResult : result.concat(tmpResult); } return result; }, getPreNode: function(setting, node) { if (!node) return null; var childKey = setting.data.key.children, p = node.parentTId ? node.getParentNode() : data.getRoot(setting); for (var i=0, l=p[childKey].length; i<l; i++) { if (p[childKey][i] === node) { return (i==0 ? null : p[childKey][i-1]); } } return null; }, getRoot: function(setting) { return setting ? roots[setting.treeId] : null; }, getRoots: function() { return roots; }, getSetting: function(treeId) { return settings[treeId]; }, getSettings: function() { return settings; }, getZTreeTools: function(treeId) { var r = this.getRoot(this.getSetting(treeId)); return r ? r.treeTools : null; }, initCache: function(setting) { for (var i=0, j=_init.caches.length; i<j; i++) { _init.caches[i].apply(this, arguments); } }, initNode: function(setting, level, node, parentNode, preNode, nextNode) { for (var i=0, j=_init.nodes.length; i<j; i++) { _init.nodes[i].apply(this, arguments); } }, initRoot: function(setting) { for (var i=0, j=_init.roots.length; i<j; i++) { _init.roots[i].apply(this, arguments); } }, isSelectedNode: function(setting, node) { var root = data.getRoot(setting); for (var i=0, j=root.curSelectedList.length; i<j; i++) { if(node === root.curSelectedList[i]) return true; } return false; }, removeNodeCache: function(setting, node) { var childKey = setting.data.key.children; if (node[childKey]) { for (var i=0, l=node[childKey].length; i<l; i++) { arguments.callee(setting, node[childKey][i]); } } data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = null; }, removeSelectedNode: function(setting, node) { var root = data.getRoot(setting); for (var i=0, j=root.curSelectedList.length; i<j; i++) { if(node === root.curSelectedList[i] || !data.getNodeCache(setting, root.curSelectedList[i].tId)) { root.curSelectedList.splice(i, 1); i--;j--; } } }, setCache: function(setting, cache) { caches[setting.treeId] = cache; }, setRoot: function(setting, root) { roots[setting.treeId] = root; }, setZTreeTools: function(setting, zTreeTools) { for (var i=0, j=_init.zTreeTools.length; i<j; i++) { _init.zTreeTools[i].apply(this, arguments); } }, transformToArrayFormat: function (setting, nodes) { if (!nodes) return []; var childKey = setting.data.key.children, r = []; if (tools.isArray(nodes)) { for (var i=0, l=nodes.length; i<l; i++) { r.push(nodes[i]); if (nodes[i][childKey]) r = r.concat(data.transformToArrayFormat(setting, nodes[i][childKey])); } } else { r.push(nodes); if (nodes[childKey]) r = r.concat(data.transformToArrayFormat(setting, nodes[childKey])); } return r; }, transformTozTreeFormat: function(setting, sNodes) { var i,l, key = setting.data.simpleData.idKey, parentKey = setting.data.simpleData.pIdKey, childKey = setting.data.key.children; if (!key || key=="" || !sNodes) return []; if (tools.isArray(sNodes)) { var r = []; var tmpMap = []; for (i=0, l=sNodes.length; i<l; i++) { tmpMap[sNodes[i][key]] = sNodes[i]; } for (i=0, l=sNodes.length; i<l; i++) { if (tmpMap[sNodes[i][parentKey]] && sNodes[i][key] != sNodes[i][parentKey]) { if (!tmpMap[sNodes[i][parentKey]][childKey]) tmpMap[sNodes[i][parentKey]][childKey] = []; tmpMap[sNodes[i][parentKey]][childKey].push(sNodes[i]); } else { r.push(sNodes[i]); } } return r; }else { return [sNodes]; } } }, //method of event proxy event = { bindEvent: function(setting) { for (var i=0, j=_init.bind.length; i<j; i++) { _init.bind[i].apply(this, arguments); } }, unbindEvent: function(setting) { for (var i=0, j=_init.unbind.length; i<j; i++) { _init.unbind[i].apply(this, arguments); } }, bindTree: function(setting) { var eventParam = { treeId: setting.treeId }, o = setting.treeObj; if (!setting.view.txtSelectedEnable) { // for can't select text o.bind('selectstart', function(e){ var node var n = e.originalEvent.srcElement.nodeName.toLowerCase(); return (n === "input" || n === "textarea" ); }).css({ "-moz-user-select":"-moz-none" }); } o.bind('click', eventParam, event.proxy); o.bind('dblclick', eventParam, event.proxy); o.bind('mouseover', eventParam, event.proxy); o.bind('mouseout', eventParam, event.proxy); o.bind('mousedown', eventParam, event.proxy); o.bind('mouseup', eventParam, event.proxy); o.bind('contextmenu', eventParam, event.proxy); }, unbindTree: function(setting) { var o = setting.treeObj; o.unbind('click', event.proxy) .unbind('dblclick', event.proxy) .unbind('mouseover', event.proxy) .unbind('mouseout', event.proxy) .unbind('mousedown', event.proxy) .unbind('mouseup', event.proxy) .unbind('contextmenu', event.proxy); }, doProxy: function(e) { var results = []; for (var i=0, j=_init.proxys.length; i<j; i++) { var proxyResult = _init.proxys[i].apply(this, arguments); results.push(proxyResult); if (proxyResult.stop) { break; } } return results; }, proxy: function(e) { var setting = data.getSetting(e.data.treeId); if (!tools.uCanDo(setting, e)) return true; var results = event.doProxy(e), r = true, x = false; for (var i=0, l=results.length; i<l; i++) { var proxyResult = results[i]; if (proxyResult.nodeEventCallback) { x = true; r = proxyResult.nodeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; } if (proxyResult.treeEventCallback) { x = true; r = proxyResult.treeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; } } return r; } }, //method of event handler handler = { onSwitchNode: function (event, node) { var setting = data.getSetting(event.data.treeId); if (node.open) { if (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false) return true; data.getRoot(setting).expandTriggerFlag = true; view.switchNode(setting, node); } else { if (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false) return true; data.getRoot(setting).expandTriggerFlag = true; view.switchNode(setting, node); } return true; }, onClickNode: function (event, node) { var setting = data.getSetting(event.data.treeId), clickFlag = ( (setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey)) && data.isSelectedNode(setting, node)) ? 0 : (setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey) && setting.view.selectedMulti) ? 2 : 1; if (tools.apply(setting.callback.beforeClick, [setting.treeId, node, clickFlag], true) == false) return true; if (clickFlag === 0) { view.cancelPreSelectedNode(setting, node); } else { view.selectNode(setting, node, clickFlag === 2); } setting.treeObj.trigger(consts.event.CLICK, [event, setting.treeId, node, clickFlag]); return true; }, onZTreeMousedown: function(event, node) { var setting = data.getSetting(event.data.treeId); if (tools.apply(setting.callback.beforeMouseDown, [setting.treeId, node], true)) { tools.apply(setting.callback.onMouseDown, [event, setting.treeId, node]); } return true; }, onZTreeMouseup: function(event, node) { var setting = data.getSetting(event.data.treeId); if (tools.apply(setting.callback.beforeMouseUp, [setting.treeId, node], true)) { tools.apply(setting.callback.onMouseUp, [event, setting.treeId, node]); } return true; }, onZTreeDblclick: function(event, node) { var setting = data.getSetting(event.data.treeId); if (tools.apply(setting.callback.beforeDblClick, [setting.treeId, node], true)) { tools.apply(setting.callback.onDblClick, [event, setting.treeId, node]); } return true; }, onZTreeContextmenu: function(event, node) { var setting = data.getSetting(event.data.treeId); if (tools.apply(setting.callback.beforeRightClick, [setting.treeId, node], true)) { tools.apply(setting.callback.onRightClick, [event, setting.treeId, node]); } return (typeof setting.callback.onRightClick) != "function"; } }, //method of tools for zTree tools = { apply: function(fun, param, defaultValue) { if ((typeof fun) == "function") { return fun.apply(zt, param?param:[]); } return defaultValue; }, canAsync: function(setting, node) { var childKey = setting.data.key.children; return (setting.async.enable && node && node.isParent && !(node.zAsync || (node[childKey] && node[childKey].length > 0))); }, clone: function (obj){ if (obj === null) return null; var o = tools.isArray(obj) ? [] : {}; for(var i in obj){ o[i] = (obj[i] instanceof Date) ? new Date(obj[i].getTime()) : (typeof obj[i] === "object" ? arguments.callee(obj[i]) : obj[i]); } return o; }, eqs: function(str1, str2) { return str1.toLowerCase() === str2.toLowerCase(); }, isArray: function(arr) { return Object.prototype.toString.apply(arr) === "[object Array]"; }, $: function(node, exp, setting) { if (!!exp && typeof exp != "string") { setting = exp; exp = ""; } if (typeof node == "string") { return $(node, setting ? setting.treeObj.get(0).ownerDocument : null); } else { return $("#" + node.tId + exp, setting ? setting.treeObj : null); } }, getMDom: function (setting, curDom, targetExpr) { if (!curDom) return null; while (curDom && curDom.id !== setting.treeId) { for (var i=0, l=targetExpr.length; curDom.tagName && i<l; i++) { if (tools.eqs(curDom.tagName, targetExpr[i].tagName) && curDom.getAttribute(targetExpr[i].attrName) !== null) { return curDom; } } curDom = curDom.parentNode; } return null; }, getNodeMainDom:function(target) { return ($(target).parent("li").get(0) || $(target).parentsUntil("li").parent().get(0)); }, isChildOrSelf: function(dom, parentId) { return ( $(dom).closest("#" + parentId).length> 0 ); }, uCanDo: function(setting, e) { return true; } }, //method of operate ztree dom view = { addNodes: function(setting, parentNode, newNodes, isSilent) { if (setting.data.keep.leaf && parentNode && !parentNode.isParent) { return; } if (!tools.isArray(newNodes)) { newNodes = [newNodes]; } if (setting.data.simpleData.enable) { newNodes = data.transformTozTreeFormat(setting, newNodes); } if (parentNode) { var target_switchObj = $$(parentNode, consts.id.SWITCH, setting), target_icoObj = $$(parentNode, consts.id.ICON, setting), target_ulObj = $$(parentNode, consts.id.UL, setting); if (!parentNode.open) { view.replaceSwitchClass(parentNode, target_switchObj, consts.folder.CLOSE); view.replaceIcoClass(parentNode, target_icoObj, consts.folder.CLOSE); parentNode.open = false; target_ulObj.css({ "display": "none" }); } data.addNodesData(setting, parentNode, newNodes); view.createNodes(setting, parentNode.level + 1, newNodes, parentNode); if (!isSilent) { view.expandCollapseParentNode(setting, parentNode, true); } } else { data.addNodesData(setting, data.getRoot(setting), newNodes); view.createNodes(setting, 0, newNodes, null); } }, appendNodes: function(setting, level, nodes, parentNode, initFlag, openFlag) { if (!nodes) return []; var html = [], childKey = setting.data.key.children; for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; if (initFlag) { var tmpPNode = (parentNode) ? parentNode: data.getRoot(setting), tmpPChild = tmpPNode[childKey], isFirstNode = ((tmpPChild.length == nodes.length) && (i == 0)), isLastNode = (i == (nodes.length - 1)); data.initNode(setting, level, node, parentNode, isFirstNode, isLastNode, openFlag); data.addNodeCache(setting, node); } var childHtml = []; if (node[childKey] && node[childKey].length > 0) { //make child html first, because checkType childHtml = view.appendNodes(setting, level + 1, node[childKey], node, initFlag, openFlag && node.open); } if (openFlag) { view.makeDOMNodeMainBefore(html, setting, node); view.makeDOMNodeLine(html, setting, node); data.getBeforeA(setting, node, html); view.makeDOMNodeNameBefore(html, setting, node); data.getInnerBeforeA(setting, node, html); view.makeDOMNodeIcon(html, setting, node); data.getInnerAfterA(setting, node, html); view.makeDOMNodeNameAfter(html, setting, node); data.getAfterA(setting, node, html); if (node.isParent && node.open) { view.makeUlHtml(setting, node, html, childHtml.join('')); } view.makeDOMNodeMainAfter(html, setting, node); data.addCreatedNode(setting, node); } } return html; }, appendParentULDom: function(setting, node) { var html = [], nObj = $$(node, setting); if (!nObj.get(0) && !!node.parentTId) { view.appendParentULDom(setting, node.getParentNode()); nObj = $$(node, setting); } var ulObj = $$(node, consts.id.UL, setting); if (ulObj.get(0)) { ulObj.remove(); } var childKey = setting.data.key.children, childHtml = view.appendNodes(setting, node.level+1, node[childKey], node, false, true); view.makeUlHtml(setting, node, html, childHtml.join('')); nObj.append(html.join('')); }, asyncNode: function(setting, node, isSilent, callback) { var i, l; if (node && !node.isParent) { tools.apply(callback); return false; } else if (node && node.isAjaxing) { return false; } else if (tools.apply(setting.callback.beforeAsync, [setting.treeId, node], true) == false) { tools.apply(callback); return false; } if (node) { node.isAjaxing = true; var icoObj = $$(node, consts.id.ICON, setting); icoObj.attr({"style":"", "class":consts.className.BUTTON + " " + consts.className.ICO_LOADING}); } var tmpParam = {}; for (i = 0, l = setting.async.autoParam.length; node && i < l; i++) { var pKey = setting.async.autoParam[i].split("="), spKey = pKey; if (pKey.length>1) { spKey = pKey[1]; pKey = pKey[0]; } tmpParam[spKey] = node[pKey]; } if (tools.isArray(setting.async.otherParam)) { for (i = 0, l = setting.async.otherParam.length; i < l; i += 2) { tmpParam[setting.async.otherParam[i]] = setting.async.otherParam[i + 1]; } } else { for (var p in setting.async.otherParam) { tmpParam[p] = setting.async.otherParam[p]; } } var _tmpV = data.getRoot(setting)._ver; $.ajax({ contentType: setting.async.contentType, cache: false, type: setting.async.type, url: tools.apply(setting.async.url, [setting.treeId, node], setting.async.url), data: tmpParam, dataType: setting.async.dataType, success: function(msg) { if (_tmpV != data.getRoot(setting)._ver) { return; } var newNodes = []; try { if (!msg || msg.length == 0) { newNodes = []; } else if (typeof msg == "string") { newNodes = eval("(" + msg + ")"); } else { newNodes = msg; } } catch(err) { newNodes = msg; } if (node) { node.isAjaxing = null; node.zAsync = true; } view.setNodeLineIcos(setting, node); if (newNodes && newNodes !== "") { newNodes = tools.apply(setting.async.dataFilter, [setting.treeId, node, newNodes], newNodes); view.addNodes(setting, node, !!newNodes ? tools.clone(newNodes) : [], !!isSilent); } else { view.addNodes(setting, node, [], !!isSilent); } setting.treeObj.trigger(consts.event.ASYNC_SUCCESS, [setting.treeId, node, msg]); tools.apply(callback); }, error: function(XMLHttpRequest, textStatus, errorThrown) { if (_tmpV != data.getRoot(setting)._ver) { return; } if (node) node.isAjaxing = null; view.setNodeLineIcos(setting, node); setting.treeObj.trigger(consts.event.ASYNC_ERROR, [setting.treeId, node, XMLHttpRequest, textStatus, errorThrown]); } }); return true; }, cancelPreSelectedNode: function (setting, node, excludeNode) { var list = data.getRoot(setting).curSelectedList, i, n; for (i=list.length-1; i>=0; i--) { n = list[i]; if (node === n || (!node && (!excludeNode || excludeNode !== n))) { $$(n, consts.id.A, setting).removeClass(consts.node.CURSELECTED); if (node) { data.removeSelectedNode(setting, node); setting.treeObj.trigger(consts.event.UNSELECTED, [event, setting.treeId, n]); break; } else { list.splice(i, 1); setting.treeObj.trigger(consts.event.UNSELECTED, [event, setting.treeId, n]); } } } }, createNodeCallback: function(setting) { if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { var root = data.getRoot(setting); while (root.createdNodes.length>0) { var node = root.createdNodes.shift(); tools.apply(setting.view.addDiyDom, [setting.treeId, node]); if (!!setting.callback.onNodeCreated) { setting.treeObj.trigger(consts.event.NODECREATED, [setting.treeId, node]); } } } }, createNodes: function(setting, level, nodes, parentNode) { if (!nodes || nodes.length == 0) return; var root = data.getRoot(setting), childKey = setting.data.key.children, openFlag = !parentNode || parentNode.open || !!$$(parentNode[childKey][0], setting).get(0); root.createdNodes = []; var zTreeHtml = view.appendNodes(setting, level, nodes, parentNode, true, openFlag); if (!parentNode) { setting.treeObj.append(zTreeHtml.join('')); } else { var ulObj = $$(parentNode, consts.id.UL, setting); if (ulObj.get(0)) { ulObj.append(zTreeHtml.join('')); } } view.createNodeCallback(setting); }, destroy: function(setting) { if (!setting) return; data.initCache(setting); data.initRoot(setting); event.unbindTree(setting); event.unbindEvent(setting); setting.treeObj.empty(); delete settings[setting.treeId]; }, expandCollapseNode: function(setting, node, expandFlag, animateFlag, callback) { var root = data.getRoot(setting), childKey = setting.data.key.children; if (!node) { tools.apply(callback, []); return; } if (root.expandTriggerFlag) { var _callback = callback; callback = function(){ if (_callback) _callback(); if (node.open) { setting.treeObj.trigger(consts.event.EXPAND, [setting.treeId, node]); } else { setting.treeObj.trigger(consts.event.COLLAPSE, [setting.treeId, node]); } }; root.expandTriggerFlag = false; } if (!node.open && node.isParent && ((!$$(node, consts.id.UL, setting).get(0)) || (node[childKey] && node[childKey].length>0 && !$$(node[childKey][0], setting).get(0)))) { view.appendParentULDom(setting, node); view.createNodeCallback(setting); } if (node.open == expandFlag) { tools.apply(callback, []); return; } var ulObj = $$(node, consts.id.UL, setting), switchObj = $$(node, consts.id.SWITCH, setting), icoObj = $$(node, consts.id.ICON, setting); if (node.isParent) { node.open = !node.open; if (node.iconOpen && node.iconClose) { icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); } if (node.open) { view.replaceSwitchClass(node, switchObj, consts.folder.OPEN); view.replaceIcoClass(node, icoObj, consts.folder.OPEN); if (animateFlag == false || setting.view.expandSpeed == "") { ulObj.show(); tools.apply(callback, []); } else { if (node[childKey] && node[childKey].length > 0) { ulObj.slideDown(setting.view.expandSpeed, callback); } else { ulObj.show(); tools.apply(callback, []); } } } else { view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE); view.replaceIcoClass(node, icoObj, consts.folder.CLOSE); if (animateFlag == false || setting.view.expandSpeed == "" || !(node[childKey] && node[childKey].length > 0)) { ulObj.hide(); tools.apply(callback, []); } else { ulObj.slideUp(setting.view.expandSpeed, callback); } } } else { tools.apply(callback, []); } }, expandCollapseParentNode: function(setting, node, expandFlag, animateFlag, callback) { if (!node) return; if (!node.parentTId) { view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); return; } else { view.expandCollapseNode(setting, node, expandFlag, animateFlag); } if (node.parentTId) { view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, animateFlag, callback); } }, expandCollapseSonNode: function(setting, node, expandFlag, animateFlag, callback) { var root = data.getRoot(setting), childKey = setting.data.key.children, treeNodes = (node) ? node[childKey]: root[childKey], selfAnimateSign = (node) ? false : animateFlag, expandTriggerFlag = data.getRoot(setting).expandTriggerFlag; data.getRoot(setting).expandTriggerFlag = false; if (treeNodes) { for (var i = 0, l = treeNodes.length; i < l; i++) { if (treeNodes[i]) view.expandCollapseSonNode(setting, treeNodes[i], expandFlag, selfAnimateSign); } } data.getRoot(setting).expandTriggerFlag = expandTriggerFlag; view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback ); }, isSelectedNode: function (setting, node) { if (!node) { return false; } var list = data.getRoot(setting).curSelectedList, i; for (i=list.length-1; i>=0; i--) { if (node === list[i]) { return true; } } return false; }, makeDOMNodeIcon: function(html, setting, node) { var nameStr = data.getNodeName(setting, node), name = setting.view.nameIsHTML ? nameStr : nameStr.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); html.push("<span id='", node.tId, consts.id.ICON, "' title='' treeNode", consts.id.ICON," class='", view.makeNodeIcoClass(setting, node), "' style='", view.makeNodeIcoStyle(setting, node), "'></span><span id='", node.tId, consts.id.SPAN, "'>",name,"</span>"); }, makeDOMNodeLine: function(html, setting, node) { html.push("<span id='", node.tId, consts.id.SWITCH, "' title='' class='", view.makeNodeLineClass(setting, node), "' treeNode", consts.id.SWITCH,"></span>"); }, makeDOMNodeMainAfter: function(html, setting, node) { html.push("</li>"); }, makeDOMNodeMainBefore: function(html, setting, node) { html.push("<li id='", node.tId, "' class='", consts.className.LEVEL, node.level,"' tabindex='0' hidefocus='true' treenode>"); }, makeDOMNodeNameAfter: function(html, setting, node) { html.push("</a>"); }, makeDOMNodeNameBefore: function(html, setting, node) { var title = data.getNodeTitle(setting, node), url = view.makeNodeUrl(setting, node), fontcss = view.makeNodeFontCss(setting, node), fontStyle = []; for (var f in fontcss) { fontStyle.push(f, ":", fontcss[f], ";"); } html.push("<a id='", node.tId, consts.id.A, "' class='", consts.className.LEVEL, node.level,"' treeNode", consts.id.A," onclick=\"", (node.click || ''), "\" ", ((url != null && url.length > 0) ? "href='" + url + "'" : ""), " target='",view.makeNodeTarget(node),"' style='", fontStyle.join(''), "'"); if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle) && title) {html.push("title='", title.replace(/'/g,"'").replace(/</g,'<').replace(/>/g,'>'),"'");} html.push(">"); }, makeNodeFontCss: function(setting, node) { var fontCss = tools.apply(setting.view.fontCss, [setting.treeId, node], setting.view.fontCss); return (fontCss && ((typeof fontCss) != "function")) ? fontCss : {}; }, makeNodeIcoClass: function(setting, node) { var icoCss = ["ico"]; if (!node.isAjaxing) { icoCss[0] = (node.iconSkin ? node.iconSkin + "_" : "") + icoCss[0]; if (node.isParent) { icoCss.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); } else { icoCss.push(consts.folder.DOCU); } } return consts.className.BUTTON + " " + icoCss.join('_'); }, makeNodeIcoStyle: function(setting, node) { var icoStyle = []; if (!node.isAjaxing) { var icon = (node.isParent && node.iconOpen && node.iconClose) ? (node.open ? node.iconOpen : node.iconClose) : node.icon; if (icon) icoStyle.push("background:url(", icon, ") 0 0 no-repeat;"); if (setting.view.showIcon == false || !tools.apply(setting.view.showIcon, [setting.treeId, node], true)) { icoStyle.push("width:0px;height:0px;"); } } return icoStyle.join(''); }, makeNodeLineClass: function(setting, node) { var lineClass = []; if (setting.view.showLine) { if (node.level == 0 && node.isFirstNode && node.isLastNode) { lineClass.push(consts.line.ROOT); } else if (node.level == 0 && node.isFirstNode) { lineClass.push(consts.line.ROOTS); } else if (node.isLastNode) { lineClass.push(consts.line.BOTTOM); } else { lineClass.push(consts.line.CENTER); } } else { lineClass.push(consts.line.NOLINE); } if (node.isParent) { lineClass.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); } else { lineClass.push(consts.folder.DOCU); } return view.makeNodeLineClassEx(node) + lineClass.join('_'); }, makeNodeLineClassEx: function(node) { return consts.className.BUTTON + " " + consts.className.LEVEL + node.level + " " + consts.className.SWITCH + " "; }, makeNodeTarget: function(node) { return (node.target || "_blank"); }, makeNodeUrl: function(setting, node) { var urlKey = setting.data.key.url; return node[urlKey] ? node[urlKey] : null; }, makeUlHtml: function(setting, node, html, content) { html.push("<ul id='", node.tId, consts.id.UL, "' class='", consts.className.LEVEL, node.level, " ", view.makeUlLineClass(setting, node), "' style='display:", (node.open ? "block": "none"),"'>"); html.push(content); html.push("</ul>"); }, makeUlLineClass: function(setting, node) { return ((setting.view.showLine && !node.isLastNode) ? consts.line.LINE : ""); }, removeChildNodes: function(setting, node) { if (!node) return; var childKey = setting.data.key.children, nodes = node[childKey]; if (!nodes) return; for (var i = 0, l = nodes.length; i < l; i++) { data.removeNodeCache(setting, nodes[i]); } data.removeSelectedNode(setting); delete node[childKey]; if (!setting.data.keep.parent) { node.isParent = false; node.open = false; var tmp_switchObj = $$(node, consts.id.SWITCH, setting), tmp_icoObj = $$(node, consts.id.ICON, setting); view.replaceSwitchClass(node, tmp_switchObj, consts.folder.DOCU); view.replaceIcoClass(node, tmp_icoObj, consts.folder.DOCU); $$(node, consts.id.UL, setting).remove(); } else { $$(node, consts.id.UL, setting).empty(); } }, setFirstNode: function(setting, parentNode) { var childKey = setting.data.key.children, childLength = parentNode[childKey].length; if ( childLength > 0) { parentNode[childKey][0].isFirstNode = true; } }, setLastNode: function(setting, parentNode) { var childKey = setting.data.key.children, childLength = parentNode[childKey].length; if ( childLength > 0) { parentNode[childKey][childLength - 1].isLastNode = true; } }, removeNode: function(setting, node) { var root = data.getRoot(setting), childKey = setting.data.key.children, parentNode = (node.parentTId) ? node.getParentNode() : root; node.isFirstNode = false; node.isLastNode = false; node.getPreNode = function() {return null;}; node.getNextNode = function() {return null;}; if (!data.getNodeCache(setting, node.tId)) { return; } $$(node, setting).remove(); data.removeNodeCache(setting, node); data.removeSelectedNode(setting, node); for (var i = 0, l = parentNode[childKey].length; i < l; i++) { if (parentNode[childKey][i].tId == node.tId) { parentNode[childKey].splice(i, 1); break; } } view.setFirstNode(setting, parentNode); view.setLastNode(setting, parentNode); var tmp_ulObj,tmp_switchObj,tmp_icoObj, childLength = parentNode[childKey].length; //repair nodes old parent if (!setting.data.keep.parent && childLength == 0) { //old parentNode has no child nodes parentNode.isParent = false; parentNode.open = false; tmp_ulObj = $$(parentNode, consts.id.UL, setting); tmp_switchObj = $$(parentNode, consts.id.SWITCH, setting); tmp_icoObj = $$(parentNode, consts.id.ICON, setting); view.replaceSwitchClass(parentNode, tmp_switchObj, consts.folder.DOCU); view.replaceIcoClass(parentNode, tmp_icoObj, consts.folder.DOCU); tmp_ulObj.css("display", "none"); } else if (setting.view.showLine && childLength > 0) { //old parentNode has child nodes var newLast = parentNode[childKey][childLength - 1]; tmp_ulObj = $$(newLast, consts.id.UL, setting); tmp_switchObj = $$(newLast, consts.id.SWITCH, setting); tmp_icoObj = $$(newLast, consts.id.ICON, setting); if (parentNode == root) { if (parentNode[childKey].length == 1) { //node was root, and ztree has only one root after move node view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.ROOT); } else { var tmp_first_switchObj = $$(parentNode[childKey][0], consts.id.SWITCH, setting); view.replaceSwitchClass(parentNode[childKey][0], tmp_first_switchObj, consts.line.ROOTS); view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); } } else { view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); } tmp_ulObj.removeClass(consts.line.LINE); } }, replaceIcoClass: function(node, obj, newName) { if (!obj || node.isAjaxing) return; var tmpName = obj.attr("class"); if (tmpName == undefined) return; var tmpList = tmpName.split("_"); switch (newName) { case consts.folder.OPEN: case consts.folder.CLOSE: case consts.folder.DOCU: tmpList[tmpList.length-1] = newName; break; } obj.attr("class", tmpList.join("_")); }, replaceSwitchClass: function(node, obj, newName) { if (!obj) return; var tmpName = obj.attr("class"); if (tmpName == undefined) return; var tmpList = tmpName.split("_"); switch (newName) { case consts.line.ROOT: case consts.line.ROOTS: case consts.line.CENTER: case consts.line.BOTTOM: case consts.line.NOLINE: tmpList[0] = view.makeNodeLineClassEx(node) + newName; break; case consts.folder.OPEN: case consts.folder.CLOSE: case consts.folder.DOCU: tmpList[1] = newName; break; } obj.attr("class", tmpList.join("_")); if (newName !== consts.folder.DOCU) { obj.removeAttr("disabled"); } else { obj.attr("disabled", "disabled"); } }, selectNode: function(setting, node, addFlag) { if (!addFlag) { view.cancelPreSelectedNode(setting, null, node); } $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED); data.addSelectedNode(setting, node); setting.treeObj.trigger(consts.event.SELECTED, [event, setting.treeId, node]); }, setNodeFontCss: function(setting, treeNode) { var aObj = $$(treeNode, consts.id.A, setting), fontCss = view.makeNodeFontCss(setting, treeNode); if (fontCss) { aObj.css(fontCss); } }, setNodeLineIcos: function(setting, node) { if (!node) return; var switchObj = $$(node, consts.id.SWITCH, setting), ulObj = $$(node, consts.id.UL, setting), icoObj = $$(node, consts.id.ICON, setting), ulLine = view.makeUlLineClass(setting, node); if (ulLine.length==0) { ulObj.removeClass(consts.line.LINE); } else { ulObj.addClass(ulLine); } switchObj.attr("class", view.makeNodeLineClass(setting, node)); if (node.isParent) { switchObj.removeAttr("disabled"); } else { switchObj.attr("disabled", "disabled"); } icoObj.removeAttr("style"); icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); icoObj.attr("class", view.makeNodeIcoClass(setting, node)); }, setNodeName: function(setting, node) { var title = data.getNodeTitle(setting, node), nObj = $$(node, consts.id.SPAN, setting); nObj.empty(); if (setting.view.nameIsHTML) { nObj.html(data.getNodeName(setting, node)); } else { nObj.text(data.getNodeName(setting, node)); } if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle)) { var aObj = $$(node, consts.id.A, setting); aObj.attr("title", !title ? "" : title); } }, setNodeTarget: function(setting, node) { var aObj = $$(node, consts.id.A, setting); aObj.attr("target", view.makeNodeTarget(node)); }, setNodeUrl: function(setting, node) { var aObj = $$(node, consts.id.A, setting), url = view.makeNodeUrl(setting, node); if (url == null || url.length == 0) { aObj.removeAttr("href"); } else { aObj.attr("href", url); } }, switchNode: function(setting, node) { if (node.open || !tools.canAsync(setting, node)) { view.expandCollapseNode(setting, node, !node.open); } else if (setting.async.enable) { if (!view.asyncNode(setting, node)) { view.expandCollapseNode(setting, node, !node.open); return; } } else if (node) { view.expandCollapseNode(setting, node, !node.open); } } }; // zTree defind $.fn.zTree = { consts : _consts, _z : { tools: tools, view: view, event: event, data: data }, getZTreeObj: function(treeId) { var o = data.getZTreeTools(treeId); return o ? o : null; }, destroy: function(treeId) { if (!!treeId && treeId.length > 0) { view.destroy(data.getSetting(treeId)); } else { for(var s in settings) { view.destroy(settings[s]); } } }, init: function(obj, zSetting, zNodes) { var setting = tools.clone(_setting); $.extend(true, setting, zSetting); setting.treeId = obj.attr("id"); setting.treeObj = obj; setting.treeObj.empty(); settings[setting.treeId] = setting; //For some older browser,(e.g., ie6) if(typeof document.body.style.maxHeight === "undefined") { setting.view.expandSpeed = ""; } data.initRoot(setting); var root = data.getRoot(setting), childKey = setting.data.key.children; zNodes = zNodes ? tools.clone(tools.isArray(zNodes)? zNodes : [zNodes]) : []; if (setting.data.simpleData.enable) { root[childKey] = data.transformTozTreeFormat(setting, zNodes); } else { root[childKey] = zNodes; } data.initCache(setting); event.unbindTree(setting); event.bindTree(setting); event.unbindEvent(setting); event.bindEvent(setting); var zTreeTools = { setting : setting, addNodes : function(parentNode, newNodes, isSilent) { if (!newNodes) return null; if (!parentNode) parentNode = null; if (parentNode && !parentNode.isParent && setting.data.keep.leaf) return null; var xNewNodes = tools.clone(tools.isArray(newNodes)? newNodes: [newNodes]); function addCallback() { view.addNodes(setting, parentNode, xNewNodes, (isSilent==true)); } if (tools.canAsync(setting, parentNode)) { view.asyncNode(setting, parentNode, isSilent, addCallback); } else { addCallback(); } return xNewNodes; }, cancelSelectedNode : function(node) { view.cancelPreSelectedNode(setting, node); }, destroy : function() { view.destroy(setting); }, expandAll : function(expandFlag) { expandFlag = !!expandFlag; view.expandCollapseSonNode(setting, null, expandFlag, true); return expandFlag; }, expandNode : function(node, expandFlag, sonSign, focus, callbackFlag) { if (!node || !node.isParent) return null; if (expandFlag !== true && expandFlag !== false) { expandFlag = !node.open; } callbackFlag = !!callbackFlag; if (callbackFlag && expandFlag && (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false)) { return null; } else if (callbackFlag && !expandFlag && (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false)) { return null; } if (expandFlag && node.parentTId) { view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, false); } if (expandFlag === node.open && !sonSign) { return null; } data.getRoot(setting).expandTriggerFlag = callbackFlag; if (!tools.canAsync(setting, node) && sonSign) { view.expandCollapseSonNode(setting, node, expandFlag, true, function() { if (focus !== false) {try{$$(node, setting).focus().blur();}catch(e){}} }); } else { node.open = !expandFlag; view.switchNode(this.setting, node); if (focus !== false) {try{$$(node, setting).focus().blur();}catch(e){}} } return expandFlag; }, getNodes : function() { return data.getNodes(setting); }, getNodeByParam : function(key, value, parentNode) { if (!key) return null; return data.getNodeByParam(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), key, value); }, getNodeByTId : function(tId) { return data.getNodeCache(setting, tId); }, getNodesByParam : function(key, value, parentNode) { if (!key) return null; return data.getNodesByParam(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), key, value); }, getNodesByParamFuzzy : function(key, value, parentNode) { if (!key) return null; return data.getNodesByParamFuzzy(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), key, value); }, getNodesByFilter: function(filter, isSingle, parentNode, invokeParam) { isSingle = !!isSingle; if (!filter || (typeof filter != "function")) return (isSingle ? null : []); return data.getNodesByFilter(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), filter, isSingle, invokeParam); }, getNodeIndex : function(node) { if (!node) return null; var childKey = setting.data.key.children, parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); for (var i=0, l = parentNode[childKey].length; i < l; i++) { if (parentNode[childKey][i] == node) return i; } return -1; }, getSelectedNodes : function() { var r = [], list = data.getRoot(setting).curSelectedList; for (var i=0, l=list.length; i<l; i++) { r.push(list[i]); } return r; }, isSelectedNode : function(node) { return data.isSelectedNode(setting, node); }, reAsyncChildNodes : function(parentNode, reloadType, isSilent) { if (!this.setting.async.enable) return; var isRoot = !parentNode; if (isRoot) { parentNode = data.getRoot(setting); } if (reloadType=="refresh") { var childKey = this.setting.data.key.children; for (var i = 0, l = parentNode[childKey] ? parentNode[childKey].length : 0; i < l; i++) { data.removeNodeCache(setting, parentNode[childKey][i]); } data.removeSelectedNode(setting); parentNode[childKey] = []; if (isRoot) { this.setting.treeObj.empty(); } else { var ulObj = $$(parentNode, consts.id.UL, setting); ulObj.empty(); } } view.asyncNode(this.setting, isRoot? null:parentNode, !!isSilent); }, refresh : function() { this.setting.treeObj.empty(); var root = data.getRoot(setting), nodes = root[setting.data.key.children] data.initRoot(setting); root[setting.data.key.children] = nodes data.initCache(setting); view.createNodes(setting, 0, root[setting.data.key.children]); }, removeChildNodes : function(node) { if (!node) return null; var childKey = setting.data.key.children, nodes = node[childKey]; view.removeChildNodes(setting, node); return nodes ? nodes : null; }, removeNode : function(node, callbackFlag) { if (!node) return; callbackFlag = !!callbackFlag; if (callbackFlag && tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return; view.removeNode(setting, node); if (callbackFlag) { this.setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]); } }, selectNode : function(node, addFlag) { if (!node) return; if (tools.uCanDo(setting)) { addFlag = setting.view.selectedMulti && addFlag; if (node.parentTId) { view.expandCollapseParentNode(setting, node.getParentNode(), true, false, function() { try{$$(node, setting).focus().blur();}catch(e){} }); } else { try{$$(node, setting).focus().blur();}catch(e){} } view.selectNode(setting, node, addFlag); } }, transformTozTreeNodes : function(simpleNodes) { return data.transformTozTreeFormat(setting, simpleNodes); }, transformToArray : function(nodes) { return data.transformToArrayFormat(setting, nodes); }, updateNode : function(node, checkTypeFlag) { if (!node) return; var nObj = $$(node, setting); if (nObj.get(0) && tools.uCanDo(setting)) { view.setNodeName(setting, node); view.setNodeTarget(setting, node); view.setNodeUrl(setting, node); view.setNodeLineIcos(setting, node); view.setNodeFontCss(setting, node); } } } root.treeTools = zTreeTools; data.setZTreeTools(setting, zTreeTools); if (root[childKey] && root[childKey].length > 0) { view.createNodes(setting, 0, root[childKey]); } else if (setting.async.enable && setting.async.url && setting.async.url !== '') { view.asyncNode(setting); } return zTreeTools; } }; var zt = $.fn.zTree, $$ = tools.$, consts = zt.consts; })(jQuery);/* * JQuery zTree excheck v3.5.18 * http://zTree.me/ * * Copyright (c) 2010 Hunter.z * * Licensed same as jquery - MIT License * http://www.opensource.org/licenses/mit-license.php * * email: hunter.z@263.net * Date: 2015-06-18 */ (function($){ //default consts of excheck var _consts = { event: { CHECK: "ztree_check" }, id: { CHECK: "_check" }, checkbox: { STYLE: "checkbox", DEFAULT: "chk", DISABLED: "disable", FALSE: "false", TRUE: "true", FULL: "full", PART: "part", FOCUS: "focus" }, radio: { STYLE: "radio", TYPE_ALL: "all", TYPE_LEVEL: "level" } }, //default setting of excheck _setting = { check: { enable: false, autoCheckTrigger: false, chkStyle: _consts.checkbox.STYLE, nocheckInherit: false, chkDisabledInherit: false, radioType: _consts.radio.TYPE_LEVEL, chkboxType: { "Y": "ps", "N": "ps" } }, data: { key: { checked: "checked" } }, callback: { beforeCheck:null, onCheck:null } }, //default root of excheck _initRoot = function (setting) { var r = data.getRoot(setting); r.radioCheckedList = []; }, //default cache of excheck _initCache = function(treeId) {}, //default bind event of excheck _bindEvent = function(setting) { var o = setting.treeObj, c = consts.event; o.bind(c.CHECK, function (event, srcEvent, treeId, node) { event.srcEvent = srcEvent; tools.apply(setting.callback.onCheck, [event, treeId, node]); }); }, _unbindEvent = function(setting) { var o = setting.treeObj, c = consts.event; o.unbind(c.CHECK); }, //default event proxy of excheck _eventProxy = function(e) { var target = e.target, setting = data.getSetting(e.data.treeId), tId = "", node = null, nodeEventType = "", treeEventType = "", nodeEventCallback = null, treeEventCallback = null; if (tools.eqs(e.type, "mouseover")) { if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { tId = tools.getNodeMainDom(target).id; nodeEventType = "mouseoverCheck"; } } else if (tools.eqs(e.type, "mouseout")) { if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { tId = tools.getNodeMainDom(target).id; nodeEventType = "mouseoutCheck"; } } else if (tools.eqs(e.type, "click")) { if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { tId = tools.getNodeMainDom(target).id; nodeEventType = "checkNode"; } } if (tId.length>0) { node = data.getNodeCache(setting, tId); switch (nodeEventType) { case "checkNode" : nodeEventCallback = _handler.onCheckNode; break; case "mouseoverCheck" : nodeEventCallback = _handler.onMouseoverCheck; break; case "mouseoutCheck" : nodeEventCallback = _handler.onMouseoutCheck; break; } } var proxyResult = { stop: nodeEventType === "checkNode", node: node, nodeEventType: nodeEventType, nodeEventCallback: nodeEventCallback, treeEventType: treeEventType, treeEventCallback: treeEventCallback }; return proxyResult }, //default init node of excheck _initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { if (!n) return; var checkedKey = setting.data.key.checked; if (typeof n[checkedKey] == "string") n[checkedKey] = tools.eqs(n[checkedKey], "true"); n[checkedKey] = !!n[checkedKey]; n.checkedOld = n[checkedKey]; if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true"); n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck); if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true"); n.chkDisabled = !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled); if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true"); n.halfCheck = !!n.halfCheck; n.check_Child_State = -1; n.check_Focus = false; n.getCheckStatus = function() {return data.getCheckStatus(setting, n);}; if (setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL && n[checkedKey] ) { var r = data.getRoot(setting); r.radioCheckedList.push(n); } }, //add dom for check _beforeA = function(setting, node, html) { var checkedKey = setting.data.key.checked; if (setting.check.enable) { data.makeChkFlag(setting, node); html.push("<span ID='", node.tId, consts.id.CHECK, "' class='", view.makeChkClass(setting, node), "' treeNode", consts.id.CHECK, (node.nocheck === true?" style='display:none;'":""),"></span>"); } }, //update zTreeObj, add method of check _zTreeTools = function(setting, zTreeTools) { zTreeTools.checkNode = function(node, checked, checkTypeFlag, callbackFlag) { var checkedKey = this.setting.data.key.checked; if (node.chkDisabled === true) return; if (checked !== true && checked !== false) { checked = !node[checkedKey]; } callbackFlag = !!callbackFlag; if (node[checkedKey] === checked && !checkTypeFlag) { return; } else if (callbackFlag && tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false) { return; } if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) { node[checkedKey] = checked; var checkObj = $$(node, consts.id.CHECK, this.setting); if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node); view.setChkClass(this.setting, checkObj, node); view.repairParentChkClassWithSelf(this.setting, node); if (callbackFlag) { this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]); } } } zTreeTools.checkAllNodes = function(checked) { view.repairAllChk(this.setting, !!checked); } zTreeTools.getCheckedNodes = function(checked) { var childKey = this.setting.data.key.children; checked = (checked !== false); return data.getTreeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey], checked); } zTreeTools.getChangeCheckedNodes = function() { var childKey = this.setting.data.key.children; return data.getTreeChangeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey]); } zTreeTools.setChkDisabled = function(node, disabled, inheritParent, inheritChildren) { disabled = !!disabled; inheritParent = !!inheritParent; inheritChildren = !!inheritChildren; view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren); view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent); } var _updateNode = zTreeTools.updateNode; zTreeTools.updateNode = function(node, checkTypeFlag) { if (_updateNode) _updateNode.apply(zTreeTools, arguments); if (!node || !this.setting.check.enable) return; var nObj = $$(node, this.setting); if (nObj.get(0) && tools.uCanDo(this.setting)) { var checkObj = $$(node, consts.id.CHECK, this.setting); if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node); view.setChkClass(this.setting, checkObj, node); view.repairParentChkClassWithSelf(this.setting, node); } } }, //method of operate data _data = { getRadioCheckedList: function(setting) { var checkedList = data.getRoot(setting).radioCheckedList; for (var i=0, j=checkedList.length; i<j; i++) { if(!data.getNodeCache(setting, checkedList[i].tId)) { checkedList.splice(i, 1); i--; j--; } } return checkedList; }, getCheckStatus: function(setting, node) { if (!setting.check.enable || node.nocheck || node.chkDisabled) return null; var checkedKey = setting.data.key.checked, r = { checked: node[checkedKey], half: node.halfCheck ? node.halfCheck : (setting.check.chkStyle == consts.radio.STYLE ? (node.check_Child_State === 2) : (node[checkedKey] ? (node.check_Child_State > -1 && node.check_Child_State < 2) : (node.check_Child_State > 0))) }; return r; }, getTreeCheckedNodes: function(setting, nodes, checked, results) { if (!nodes) return []; var childKey = setting.data.key.children, checkedKey = setting.data.key.checked, onlyOne = (checked && setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL); results = !results ? [] : results; for (var i = 0, l = nodes.length; i < l; i++) { if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] == checked) { results.push(nodes[i]); if(onlyOne) { break; } } data.getTreeCheckedNodes(setting, nodes[i][childKey], checked, results); if(onlyOne && results.length > 0) { break; } } return results; }, getTreeChangeCheckedNodes: function(setting, nodes, results) { if (!nodes) return []; var childKey = setting.data.key.children, checkedKey = setting.data.key.checked; results = !results ? [] : results; for (var i = 0, l = nodes.length; i < l; i++) { if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] != nodes[i].checkedOld) { results.push(nodes[i]); } data.getTreeChangeCheckedNodes(setting, nodes[i][childKey], results); } return results; }, makeChkFlag: function(setting, node) { if (!node) return; var childKey = setting.data.key.children, checkedKey = setting.data.key.checked, chkFlag = -1; if (node[childKey]) { for (var i = 0, l = node[childKey].length; i < l; i++) { var cNode = node[childKey][i]; var tmp = -1; if (setting.check.chkStyle == consts.radio.STYLE) { if (cNode.nocheck === true || cNode.chkDisabled === true) { tmp = cNode.check_Child_State; } else if (cNode.halfCheck === true) { tmp = 2; } else if (cNode[checkedKey]) { tmp = 2; } else { tmp = cNode.check_Child_State > 0 ? 2:0; } if (tmp == 2) { chkFlag = 2; break; } else if (tmp == 0){ chkFlag = 0; } } else if (setting.check.chkStyle == consts.checkbox.STYLE) { if (cNode.nocheck === true || cNode.chkDisabled === true) { tmp = cNode.check_Child_State; } else if (cNode.halfCheck === true) { tmp = 1; } else if (cNode[checkedKey] ) { tmp = (cNode.check_Child_State === -1 || cNode.check_Child_State === 2) ? 2 : 1; } else { tmp = (cNode.check_Child_State > 0) ? 1 : 0; } if (tmp === 1) { chkFlag = 1; break; } else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) { chkFlag = 1; break; } else if (chkFlag === 2 && tmp > -1 && tmp < 2) { chkFlag = 1; break; } else if (tmp > -1) { chkFlag = tmp; } } } } node.check_Child_State = chkFlag; } }, //method of event proxy _event = { }, //method of event handler _handler = { onCheckNode: function (event, node) { if (node.chkDisabled === true) return false; var setting = data.getSetting(event.data.treeId), checkedKey = setting.data.key.checked; if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true; node[checkedKey] = !node[checkedKey]; view.checkNodeRelation(setting, node); var checkObj = $$(node, consts.id.CHECK, setting); view.setChkClass(setting, checkObj, node); view.repairParentChkClassWithSelf(setting, node); setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]); return true; }, onMouseoverCheck: function(event, node) { if (node.chkDisabled === true) return false; var setting = data.getSetting(event.data.treeId), checkObj = $$(node, consts.id.CHECK, setting); node.check_Focus = true; view.setChkClass(setting, checkObj, node); return true; }, onMouseoutCheck: function(event, node) { if (node.chkDisabled === true) return false; var setting = data.getSetting(event.data.treeId), checkObj = $$(node, consts.id.CHECK, setting); node.check_Focus = false; view.setChkClass(setting, checkObj, node); return true; } }, //method of tools for zTree _tools = { }, //method of operate ztree dom _view = { checkNodeRelation: function(setting, node) { var pNode, i, l, childKey = setting.data.key.children, checkedKey = setting.data.key.checked, r = consts.radio; if (setting.check.chkStyle == r.STYLE) { var checkedList = data.getRadioCheckedList(setting); if (node[checkedKey]) { if (setting.check.radioType == r.TYPE_ALL) { for (i = checkedList.length-1; i >= 0; i--) { pNode = checkedList[i]; if (pNode[checkedKey] && pNode != node) { pNode[checkedKey] = false; checkedList.splice(i, 1); view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); if (pNode.parentTId != node.parentTId) { view.repairParentChkClassWithSelf(setting, pNode); } } } checkedList.push(node); } else { var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); for (i = 0, l = parentNode[childKey].length; i < l; i++) { pNode = parentNode[childKey][i]; if (pNode[checkedKey] && pNode != node) { pNode[checkedKey] = false; view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); } } } } else if (setting.check.radioType == r.TYPE_ALL) { for (i = 0, l = checkedList.length; i < l; i++) { if (node == checkedList[i]) { checkedList.splice(i, 1); break; } } } } else { if (node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.Y.indexOf("s") > -1)) { view.setSonNodeCheckBox(setting, node, true); } if (!node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.N.indexOf("s") > -1)) { view.setSonNodeCheckBox(setting, node, false); } if (node[checkedKey] && setting.check.chkboxType.Y.indexOf("p") > -1) { view.setParentNodeCheckBox(setting, node, true); } if (!node[checkedKey] && setting.check.chkboxType.N.indexOf("p") > -1) { view.setParentNodeCheckBox(setting, node, false); } } }, makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; } else if (node.halfCheck) { fullStyle = c.PART; } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; return consts.className.BUTTON + " " + c.DEFAULT + " " + chkName; }, repairAllChk: function(setting, checked) { if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) { var checkedKey = setting.data.key.checked, childKey = setting.data.key.children, root = data.getRoot(setting); for (var i = 0, l = root[childKey].length; i<l ; i++) { var node = root[childKey][i]; if (node.nocheck !== true && node.chkDisabled !== true) { node[checkedKey] = checked; } view.setSonNodeCheckBox(setting, node, checked); } } }, repairChkClass: function(setting, node) { if (!node) return; data.makeChkFlag(setting, node); if (node.nocheck !== true) { var checkObj = $$(node, consts.id.CHECK, setting); view.setChkClass(setting, checkObj, node); } }, repairParentChkClass: function(setting, node) { if (!node || !node.parentTId) return; var pNode = node.getParentNode(); view.repairChkClass(setting, pNode); view.repairParentChkClass(setting, pNode); }, repairParentChkClassWithSelf: function(setting, node) { if (!node) return; var childKey = setting.data.key.children; if (node[childKey] && node[childKey].length > 0) { view.repairParentChkClass(setting, node[childKey][0]); } else { view.repairParentChkClass(setting, node); } }, repairSonChkDisabled: function(setting, node, chkDisabled, inherit) { if (!node) return; var childKey = setting.data.key.children; if (node.chkDisabled != chkDisabled) { node.chkDisabled = chkDisabled; } view.repairChkClass(setting, node); if (node[childKey] && inherit) { for (var i = 0, l = node[childKey].length; i < l; i++) { var sNode = node[childKey][i]; view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit); } } }, repairParentChkDisabled: function(setting, node, chkDisabled, inherit) { if (!node) return; if (node.chkDisabled != chkDisabled && inherit) { node.chkDisabled = chkDisabled; } view.repairChkClass(setting, node); view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit); }, setChkClass: function(setting, obj, node) { if (!obj) return; if (node.nocheck === true) { obj.hide(); } else { obj.show(); } obj.attr('class', view.makeChkClass(setting, node)); }, setParentNodeCheckBox: function(setting, node, value, srcNode) { var childKey = setting.data.key.children, checkedKey = setting.data.key.checked, checkObj = $$(node, consts.id.CHECK, setting); if (!srcNode) srcNode = node; data.makeChkFlag(setting, node); if (node.nocheck !== true && node.chkDisabled !== true) { node[checkedKey] = value; view.setChkClass(setting, checkObj, node); if (setting.check.autoCheckTrigger && node != srcNode) { setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); } } if (node.parentTId) { var pSign = true; if (!value) { var pNodes = node.getParentNode()[childKey]; for (var i = 0, l = pNodes.length; i < l; i++) { if ((pNodes[i].nocheck !== true && pNodes[i].chkDisabled !== true && pNodes[i][checkedKey]) || ((pNodes[i].nocheck === true || pNodes[i].chkDisabled === true) && pNodes[i].check_Child_State > 0)) { pSign = false; break; } } } if (pSign) { view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode); } } }, setSonNodeCheckBox: function(setting, node, value, srcNode) { if (!node) return; var childKey = setting.data.key.children, checkedKey = setting.data.key.checked, checkObj = $$(node, consts.id.CHECK, setting); if (!srcNode) srcNode = node; var hasDisable = false; if (node[childKey]) { for (var i = 0, l = node[childKey].length; i < l && node.chkDisabled !== true; i++) { var sNode = node[childKey][i]; view.setSonNodeCheckBox(setting, sNode, value, srcNode); if (sNode.chkDisabled === true) hasDisable = true; } } if (node != data.getRoot(setting) && node.chkDisabled !== true) { if (hasDisable && node.nocheck !== true) { data.makeChkFlag(setting, node); } if (node.nocheck !== true && node.chkDisabled !== true) { node[checkedKey] = value; if (!hasDisable) node.check_Child_State = (node[childKey] && node[childKey].length > 0) ? (value ? 2 : 0) : -1; } else { node.check_Child_State = -1; } view.setChkClass(setting, checkObj, node); if (setting.check.autoCheckTrigger && node != srcNode && node.nocheck !== true && node.chkDisabled !== true) { setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); } } } }, _z = { tools: _tools, view: _view, event: _event, data: _data }; $.extend(true, $.fn.zTree.consts, _consts); $.extend(true, $.fn.zTree._z, _z); var zt = $.fn.zTree, tools = zt._z.tools, consts = zt.consts, view = zt._z.view, data = zt._z.data, event = zt._z.event, $$ = tools.$; data.exSetting(_setting); data.addInitBind(_bindEvent); data.addInitUnBind(_unbindEvent); data.addInitCache(_initCache); data.addInitNode(_initNode); data.addInitProxy(_eventProxy, true); data.addInitRoot(_initRoot); data.addBeforeA(_beforeA); data.addZTreeTools(_zTreeTools); var _createNodes = view.createNodes; view.createNodes = function(setting, level, nodes, parentNode) { if (_createNodes) _createNodes.apply(view, arguments); if (!nodes) return; view.repairParentChkClassWithSelf(setting, parentNode); } var _removeNode = view.removeNode; view.removeNode = function(setting, node) { var parentNode = node.getParentNode(); if (_removeNode) _removeNode.apply(view, arguments); if (!node || !parentNode) return; view.repairChkClass(setting, parentNode); view.repairParentChkClass(setting, parentNode); } var _appendNodes = view.appendNodes; view.appendNodes = function(setting, level, nodes, parentNode, initFlag, openFlag) { var html = ""; if (_appendNodes) { html = _appendNodes.apply(view, arguments); } if (parentNode) { data.makeChkFlag(setting, parentNode); } return html; } })(jQuery);/** * 可以改变图标的button * * Created by GUY on 2016/2/2. * * @class BI.IconChangeButton * @extends BI.Single */ BI.IconChangeButton = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.IconChangeButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-icon-change-button", iconClass: "", iconWidth: null, iconHeight: null, stopEvent: false, stopPropagation: false, selected: false, once: false, // 点击一次选中有效,再点无效 forceSelected: false, // 点击即选中, 选中了就不会被取消 forceNotSelected: false, // 无论怎么点击都不会被选中 disableSelected: false, // 使能选中 shadow: false, isShadowShowingOnSelected: false, // 选中状态下是否显示阴影 trigger: null, handler: BI.emptyFn }); }, _init: function () { BI.IconChangeButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.button = BI.createWidget({ type: "bi.icon_button", element: this, cls: o.iconClass, height: o.height, iconWidth: o.iconWidth, iconHeight: o.iconHeight, stopEvent: o.stopEvent, stopPropagation: o.stopPropagation, selected: o.selected, once: o.once, forceSelected: o.forceSelected, forceNotSelected: o.forceNotSelected, disableSelected: o.disableSelected, shadow: o.shadow, isShadowShowingOnSelected: o.isShadowShowingOnSelected, trigger: o.trigger, handler: o.handler }); this.button.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button.on(BI.IconButton.EVENT_CHANGE, function () { self.fireEvent(BI.IconChangeButton.EVENT_CHANGE, arguments); }); }, isSelected: function () { return this.button.isSelected(); }, setSelected: function (b) { this.button.setSelected(b); }, setIcon: function (cls) { var o = this.options; if (o.iconClass !== cls) { this.element.removeClass(o.iconClass).addClass(cls); o.iconClass = cls; } } }); BI.IconChangeButton.EVENT_CHANGE = "IconChangeButton.EVENT_CHANGE"; BI.shortcut("bi.icon_change_button", BI.IconChangeButton);/** * guy * @extends BI.Single * @type {*|void|Object} */ BI.HalfIconButton = BI.inherit(BI.IconButton, { _defaultConfig: function () { var conf = BI.HalfIconButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-half-icon-button check-half-select-icon", height: 16, width: 16, iconWidth: 16, iconHeight: 16, selected: false }); }, _init: function () { BI.HalfIconButton.superclass._init.apply(this, arguments); }, doClick: function () { BI.HalfIconButton.superclass.doClick.apply(this, arguments); if(this.isValid()) { this.fireEvent(BI.HalfIconButton.EVENT_CHANGE); } } }); BI.HalfIconButton.EVENT_CHANGE = "HalfIconButton.EVENT_CHANGE"; BI.shortcut("bi.half_icon_button", BI.HalfIconButton);/** * 统一的trigger图标按钮 * * Created by GUY on 2015/9/16. * @class BI.TriggerIconButton * @extends BI.IconButton */ BI.TriggerIconButton = BI.inherit(BI.IconButton, { _defaultConfig: function () { var conf = BI.TriggerIconButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-trigger-icon-button", extraCls: "pull-down-font" }); }, _init: function () { BI.TriggerIconButton.superclass._init.apply(this, arguments); }, doClick: function () { BI.TriggerIconButton.superclass.doClick.apply(this, arguments); if (this.isValid()) { this.fireEvent(BI.TriggerIconButton.EVENT_CHANGE, this); } } }); BI.TriggerIconButton.EVENT_CHANGE = "TriggerIconButton.EVENT_CHANGE"; BI.shortcut("bi.trigger_icon_button", BI.TriggerIconButton);/** * guy * 复选框item * @type {*|void|Object} */ BI.MultiSelectItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.MultiSelectItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-multi-select-item", height: 25, logic: { dynamic: false } }); }, _init: function () { BI.MultiSelectItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.checkbox" }); this.text = BI.createWidget({ type: "bi.label", cls: "list-item-text", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, rgap: o.rgap, text: o.text, keyword: o.keyword, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.setSelected(self.isSelected()); } }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { items: BI.LogicFactory.createLogicItemsByDirection("left", { type: "bi.center_adapt", items: [this.checkbox], width: 36 }, this.text) })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.MultiSelectItem.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); if (this.isValid()) { this.fireEvent(BI.MultiSelectItem.EVENT_CHANGE, this.getValue(), this); } }, setSelected: function (v) { BI.MultiSelectItem.superclass.setSelected.apply(this, arguments); this.checkbox.setSelected(v); } }); BI.MultiSelectItem.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multi_select_item", BI.MultiSelectItem);/** * Created by GUY on 2016/2/2. * * @class BI.SingleSelectIconTextItem * @extends BI.BasicButton */ BI.SingleSelectIconTextItem = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.SingleSelectIconTextItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-single-select-icon-text-item bi-list-item-active", iconClass: "", hgap: 10, height: 25 }); }, _init: function () { BI.SingleSelectIconTextItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.text = BI.createWidget({ type: "bi.icon_text_item", element: this, cls: o.iconClass, once: o.once, selected: o.selected, height: o.height, iconHeight: o.iconHeight, iconWidth: o.iconWidth, text: o.text, keyword: o.keyword, value: o.value, py: o.py }); this.text.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, isSelected: function () { return this.text.isSelected(); }, setSelected: function (b) { this.text.setSelected(b); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.SingleSelectIconTextItem.superclass.doClick.apply(this, arguments); } }); BI.shortcut("bi.single_select_icon_text_item", BI.SingleSelectIconTextItem);/** * guy * 复选框item * @type {*|void|Object} */ BI.SingleSelectItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.SingleSelectItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-single-select-item bi-list-item-active", hgap: 10, height: 25, textAlign: "left" }); }, _init: function () { BI.SingleSelectItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.text = BI.createWidget({ type: "bi.label", element: this, textAlign: o.textAlign, whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, keyword: o.keyword, value: o.value, py: o.py }); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.SingleSelectItem.superclass.doClick.apply(this, arguments); }, setSelected: function (v) { BI.SingleSelectItem.superclass.setSelected.apply(this, arguments); } }); BI.shortcut("bi.single_select_item", BI.SingleSelectItem);/** * guy * 单选框item * @type {*|void|Object} */ BI.SingleSelectRadioItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.SingleSelectRadioItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-single-select-radio-item bi-list-item-active", logic: { dynamic: false }, hgap: 10, height: 25 }); }, _init: function () { BI.SingleSelectRadioItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.radio = BI.createWidget({ type: "bi.radio" }); this.radio.on(BI.Controller.EVENT_CHANGE, function (type) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.text = BI.createWidget({ type: "bi.label", cls: "list-item-text", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, keyword: o.keyword, value: o.value, py: o.py }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { items: BI.LogicFactory.createLogicItemsByDirection("left", { type: "bi.center_adapt", items: [this.radio], width: 36 }, this.text) })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.SingleSelectRadioItem.superclass.doClick.apply(this, arguments); this.radio.setSelected(this.isSelected()); }, setSelected: function (v) { BI.SingleSelectRadioItem.superclass.setSelected.apply(this, arguments); this.radio.setSelected(v); } }); BI.shortcut("bi.single_select_radio_item", BI.SingleSelectRadioItem);/** * Created by roy on 15/10/16. */ BI.ArrowNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.ArrowNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-arrow-group-node bi-list-item", logic: { dynamic: false }, id: "", pId: "", open: false, height: 25 }); }, _init: function () { var self = this, o = this.options; BI.ArrowNode.superclass._init.apply(this, arguments); this.checkbox = BI.createWidget({ type: "bi.arrow_tree_group_node_checkbox", iconWidth: 13, iconHeight: 13 }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.setSelected(self.isSelected()); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.ArrowNode.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isOpened()); }, setValue: function (v) { this.text.setValue(v); }, setOpened: function (v) { BI.ArrowNode.superclass.setOpened.apply(this, arguments); this.checkbox.setSelected(v); } }); BI.shortcut("bi.arrow_group_node", BI.ArrowNode);/** * 加号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.FirstPlusGroupNode * @extends BI.NodeButton */ BI.FirstPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.FirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-first-plus-group-node bi-list-item", logic: { dynamic: false }, id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.FirstPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.first_tree_node_checkbox", stopPropagation: true }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { if (this.isSelected()) { self.triggerExpand(); } else { self.triggerCollapse(); } } }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.FirstPlusGroupNode.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); }, setOpened: function (v) { BI.FirstPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.checkbox)) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.first_plus_group_node", BI.FirstPlusGroupNode);/** * Created by User on 2016/3/31. */ /** * > + icon + 文本 * @class BI.IconArrowNode * @extends BI.NodeButton */ BI.IconArrowNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.IconArrowNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-icon-arrow-node bi-list-item", logic: { dynamic: false }, id: "", pId: "", open: false, height: 25, iconHeight: 13, iconWidth: 13, iconCls: "" }); }, _init: function () { BI.IconArrowNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.tree_group_node_checkbox", width: 23, stopPropagation: true }); var icon = BI.createWidget({ type: "bi.center_adapt", cls: o.iconCls, width: 23, items: [{ type: "bi.icon", height: o.iconHeight, width: o.iconWidth }] }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { if (this.isSelected()) { self.triggerExpand(); } else { self.triggerCollapse(); } } }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, { width: 23, el: icon }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.IconArrowNode.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); }, setOpened: function (v) { BI.IconArrowNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.checkbox)) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.icon_arrow_node", BI.IconArrowNode);/** * 加号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.LastPlusGroupNode * @extends BI.NodeButton */ BI.LastPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.LastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-last-plus-group-node bi-list-item", logic: { dynamic: false }, id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.LastPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.last_tree_node_checkbox", stopPropagation: true }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if(type === BI.Events.CLICK) { if (this.isSelected()) { self.triggerExpand(); } else { self.triggerCollapse(); } } }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.LastPlusGroupNode.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); }, setOpened: function (v) { BI.LastPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.checkbox)) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.last_plus_group_node", BI.LastPlusGroupNode);/** * 加号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.MidPlusGroupNode * @extends BI.NodeButton */ BI.MidPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-mid-plus-group-node bi-list-item", logic: { dynamic: false }, id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.MidPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.mid_tree_node_checkbox", stopPropagation: true }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { if (this.isSelected()) { self.triggerExpand(); } else { self.triggerCollapse(); } } }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.MidPlusGroupNode.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MidPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.checkbox)) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.mid_plus_group_node", BI.MidPlusGroupNode);BI.MultiLayerIconArrowNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MultiLayerIconArrowNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-multilayer-icon-arrow-node bi-list-item", layer: 0, // 第几层级 id: "", pId: "", open: false, height: 25, iconHeight: 13, iconWidth: 13, iconCls: "" }); }, _init: function () { BI.MultiLayerIconArrowNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.node = BI.createWidget({ type: "bi.icon_arrow_node", iconCls: o.iconCls, // logic: { // dynamic: true // }, id: o.id, pId: o.pId, open: o.open, height: o.height, iconHeight: o.iconHeight, iconWidth: o.iconWidth, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.node.on(BI.Controller.EVENT_CHANGE, function (type) { self.setSelected(self.isSelected()); self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", width: 13, height: o.height }); }); items.push(this.node); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, isOnce: function () { return true; }, doRedMark: function () { this.node.doRedMark.apply(this.node, arguments); }, unRedMark: function () { this.node.unRedMark.apply(this.node, arguments); }, isSelected: function () { return this.node.isSelected(); }, setSelected: function (b) { BI.MultiLayerIconArrowNode.superclass.setSelected.apply(this, arguments); this.node.setSelected(b); }, doClick: function () { BI.NodeButton.superclass.doClick.apply(this, arguments); this.node.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MultiLayerIconArrowNode.superclass.setOpened.apply(this, arguments); this.node.setOpened(v); } }); BI.shortcut("bi.multilayer_icon_arrow_node", BI.MultiLayerIconArrowNode);/** * 加号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.PlusGroupNode * @extends BI.NodeButton */ BI.PlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.PlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-plus-group-node bi-list-item", logic: { dynamic: false }, id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.PlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.tree_node_checkbox" }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.setSelected(self.isSelected()); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.PlusGroupNode.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); }, setOpened: function (v) { BI.PlusGroupNode.superclass.setOpened.apply(this, arguments); if (this.checkbox) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.plus_group_node", BI.PlusGroupNode);/** * 三角号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.TriangleGroupNode * @extends BI.NodeButton */ BI.TriangleGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.TriangleGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-triangle-group-node bi-list-item", logic: { dynamic: false }, id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.TriangleGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ iconWidth: 13, iconHeight: 13, type: "bi.tree_group_node_checkbox" }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py, keyword: o.keyword }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.setSelected(self.isSelected()); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.TriangleGroupNode.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isOpened()); }, setOpened: function (v) { BI.TriangleGroupNode.superclass.setOpened.apply(this, arguments); this.checkbox.setSelected(v); }, setText: function (text) { BI.TriangleGroupNode.superclass.setText.apply(this, arguments); this.text.setText(text); } }); BI.shortcut("bi.triangle_group_node", BI.TriangleGroupNode);/** * guy * 复选框item * @type {*|void|Object} */ BI.FirstTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.FirstTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-first-tree-leaf-item bi-list-item-active", logic: { dynamic: false }, id: "", pId: "", layer: 0, height: 25 }); }, _init: function () { BI.FirstTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.checkbox" }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.setSelected(self.isSelected()); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, ((o.layer === 0) ? "" : { width: 13, el: { type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height } }), { width: 25, el: { type: "bi.layout", cls: "mid-line-conn-background", width: 25, height: o.height } }, { el: this.text }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.FirstTreeLeafItem.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); }, setSelected: function (v) { BI.FirstTreeLeafItem.superclass.setSelected.apply(this, arguments); this.checkbox.setSelected(v); } }); BI.shortcut("bi.first_tree_leaf_item", BI.FirstTreeLeafItem);BI.IconTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.IconTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-icon-tree-leaf-item bi-list-item-active", logic: { dynamic: false }, height: 25, iconWidth: 16, iconHeight: 16, iconCls: "" }); }, _init: function () { BI.IconTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; var icon = BI.createWidget({ type: "bi.center_adapt", width: 23, cls: o.iconCls, items: [{ type: "bi.icon", width: o.iconWidth, height: o.iconHeight }] }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 23, el: icon }, { el: this.text }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.IconTreeLeafItem.superclass.doClick.apply(this, arguments); }, setSelected: function (v) { BI.IconTreeLeafItem.superclass.setSelected.apply(this, arguments); } }); BI.shortcut("bi.icon_tree_leaf_item", BI.IconTreeLeafItem);/** * guy * 复选框item * @type {*|void|Object} */ BI.LastTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.LastTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-last-tree-leaf-item bi-list-item-active", logic: { dynamic: false }, id: "", pId: "", layer: 0, height: 25 }); }, _init: function () { BI.LastTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.checkbox" }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.setSelected(self.isSelected()); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, ((o.layer === 0) ? "" : { width: 13, el: { type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height } }), { width: 25, el: { type: "bi.layout", cls: "mid-line-conn-background", width: 25, height: o.height } }, { el: this.text }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.LastTreeLeafItem.superclass.doClick.apply(this, arguments); // this.checkbox.setSelected(this.isSelected()); }, setSelected: function (v) { BI.LastTreeLeafItem.superclass.setSelected.apply(this, arguments); // this.checkbox.setSelected(v); } }); BI.shortcut("bi.last_tree_leaf_item", BI.LastTreeLeafItem);/** * guy * 复选框item * @type {*|void|Object} */ BI.MidTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.MidTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-mid-tree-leaf-item bi-list-item-active", logic: { dynamic: false }, id: "", pId: "", layer: 0, height: 25 }); }, _init: function () { BI.MidTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.checkbox" }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.setSelected(self.isSelected()); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, ((o.layer === 0) ? "" : { width: 13, el: { type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height } }), { width: 25, el: { type: "bi.layout", cls: "mid-line-conn-background", width: 25, height: o.height } }, { el: this.text }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.MidTreeLeafItem.superclass.doClick.apply(this, arguments); this.checkbox.setSelected(this.isSelected()); }, setSelected: function (v) { BI.MidTreeLeafItem.superclass.setSelected.apply(this, arguments); this.checkbox.setSelected(v); } }); BI.shortcut("bi.mid_tree_leaf_item", BI.MidTreeLeafItem);/** * @class BI.MultiLayerIconTreeLeafItem * @extends BI.BasicButton */ BI.MultiLayerIconTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.MultiLayerIconTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-multilayer-icon-tree-leaf-item bi-list-item-active", layer: 0, height: 25, iconCls: "", iconHeight: 14, iconWidth: 12 }); }, _init: function () { BI.MultiLayerIconTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.item = BI.createWidget({ type: "bi.icon_tree_leaf_item", cls: "bi-list-item-none", iconCls: o.iconCls, id: o.id, pId: o.pId, isFront: true, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py, iconWidth: o.iconWidth, iconHeight: o.iconHeight }); this.item.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) {// 本身实现click功能 return; } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", width: 13, height: o.height }); }); items.push(this.item); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.item.doRedMark.apply(this.item, arguments); }, unRedMark: function () { this.item.unRedMark.apply(this.item, arguments); }, doHighLight: function () { this.item.doHighLight.apply(this.item, arguments); }, unHighLight: function () { this.item.unHighLight.apply(this.item, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.MultiLayerIconTreeLeafItem.superclass.doClick.apply(this, arguments); this.item.setSelected(this.isSelected()); }, setSelected: function (v) { BI.MultiLayerIconTreeLeafItem.superclass.setSelected.apply(this, arguments); this.item.setSelected(v); }, getValue: function () { return this.options.value; } }); BI.shortcut("bi.multilayer_icon_tree_leaf_item", BI.MultiLayerIconTreeLeafItem);/** * 树叶子节点 * Created by GUY on 2015/9/6. * @class BI.TreeTextLeafItem * @extends BI.BasicButton */ BI.TreeTextLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.TreeTextLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-tree-text-leaf-item bi-list-item-active", id: "", pId: "", height: 25, hgap: 0, lgap: 0, rgap: 0 }); }, _init: function () { BI.TreeTextLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, lgap: o.lgap, rgap: o.hgap, text: o.text, value: o.value, py: o.py }); BI.createWidget({ type: "bi.htape", element: this, items: [{ el: this.text }] }); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; } }); BI.shortcut("bi.tree_text_leaf_item", BI.TreeTextLeafItem);/** * Created by GUY on 2015/8/28. * @class BI.Calendar * @extends BI.Widget */ BI.Calendar = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.Calendar.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-calendar", logic: { dynamic: false }, min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 year: 2015, month: 7, // 7表示八月 day: 25 }); }, _dateCreator: function (Y, M, D) { var self = this, o = this.options, log = {}, De = Date.getDate(); var mins = o.min.match(/\d+/g); var maxs = o.max.match(/\d+/g); Y < (mins[0] | 0) && (Y = (mins[0] | 0)); Y > (maxs[0] | 0) && (Y = (maxs[0] | 0)); De.setFullYear(Y, M, D); log.ymd = [De.getFullYear(), De.getMonth(), De.getDate()]; var MD = Date._MD.slice(0); MD[1] = Date.isLeap(log.ymd[0]) ? 29 : 28; De.setFullYear(log.ymd[0], log.ymd[1], 1); log.FDay = De.getDay(); log.PDay = MD[M === 0 ? 11 : M - 1] - log.FDay + 1; log.NDay = 1; var items = []; BI.each(BI.range(42), function (i) { var td = {}, YY = log.ymd[0], MM = log.ymd[1] + 1, DD; if (i < log.FDay) { td.lastMonth = true; DD = i + log.PDay; MM === 1 && (YY -= 1); MM = MM === 1 ? 12 : MM - 1; } else if (i >= log.FDay && i < log.FDay + MD[log.ymd[1]]) { DD = i - log.FDay + 1; if (i - log.FDay + 1 === log.ymd[2]) { td.currentDay = true; } } else { td.nextMonth = true; DD = log.NDay++; MM === 12 && (YY += 1); MM = MM === 12 ? 1 : MM + 1; } if (Date.checkVoid(YY, MM, DD, mins, maxs)[0]) { td.disabled = true; } td.text = DD; items.push(td); }); return items; }, _init: function () { BI.Calendar.superclass._init.apply(this, arguments); var self = this, o = this.options; var items = BI.map(Date._SDN.slice(0, 7), function (i, value) { return { type: "bi.label", height: 25, text: value }; }); var title = BI.createWidget({ type: "bi.button_group", height: 25, items: items }); var days = this._dateCreator(o.year, o.month, o.day); items = []; items.push(days.slice(0, 7)); items.push(days.slice(7, 14)); items.push(days.slice(14, 21)); items.push(days.slice(21, 28)); items.push(days.slice(28, 35)); items.push(days.slice(35, 42)); items = BI.map(items, function (i, item) { return BI.map(item, function (j, td) { return BI.extend(td, { type: "bi.text_item", cls: "bi-list-item-active", textAlign: "center", whiteSpace: "normal", once: false, forceSelected: true, height: 25, value: o.year + "-" + o.month + "-" + td.text, disabled: td.lastMonth || td.nextMonth || td.disabled // selected: td.currentDay }); }); }); this.days = BI.createWidget({ type: "bi.button_group", items: BI.createItems(items, {}), layouts: [BI.LogicFactory.createLogic("table", BI.extend({}, o.logic, { columns: 7, rows: 6, columnSize: [1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7], rowSize: 25 }))] }); this.days.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic("vertical", BI.extend({}, o.logic, { items: BI.LogicFactory.createLogicItemsByDirection("top", title, this.days) })))); }, isFrontDate: function () { var o = this.options, c = this._const; var Y = o.year, M = o.month, De = Date.getDate(), day = De.getDay(); Y = Y | 0; De.setFullYear(Y, M, 1); var newDate = De.getOffsetDate(-1 * (day + 1)); return !!Date.checkVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), o.min, o.max)[0]; }, isFinalDate: function () { var o = this.options, c = this._const; var Y = o.year, M = o.month, De = Date.getDate(), day = De.getDay(); Y = Y | 0; De.setFullYear(Y, M, 1); var newDate = De.getOffsetDate(42 - day); return !!Date.checkVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), o.min, o.max)[0]; }, setValue: function (ob) { this.days.setValue([ob.year + "-" + ob.month + "-" + ob.day]); }, getValue: function () { var date = this.days.getValue()[0].match(/\d+/g); return { year: date[0] | 0, month: date[1] | 0, day: date[2] | 0 }; } }); BI.extend(BI.Calendar, { getPageByDateJSON: function (json) { var year = Date.getDate().getFullYear(); var month = Date.getDate().getMonth(); var page = (json.year - year) * 12; page += json.month - month; return page; }, getDateJSONByPage: function (v) { var months = Date.getDate().getMonth(); var page = v; // 对当前page做偏移,使到当前年初 page = page + months; var year = BI.parseInt(page / 12); if(page < 0 && page % 12 !== 0) { year--; } var month = page >= 0 ? (page % 12) : ((12 + page % 12) % 12); return { year: Date.getDate().getFullYear() + year, month: month }; } }); BI.shortcut("bi.calendar", BI.Calendar);/** * Created by GUY on 2015/8/28. * @class BI.YearCalendar * @extends BI.Widget */ BI.YearCalendar = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.YearCalendar.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-year-calendar", behaviors: {}, logic: { dynamic: false }, min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 year: null }); }, _yearCreator: function (Y) { var o = this.options; Y = Y | 0; var start = BI.YearCalendar.getStartYear(Y); var items = []; BI.each(BI.range(BI.YearCalendar.INTERVAL), function (i) { var td = {}; if (Date.checkVoid(start + i, 1, 1, o.min, o.max)[0]) { td.disabled = true; } td.text = start + i; items.push(td); }); return items; }, _init: function () { BI.YearCalendar.superclass._init.apply(this, arguments); var self = this, o = this.options; this.currentYear = Date.getDate().getFullYear(); var years = this._yearCreator(o.year || this.currentYear); // 纵向排列年 var len = years.length, tyears = BI.makeArray(len, ""); var map = [0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11]; BI.each(years, function (i, y) { tyears[i] = years[map[i]]; }); var items = []; items.push(tyears.slice(0, 2)); items.push(tyears.slice(2, 4)); items.push(tyears.slice(4, 6)); items.push(tyears.slice(6, 8)); items.push(tyears.slice(8, 10)); items.push(tyears.slice(10, 12)); items = BI.map(items, function (i, item) { return BI.map(item, function (j, td) { return BI.extend(td, { type: "bi.text_item", cls: "bi-list-item-active", textAlign: "center", whiteSpace: "normal", once: false, forceSelected: true, height: 23, width: 38, value: td.text, disabled: td.disabled }); }); }); this.years = BI.createWidget({ type: "bi.button_group", behaviors: o.behaviors, items: BI.createItems(items, {}), layouts: [BI.LogicFactory.createLogic("table", BI.extend({}, o.logic, { columns: 2, rows: 6, columnSize: [1 / 2, 1 / 2], rowSize: 25 })), { type: "bi.center_adapt", vgap: 1 }] }); this.years.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic("vertical", BI.extend({}, o.logic, { items: BI.LogicFactory.createLogicItemsByDirection("top", this.years) })))); }, isFrontYear: function () { var o = this.options; var Y = o.year; Y = Y | 0; return !!Date.checkVoid(BI.YearCalendar.getStartYear(Y) - 1, 1, 1, o.min, o.max)[0]; }, isFinalYear: function () { var o = this.options, c = this._const; var Y = o.year; Y = Y | 0; return !!Date.checkVoid(BI.YearCalendar.getEndYear(Y) + 1, 1, 1, o.min, o.max)[0]; }, setValue: function (val) { this.years.setValue([val]); }, getValue: function () { return this.years.getValue()[0]; } }); // 类方法 BI.extend(BI.YearCalendar, { INTERVAL: 12, // 获取显示的第一年 getStartYear: function (year) { var cur = Date.getDate().getFullYear(); return year - ((year - cur + 3) % BI.YearCalendar.INTERVAL + 12) % BI.YearCalendar.INTERVAL; }, getEndYear: function (year) { return BI.YearCalendar.getStartYear(year) + BI.YearCalendar.INTERVAL; }, getPageByYear: function (year) { var cur = Date.getDate().getFullYear(); year = BI.YearCalendar.getStartYear(year); return (year - cur + 3) / BI.YearCalendar.INTERVAL; } }); BI.shortcut("bi.year_calendar", BI.YearCalendar);/** * 绘制一些较复杂的canvas * * Created by GUY on 2015/11/24. * @class BI.ComplexCanvas * @extends BI.Widget */ BI.ComplexCanvas = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ComplexCanvas.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-complex-canvas" }); }, _init: function () { BI.ComplexCanvas.superclass._init.apply(this, arguments); var o = this.options; this.canvas = BI.createWidget({ type: "bi.canvas", element: this, width: o.width, height: o.height }); }, // 绘制树枝节点 branch: function (x0, y0, x1, y1, x2, y2) { var self = this, args = [].slice.call(arguments); if (args.length <= 5) { return this.canvas.line.apply(this.canvas, arguments); } var options; if (BI.isOdd(args.length)) { options = BI.last(args); args = BI.initial(args); } args = [].slice.call(args, 2); var odd = BI.filter(args, function (i) { return i % 2 === 0; }); var even = BI.filter(args, function (i) { return i % 2 !== 0; }); options || (options = {}); var offset = options.offset || 20; if ((y0 > y1 && y0 > y2) || (y0 < y1 && y0 < y2)) { if (y0 > y1 && y0 > y2) { var y = Math.max.apply(this, even) + offset; } else { var y = Math.min.apply(this, even) - offset; } var minx = Math.min.apply(this, odd); var minix = BI.indexOf(odd, minx); var maxx = Math.max.apply(this, odd); var maxix = BI.indexOf(odd, maxx); this.canvas.line(minx, even[minix], minx, y, maxx, y, maxx, even[maxix], options); BI.each(odd, function (i, dot) { if (i !== maxix && i !== minix) { self.canvas.line(dot, even[i], dot, y, options); } }); this.canvas.line(x0, y, x0, y0, options); return; } if ((x0 > x1 && x0 > x2) || (x0 < x1 && x0 < x2)) { if (x0 > x1 && x0 > x2) { var x = Math.max.apply(this, odd) + offset; } else { var x = Math.min.apply(this, odd) - offset; } var miny = Math.min.apply(this, even); var miniy = BI.indexOf(even, miny); var maxy = Math.max.apply(this, even); var maxiy = BI.indexOf(even, maxy); this.canvas.line(odd[miniy], miny, x, miny, x, maxy, odd[maxiy], maxy, options); BI.each(even, function (i, dot) { if (i !== miniy && i !== maxiy) { self.canvas.line(odd[i], dot, x, dot, options); } }); this.canvas.line(x, y0, x0, y0, options); return; } }, stroke: function (callback) { this.canvas.stroke(callback); } }); BI.shortcut("bi.complex_canvas", BI.ComplexCanvas);/** * Created by roy on 15/10/16. * 上箭头与下箭头切换的树节点 */ BI.ArrowTreeGroupNodeCheckbox = BI.inherit(BI.IconButton, { _defaultConfig: function () { return BI.extend(BI.ArrowTreeGroupNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-arrow-tree-group-node" }); }, _init: function () { BI.ArrowTreeGroupNodeCheckbox.superclass._init.apply(this, arguments); }, setSelected: function (v) { BI.ArrowTreeGroupNodeCheckbox.superclass.setSelected.apply(this, arguments); if(v) { this.element.removeClass("pull-right-font").addClass("pull-down-font"); } else { this.element.removeClass("pull-down-font").addClass("pull-right-font"); } } }); BI.shortcut("bi.arrow_tree_group_node_checkbox", BI.ArrowTreeGroupNodeCheckbox);/** * 十字型的树节点 * @class BI.CheckingMarkNode * @extends BI.IconButton */ BI.CheckingMarkNode = BI.inherit(BI.IconButton, { _defaultConfig: function () { return BI.extend( BI.CheckingMarkNode.superclass._defaultConfig.apply(this, arguments), { extraCls: "check-mark-font" }); }, _init: function () { BI.CheckingMarkNode.superclass._init.apply(this, arguments); this.setSelected(this.options.selected); }, setSelected: function (v) { BI.CheckingMarkNode.superclass.setSelected.apply(this, arguments); if(v === true) { this.element.addClass("check-mark-font"); } else { this.element.removeClass("check-mark-font"); } } }); BI.shortcut("bi.checking_mark_node", BI.CheckingMarkNode);/** * 十字型的树节点 * @class BI.FirstTreeNodeCheckbox * @extends BI.IconButton */ BI.FirstTreeNodeCheckbox = BI.inherit(BI.IconButton, { _defaultConfig: function () { return BI.extend( BI.FirstTreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { extraCls: "tree-collapse-icon-type2", iconWidth: 25, iconHeight: 25 }); }, _init: function () { BI.FirstTreeNodeCheckbox.superclass._init.apply(this, arguments); }, setSelected: function (v) { BI.FirstTreeNodeCheckbox.superclass.setSelected.apply(this, arguments); if(v === true) { this.element.addClass("tree-expand-icon-type2"); } else { this.element.removeClass("tree-expand-icon-type2"); } } }); BI.shortcut("bi.first_tree_node_checkbox", BI.FirstTreeNodeCheckbox);/** * 十字型的树节点 * @class BI.LastTreeNodeCheckbox * @extends BI.IconButton */ BI.LastTreeNodeCheckbox = BI.inherit(BI.IconButton, { _defaultConfig: function () { return BI.extend( BI.LastTreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { extraCls: "tree-collapse-icon-type4", iconWidth: 25, iconHeight: 25 }); }, _init: function () { BI.LastTreeNodeCheckbox.superclass._init.apply(this, arguments); }, setSelected: function (v) { BI.LastTreeNodeCheckbox.superclass.setSelected.apply(this, arguments); if(v === true) { this.element.addClass("tree-expand-icon-type3"); } else { this.element.removeClass("tree-expand-icon-type3"); } } }); BI.shortcut("bi.last_tree_node_checkbox", BI.LastTreeNodeCheckbox);/** * 十字型的树节点 * @class BI.MidTreeNodeCheckbox * @extends BI.IconButton */ BI.MidTreeNodeCheckbox = BI.inherit(BI.IconButton, { _defaultConfig: function () { return BI.extend( BI.MidTreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { extraCls: "tree-collapse-icon-type3", iconWidth: 25, iconHeight: 25 }); }, _init: function () { BI.MidTreeNodeCheckbox.superclass._init.apply(this, arguments); }, setSelected: function (v) { BI.MidTreeNodeCheckbox.superclass.setSelected.apply(this, arguments); if(v === true) { this.element.addClass("tree-expand-icon-type3"); } else { this.element.removeClass("tree-expand-icon-type3"); } } }); BI.shortcut("bi.mid_tree_node_checkbox", BI.MidTreeNodeCheckbox);/** * 三角形的树节点 * Created by GUY on 2015/9/6. * @class BI.TreeGroupNodeCheckbox * @extends BI.IconButton */ BI.TreeGroupNodeCheckbox = BI.inherit(BI.IconButton, { _defaultConfig: function () { return BI.extend( BI.TreeGroupNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { extraCls: "tree-node-triangle-collapse-font" }); }, _init: function () { BI.TreeGroupNodeCheckbox.superclass._init.apply(this, arguments); }, setSelected: function (v) { BI.TreeGroupNodeCheckbox.superclass.setSelected.apply(this, arguments); if(v) { this.element.removeClass("tree-node-triangle-collapse-font").addClass("tree-node-triangle-expand-font"); } else { this.element.removeClass("tree-node-triangle-expand-font").addClass("tree-node-triangle-collapse-font"); } } }); BI.shortcut("bi.tree_group_node_checkbox", BI.TreeGroupNodeCheckbox);/** * 十字型的树节点 * @class BI.TreeNodeCheckbox * @extends BI.IconButton */ BI.TreeNodeCheckbox = BI.inherit(BI.IconButton, { _defaultConfig: function () { return BI.extend( BI.TreeNodeCheckbox.superclass._defaultConfig.apply(this, arguments), { extraCls: "tree-collapse-icon-type1", iconWidth: 25, iconHeight: 25 }); }, _init: function () { BI.TreeNodeCheckbox.superclass._init.apply(this, arguments); }, setSelected: function (v) { BI.TreeNodeCheckbox.superclass.setSelected.apply(this, arguments); if(v) { this.element.addClass("tree-expand-icon-type1"); } else { this.element.removeClass("tree-expand-icon-type1"); } } }); BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox);/* ! * clipboard.js v1.6.1 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ try {// IE8下会抛错 (function (f) { if (typeof exports === "object" && typeof module !== "undefined") { module.exports = f(); } else if (typeof define === "function" && define.amd) { define([], f); } else { var g; if (typeof window !== "undefined") { g = window; } else if (typeof global !== "undefined") { g = global; } else if (typeof self !== "undefined") { g = self; } else { g = this; } g.Clipboard = f(); } })(function () { var define, module, exports; return (function e (t, n, r) { function s (o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require === "function" && require; if (!u && a)return a(o, !0); if (i)return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = "MODULE_NOT_FOUND", f; } var l = n[o] = {exports: {}}; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e); }, l, l.exports, e, t, n, r); } return n[o].exports; } var i = typeof require === "function" && require; for (var o = 0; o < r.length; o++)s(r[o]); return s; })({ 1: [function (require, module, exports) { var DOCUMENT_NODE_TYPE = 9; /** * A polyfill for Element.matches() */ if (typeof Element !== "undefined" && !Element.prototype.matches) { var proto = Element.prototype; proto.matches = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector; } /** * Finds the closest parent that matches a selector. * * @param {Element} element * @param {String} selector * @return {Function} */ function closest (element, selector) { while (element && element.nodeType !== DOCUMENT_NODE_TYPE) { if (element.matches(selector)) return element; element = element.parentNode; } } module.exports = closest; }, {}], 2: [function (require, module, exports) { var closest = require("./closest"); /** * Delegates event to a selector. * * @param {Element} element * @param {String} selector * @param {String} type * @param {Function} callback * @param {Boolean} useCapture * @return {Object} */ function delegate (element, selector, type, callback, useCapture) { var listenerFn = listener.apply(this, arguments); element.addEventListener(type, listenerFn, useCapture); return { destroy: function () { element.removeEventListener(type, listenerFn, useCapture); } }; } /** * Finds closest match and invokes callback. * * @param {Element} element * @param {String} selector * @param {String} type * @param {Function} callback * @return {Function} */ function listener (element, selector, type, callback) { return function (e) { e.delegateTarget = closest(e.target, selector); if (e.delegateTarget) { callback.call(element, e); } }; } module.exports = delegate; }, {"./closest": 1}], 3: [function (require, module, exports) { /** * Check if argument is a HTML element. * * @param {Object} value * @return {Boolean} */ exports.node = function (value) { return value !== undefined && value instanceof HTMLElement && value.nodeType === 1; }; /** * Check if argument is a list of HTML elements. * * @param {Object} value * @return {Boolean} */ exports.nodeList = function (value) { var type = Object.prototype.toString.call(value); return value !== undefined && (type === "[object NodeList]" || type === "[object HTMLCollection]") && ("length" in value) && (value.length === 0 || exports.node(value[0])); }; /** * Check if argument is a string. * * @param {Object} value * @return {Boolean} */ exports.string = function (value) { return typeof value === "string" || value instanceof String; }; /** * Check if argument is a function. * * @param {Object} value * @return {Boolean} */ exports.fn = function (value) { var type = Object.prototype.toString.call(value); return type === "[object Function]"; }; }, {}], 4: [function (require, module, exports) { var is = require("./is"); var delegate = require("delegate"); /** * Validates all params and calls the right * listener function based on its target type. * * @param {String|HTMLElement|HTMLCollection|NodeList} target * @param {String} type * @param {Function} callback * @return {Object} */ function listen (target, type, callback) { if (!target && !type && !callback) { throw new Error("Missing required arguments"); } if (!is.string(type)) { throw new TypeError("Second argument must be a String"); } if (!is.fn(callback)) { throw new TypeError("Third argument must be a Function"); } if (is.node(target)) { return listenNode(target, type, callback); } else if (is.nodeList(target)) { return listenNodeList(target, type, callback); } else if (is.string(target)) { return listenSelector(target, type, callback); } throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList"); } /** * Adds an event listener to a HTML element * and returns a remove listener function. * * @param {HTMLElement} node * @param {String} type * @param {Function} callback * @return {Object} */ function listenNode (node, type, callback) { node.addEventListener(type, callback); return { destroy: function () { node.removeEventListener(type, callback); } }; } /** * Add an event listener to a list of HTML elements * and returns a remove listener function. * * @param {NodeList|HTMLCollection} nodeList * @param {String} type * @param {Function} callback * @return {Object} */ function listenNodeList (nodeList, type, callback) { Array.prototype.forEach.call(nodeList, function (node) { node.addEventListener(type, callback); }); return { destroy: function () { Array.prototype.forEach.call(nodeList, function (node) { node.removeEventListener(type, callback); }); } }; } /** * Add an event listener to a selector * and returns a remove listener function. * * @param {String} selector * @param {String} type * @param {Function} callback * @return {Object} */ function listenSelector (selector, type, callback) { return delegate(document.body, selector, type, callback); } module.exports = listen; }, {"./is": 3, delegate: 2}], 5: [function (require, module, exports) { function select (element) { var selectedText; if (element.nodeName === "SELECT") { element.focus(); selectedText = element.value; } else if (element.nodeName === "INPUT" || element.nodeName === "TEXTAREA") { var isReadOnly = element.hasAttribute("readonly"); if (!isReadOnly) { element.setAttribute("readonly", ""); } element.select(); element.setSelectionRange(0, element.value.length); if (!isReadOnly) { element.removeAttribute("readonly"); } selectedText = element.value; } else { if (element.hasAttribute("contenteditable")) { element.focus(); } var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); selectedText = selection.toString(); } return selectedText; } module.exports = select; }, {}], 6: [function (require, module, exports) { function E () { // Keep this empty so it's easier to inherit from // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) } E.prototype = { on: function (name, callback, ctx) { var e = this.e || (this.e = {}); (e[name] || (e[name] = [])).push({ fn: callback, ctx: ctx }); return this; }, once: function (name, callback, ctx) { var self = this; function listener () { self.off(name, listener); callback.apply(ctx, arguments); } listener._ = callback; return this.on(name, listener, ctx); }, emit: function (name) { var data = [].slice.call(arguments, 1); var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); var i = 0; var len = evtArr.length; for (i; i < len; i++) { evtArr[i].fn.apply(evtArr[i].ctx, data); } return this; }, off: function (name, callback) { var e = this.e || (this.e = {}); var evts = e[name]; var liveEvents = []; if (evts && callback) { for (var i = 0, len = evts.length; i < len; i++) { if (evts[i].fn !== callback && evts[i].fn._ !== callback) {liveEvents.push(evts[i]);} } } // Remove event from queue to prevent memory leak // Suggested by https://github.com/lazd // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 (liveEvents.length) ? e[name] = liveEvents : delete e[name]; return this; } }; module.exports = E; }, {}], 7: [function (require, module, exports) { (function (global, factory) { if (typeof define === "function" && define.amd) { define(["module", "select"], factory); } else if (typeof exports !== "undefined") { factory(module, require("select")); } else { var mod = { exports: {} }; factory(mod, global.select); global.clipboardAction = mod.exports; } })(this, function (module, _select) { "use strict"; var _select2 = _interopRequireDefault(_select); function _interopRequireDefault (obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _classCallCheck (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var _createClass = function () { function defineProperties (target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var ClipboardAction = function () { /** * @param {Object} options */ function ClipboardAction (options) { _classCallCheck(this, ClipboardAction); this.resolveOptions(options); this.initSelection(); } /** * Defines base properties passed from constructor. * @param {Object} options */ _createClass(ClipboardAction, [{ key: "resolveOptions", value: function resolveOptions () { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; this.action = options.action; this.emitter = options.emitter; this.target = options.target; this.text = options.text; this.trigger = options.trigger; this.selectedText = ""; } }, { key: "initSelection", value: function initSelection () { if (this.text) { this.selectFake(); } else if (this.target) { this.selectTarget(); } } }, { key: "selectFake", value: function selectFake () { var _this = this; var isRTL = document.documentElement.getAttribute("dir") == "rtl"; this.removeFake(); this.fakeHandlerCallback = function () { return _this.removeFake(); }; this.fakeHandler = document.body.addEventListener("click", this.fakeHandlerCallback) || true; this.fakeElem = document.createElement("textarea"); // Prevent zooming on iOS this.fakeElem.style.fontSize = "12pt"; // Reset box model this.fakeElem.style.border = "0"; this.fakeElem.style.padding = "0"; this.fakeElem.style.margin = "0"; // Move element out of screen horizontally this.fakeElem.style.position = "absolute"; this.fakeElem.style[isRTL ? "right" : "left"] = "-9999px"; // Move element to the same position vertically var yPosition = window.pageYOffset || document.documentElement.scrollTop; this.fakeElem.style.top = yPosition + "px"; this.fakeElem.setAttribute("readonly", ""); this.fakeElem.value = this.text; document.body.appendChild(this.fakeElem); this.selectedText = (0, _select2["default"])(this.fakeElem); this.copyText(); } }, { key: "removeFake", value: function removeFake () { if (this.fakeHandler) { document.body.removeEventListener("click", this.fakeHandlerCallback); this.fakeHandler = null; this.fakeHandlerCallback = null; } if (this.fakeElem) { document.body.removeChild(this.fakeElem); this.fakeElem = null; } } }, { key: "selectTarget", value: function selectTarget () { this.selectedText = (0, _select2["default"])(this.target); this.copyText(); } }, { key: "copyText", value: function copyText () { var succeeded = void 0; try { succeeded = document.execCommand(this.action); } catch (err) { succeeded = false; } this.handleResult(succeeded); } }, { key: "handleResult", value: function handleResult (succeeded) { this.emitter.emit(succeeded ? "success" : "error", { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: "clearSelection", value: function clearSelection () { if (this.target) { this.target.blur(); } window.getSelection().removeAllRanges(); } }, { key: "destroy", value: function destroy () { this.removeFake(); } }, { key: "action", set: function set () { var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "copy"; this._action = action; if (this._action !== "copy" && this._action !== "cut") { throw new Error("Invalid \"action\" value, use either \"copy\" or \"cut\""); } }, get: function get () { return this._action; } }, { key: "target", set: function set (target) { if (target !== undefined) { if (target && (typeof target === "undefined" ? "undefined" : _typeof(target)) === "object" && target.nodeType === 1) { if (this.action === "copy" && target.hasAttribute("disabled")) { throw new Error("Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute"); } if (this.action === "cut" && (target.hasAttribute("readonly") || target.hasAttribute("disabled"))) { throw new Error("Invalid \"target\" attribute. You can't cut text from elements with \"readonly\" or \"disabled\" attributes"); } this._target = target; } else { throw new Error("Invalid \"target\" value, use a valid Element"); } } }, get: function get () { return this._target; } }]); return ClipboardAction; }(); module.exports = ClipboardAction; }); }, {select: 5}], 8: [function (require, module, exports) { (function (global, factory) { if (typeof define === "function" && define.amd) { define(["module", "./clipboard-action", "tiny-emitter", "good-listener"], factory); } else if (typeof exports !== "undefined") { factory(module, require("./clipboard-action"), require("tiny-emitter"), require("good-listener")); } else { var mod = { exports: {} }; factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); global.clipboard = mod.exports; } })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { "use strict"; var _clipboardAction2 = _interopRequireDefault(_clipboardAction); var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); var _goodListener2 = _interopRequireDefault(_goodListener); function _interopRequireDefault (obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _classCallCheck (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var _createClass = function () { function defineProperties (target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _possibleConstructorReturn (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Clipboard = function (_Emitter) { _inherits(Clipboard, _Emitter); /** * @param {String|HTMLElement|HTMLCollection|NodeList} trigger * @param {Object} options */ function Clipboard (trigger, options) { _classCallCheck(this, Clipboard); var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); _this.resolveOptions(options); _this.listenClick(trigger); return _this; } /** * Defines if attributes would be resolved using internal setter functions * or custom functions that were passed in the constructor. * @param {Object} options */ _createClass(Clipboard, [{ key: "resolveOptions", value: function resolveOptions () { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; this.action = typeof options.action === "function" ? options.action : this.defaultAction; this.target = typeof options.target === "function" ? options.target : this.defaultTarget; this.text = typeof options.text === "function" ? options.text : this.defaultText; } }, { key: "listenClick", value: function listenClick (trigger) { var _this2 = this; this.listener = (0, _goodListener2["default"])(trigger, "click", function (e) { return _this2.onClick(e); }); } }, { key: "onClick", value: function onClick (e) { var trigger = e.delegateTarget || e.currentTarget; if (this.clipboardAction) { this.clipboardAction = null; } this.clipboardAction = new _clipboardAction2["default"]({ action: this.action(trigger), target: this.target(trigger), text: this.text(trigger), trigger: trigger, emitter: this }); } }, { key: "defaultAction", value: function defaultAction (trigger) { return getAttributeValue("action", trigger); } }, { key: "defaultTarget", value: function defaultTarget (trigger) { var selector = getAttributeValue("target", trigger); if (selector) { return document.querySelector(selector); } } }, { key: "defaultText", value: function defaultText (trigger) { return getAttributeValue("text", trigger); } }, { key: "destroy", value: function destroy () { this.listener.destroy(); if (this.clipboardAction) { this.clipboardAction.destroy(); this.clipboardAction = null; } } }], [{ key: "isSupported", value: function isSupported () { var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ["copy", "cut"]; var actions = typeof action === "string" ? [action] : action; var support = !!document.queryCommandSupported; actions.forEach(function (action) { support = support && !!document.queryCommandSupported(action); }); return support; } }]); return Clipboard; }(_tinyEmitter2["default"]); /** * Helper function to retrieve attribute value. * @param {String} suffix * @param {Element} element */ function getAttributeValue (suffix, element) { var attribute = "data-clipboard-" + suffix; if (!element.hasAttribute(attribute)) { return; } return element.getAttribute(attribute); } module.exports = Clipboard; }); }, {"./clipboard-action": 7, "good-listener": 4, "tiny-emitter": 6}] }, {}, [8])(8); }); } catch (e) { /* * zClip :: jQuery ZeroClipboard v1.1.1 * http://steamdev.com/zclip * * Copyright 2011, SteamDev * Released under the MIT license. * http://www.opensource.org/licenses/mit-license.php * * Date: Wed Jun 01, 2011 */ (function ($) { $.fn.zclip = function (params) { if (typeof params === "object" && !params.length) { var settings = $.extend({ path: "ZeroClipboard.swf", copy: null, beforeCopy: null, afterCopy: null, clickAfter: true, setHandCursor: true, setCSSEffects: true }, params); return this.each(function () { var o = $(this); if (o.is(":visible") && (typeof settings.copy === "string" || $.isFunction(settings.copy))) { ZeroClipboard.setMoviePath(settings.path); var clip = new ZeroClipboard.Client(); if ($.isFunction(settings.copy)) { o.bind("zClip_copy", settings.copy); } if ($.isFunction(settings.beforeCopy)) { o.bind("zClip_beforeCopy", settings.beforeCopy); } if ($.isFunction(settings.afterCopy)) { o.bind("zClip_afterCopy", settings.afterCopy); } clip.setHandCursor(settings.setHandCursor); clip.setCSSEffects(settings.setCSSEffects); clip.addEventListener("mouseOver", function (client) { o.trigger("mouseenter"); }); clip.addEventListener("mouseOut", function (client) { o.trigger("mouseleave"); }); clip.addEventListener("mouseDown", function (client) { o.trigger("mousedown"); if (!$.isFunction(settings.copy)) { clip.setText(settings.copy); } else { clip.setText(o.triggerHandler("zClip_copy")); } if ($.isFunction(settings.beforeCopy)) { o.trigger("zClip_beforeCopy"); } }); clip.addEventListener("complete", function (client, text) { if ($.isFunction(settings.afterCopy)) { o.trigger("zClip_afterCopy"); } else { if (text.length > 500) { text = text.substr(0, 500) + "...\n\n(" + (text.length - 500) + " characters not shown)"; } o.removeClass("hover"); alert("Copied text to clipboard:\n\n " + text); } if (settings.clickAfter) { o.trigger("click"); } }); clip.glue(o[0], o.parent()[0]); $(window).bind("load resize", function () { clip.reposition(); }); } }); } else if (typeof params === "string") { return this.each(function () { var o = $(this); params = params.toLowerCase(); var zclipId = o.data("zclipId"); var clipElm = $("#" + zclipId + ".zclip"); if (params == "remove") { clipElm.remove(); o.removeClass("active hover"); } else if (params == "hide") { clipElm.hide(); o.removeClass("active hover"); } else if (params == "show") { clipElm.show(); } }); } }; })(jQuery); // ZeroClipboard // Simple Set Clipboard System // Author: Joseph Huckaby var ZeroClipboard = { version: "1.0.7", clients: {}, // registered upload clients on page, indexed by id moviePath: "ZeroClipboard.swf", // URL to movie nextId: 1, // ID of next movie $: function (thingy) { // simple DOM lookup utility function if (typeof(thingy) === "string") thingy = document.getElementById(thingy); if (!thingy.addClass) { // extend element with a few useful methods thingy.hide = function () { this.style.display = "none"; }; thingy.show = function () { this.style.display = ""; }; thingy.addClass = function (name) { this.removeClass(name); this.className += " " + name; }; thingy.removeClass = function (name) { var classes = this.className.split(/\s+/); var idx = -1; for (var k = 0; k < classes.length; k++) { if (classes[k] == name) { idx = k; k = classes.length; } } if (idx > -1) { classes.splice(idx, 1); this.className = classes.join(" "); } return this; }; thingy.hasClass = function (name) { return !!this.className.match(new RegExp("\\s*" + name + "\\s*")); }; } return thingy; }, setMoviePath: function (path) { // set path to ZeroClipboard.swf this.moviePath = path; }, dispatch: function (id, eventName, args) { // receive event from flash movie, send to client var client = this.clients[id]; if (client) { client.receiveEvent(eventName, args); } }, register: function (id, client) { // register new client to receive events this.clients[id] = client; }, getDOMObjectPosition: function (obj, stopObj) { // get absolute coordinates for dom element var info = { left: 0, top: 0, width: obj.width ? obj.width : obj.offsetWidth, height: obj.height ? obj.height : obj.offsetHeight }; if (obj && (obj != stopObj)) { info.left += obj.offsetLeft; info.top += obj.offsetTop; } return info; }, Client: function (elem) { // constructor for new simple upload client this.handlers = {}; // unique ID this.id = ZeroClipboard.nextId++; this.movieId = "ZeroClipboardMovie_" + this.id; // register client with singleton to receive flash events ZeroClipboard.register(this.id, this); // create movie if (elem) this.glue(elem); } }; ZeroClipboard.Client.prototype = { id: 0, // unique ID for us ready: false, // whether movie is ready to receive events or not movie: null, // reference to movie object clipText: "", // text to copy to clipboard handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor cssEffects: true, // enable CSS mouse effects on dom container handlers: null, // user event handlers glue: function (elem, appendElem, stylesToAdd) { // glue to DOM element // elem can be ID or actual DOM element object this.domElement = ZeroClipboard.$(elem); // float just above object, or zIndex 99 if dom element isn't set var zIndex = 99; if (this.domElement.style.zIndex) { zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; } if (typeof(appendElem) === "string") { appendElem = ZeroClipboard.$(appendElem); } else if (typeof(appendElem) === "undefined") { appendElem = document.getElementsByTagName("body")[0]; } // find X/Y position of domElement var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); // create floating DIV above element this.div = document.createElement("div"); this.div.className = "zclip"; this.div.id = "zclip-" + this.movieId; $(this.domElement).data("zclipId", "zclip-" + this.movieId); var style = this.div.style; style.position = "absolute"; style.left = "" + box.left + "px"; style.top = "" + box.top + "px"; style.width = "" + box.width + "px"; style.height = "" + box.height + "px"; style.zIndex = zIndex; if (typeof(stylesToAdd) === "object") { for (addedStyle in stylesToAdd) { style[addedStyle] = stylesToAdd[addedStyle]; } } // style.backgroundColor = '#f00'; // debug appendElem.appendChild(this.div); this.div.innerHTML = this.getHTML(box.width, box.height); }, getHTML: function (width, height) { // return HTML for movie var html = ""; var flashvars = "id=" + this.id + "&width=" + width + "&height=" + height; if (navigator.userAgent.match(/MSIE/)) { // IE gets an OBJECT tag var protocol = location.href.match(/^https/i) ? "https://" : "http://"; html += "<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"" + protocol + "download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0\" width=\"" + width + "\" height=\"" + height + "\" id=\"" + this.movieId + "\" align=\"middle\"><param name=\"allowScriptAccess\" value=\"always\" /><param name=\"allowFullScreen\" value=\"false\" /><param name=\"movie\" value=\"" + ZeroClipboard.moviePath + "\" /><param name=\"loop\" value=\"false\" /><param name=\"menu\" value=\"false\" /><param name=\"quality\" value=\"best\" /><param name=\"bgcolor\" value=\"#ffffff\" /><param name=\"flashvars\" value=\"" + flashvars + "\"/><param name=\"wmode\" value=\"transparent\"/></object>"; } else { // all other browsers get an EMBED tag html += "<embed id=\"" + this.movieId + "\" src=\"" + ZeroClipboard.moviePath + "\" loop=\"false\" menu=\"false\" quality=\"best\" bgcolor=\"#ffffff\" width=\"" + width + "\" height=\"" + height + "\" name=\"" + this.movieId + "\" align=\"middle\" allowScriptAccess=\"always\" allowFullScreen=\"false\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" flashvars=\"" + flashvars + "\" wmode=\"transparent\" />"; } return html; }, hide: function () { // temporarily hide floater offscreen if (this.div) { this.div.style.left = "-2000px"; } }, show: function () { // show ourselves after a call to hide() this.reposition(); }, destroy: function () { // destroy control and floater if (this.domElement && this.div) { this.hide(); this.div.innerHTML = ""; var body = document.getElementsByTagName("body")[0]; try { body.removeChild(this.div); } catch (e) { } this.domElement = null; this.div = null; } }, reposition: function (elem) { // reposition our floating div, optionally to new container // warning: container CANNOT change size, only position if (elem) { this.domElement = ZeroClipboard.$(elem); if (!this.domElement) this.hide(); } if (this.domElement && this.div) { var box = ZeroClipboard.getDOMObjectPosition(this.domElement); var style = this.div.style; style.left = "" + box.left + "px"; style.top = "" + box.top + "px"; } }, setText: function (newText) { // set text to be copied to clipboard this.clipText = newText; if (this.ready) { this.movie.setText(newText); } }, addEventListener: function (eventName, func) { // add user event listener for event // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel eventName = eventName.toString().toLowerCase().replace(/^on/, ""); if (!this.handlers[eventName]) { this.handlers[eventName] = []; } this.handlers[eventName].push(func); }, setHandCursor: function (enabled) { // enable hand cursor (true), or default arrow cursor (false) this.handCursorEnabled = enabled; if (this.ready) { this.movie.setHandCursor(enabled); } }, setCSSEffects: function (enabled) { // enable or disable CSS effects on DOM container this.cssEffects = !!enabled; }, receiveEvent: function (eventName, args) { // receive event from flash eventName = eventName.toString().toLowerCase().replace(/^on/, ""); // special behavior for certain events switch (eventName) { case "load": // movie claims it is ready, but in IE this isn't always the case... // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function this.movie = document.getElementById(this.movieId); if (!this.movie) { var self = this; setTimeout(function () { self.receiveEvent("load", null); }, 1); return; } // firefox on pc needs a "kick" in order to set these in certain cases if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { var self = this; setTimeout(function () { self.receiveEvent("load", null); }, 100); this.ready = true; return; } this.ready = true; try { this.movie.setText(this.clipText); } catch (e) { } try { this.movie.setHandCursor(this.handCursorEnabled); } catch (e) { } break; case "mouseover": if (this.domElement && this.cssEffects) { this.domElement.addClass("hover"); if (this.recoverActive) { this.domElement.addClass("active"); } } break; case "mouseout": if (this.domElement && this.cssEffects) { this.recoverActive = false; if (this.domElement.hasClass("active")) { this.domElement.removeClass("active"); this.recoverActive = true; } this.domElement.removeClass("hover"); } break; case "mousedown": if (this.domElement && this.cssEffects) { this.domElement.addClass("active"); } break; case "mouseup": if (this.domElement && this.cssEffects) { this.domElement.removeClass("active"); this.recoverActive = false; } break; } // switch eventName if (this.handlers[eventName]) { for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { var func = this.handlers[eventName][idx]; if (typeof(func) === "function") { // actual function reference func(this, args); } else if ((typeof(func) === "object") && (func.length == 2)) { // PHP style object + method, i.e. [myObject, 'myMethod'] func[0][func[1]](this, args); } else if (typeof(func) === "string") { // name of function window[func](this, args); } } // foreach event handler defined } // user defined handler for event } }; }/** * 复制 * Created by GUY on 2016/2/16. * @class BI.ClipBoard * @extends BI.BasicButton */ BI.ClipBoard = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.ClipBoard.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-clipboard", copy: BI.emptyFn, afterCopy: BI.emptyFn }); }, _init: function () { BI.ClipBoard.superclass._init.apply(this, arguments); }, mounted: function () { var self = this, o = this.options; if (window.Clipboard) { this.clipboard = new Clipboard(this.element[0], { text: function () { return BI.isFunction(o.copy) ? o.copy() : o.copy; } }); this.clipboard.on("success", o.afterCopy); } else { this.element.zclip({ path: BI.resourceURL + "/ZeroClipboard.swf", copy: o.copy, beforeCopy: o.beforeCopy, afterCopy: o.afterCopy }); } }, destroyed: function () { this.clipboard && this.clipboard.destroy(); } }); BI.shortcut("bi.clipboard", BI.ClipBoard);/** * 自定义选色 * * Created by GUY on 2015/11/17. * @class BI.CustomColorChooser * @extends BI.Widget */ BI.CustomColorChooser = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CustomColorChooser.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-custom-color-chooser", width: 227, height: 245 }); }, _init: function () { BI.CustomColorChooser.superclass._init.apply(this, arguments); var self = this; this.editor = BI.createWidget({ type: "bi.color_picker_editor" }); this.editor.on(BI.ColorPickerEditor.EVENT_CHANGE, function () { self.setValue(this.getValue()); }); this.farbtastic = BI.createWidget({ type: "bi.farbtastic" }); this.farbtastic.on(BI.Farbtastic.EVENT_CHANGE, function () { self.setValue(this.getValue()); }); BI.createWidget({ type: "bi.vtape", element: this, items: [{ type: "bi.absolute", items: [{ el: this.editor, left: 10, top: 10, right: 10 }], height: 30 }, { type: "bi.absolute", items: [{ el: this.farbtastic, left: 15, right: 15, top: 10 }], height: 215 }] }); }, setValue: function (color) { this.editor.setValue(color); this.farbtastic.setValue(color); }, getValue: function () { return this.editor.getValue(); } }); BI.CustomColorChooser.EVENT_CHANGE = "CustomColorChooser.EVENT_CHANGE"; BI.shortcut("bi.custom_color_chooser", BI.CustomColorChooser);/** * 选色控件 * * Created by GUY on 2015/11/17. * @class BI.ColorChooser * @extends BI.Widget */ BI.ColorChooser = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ColorChooser.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-color-chooser", el: {} }); }, _init: function () { BI.ColorChooser.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(BI.extend({ type: "bi.color_chooser_trigger", width: o.width, height: o.height }, o.el)); this.colorPicker = BI.createWidget({ type: "bi.color_chooser_popup" }); this.combo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 1, el: this.trigger, popup: { el: this.colorPicker, stopPropagation: false, minWidth: 202 } }); var fn = function () { var color = self.colorPicker.getValue(); self.trigger.setValue(color); var colors = BI.string2Array(BI.Cache.getItem("colors") || ""); var que = new BI.Queue(8); que.fromArray(colors); que.remove(color); que.unshift(color); BI.Cache.setItem("colors", BI.array2String(que.toArray())); }; this.colorPicker.on(BI.ColorChooserPopup.EVENT_VALUE_CHANGE, function () { fn(); }); this.colorPicker.on(BI.ColorChooserPopup.EVENT_CHANGE, function () { fn(); self.combo.hideView(); }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.colorPicker.setStoreColors(BI.string2Array(BI.Cache.getItem("colors") || "")); }); this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { self.fireEvent(BI.ColorChooser.EVENT_CHANGE, arguments); }); }, isViewVisible: function () { return this.combo.isViewVisible(); }, hideView: function () { this.combo.hideView(); }, showView: function () { this.combo.showView(); }, setValue: function (color) { this.combo.setValue(color); }, getValue: function () { return this.colorPicker.getValue(); } }); BI.ColorChooser.EVENT_CHANGE = "ColorChooser.EVENT_CHANGE"; BI.shortcut("bi.color_chooser", BI.ColorChooser);/** * 选色控件 * * Created by GUY on 2015/11/17. * @class BI.ColorChooserPopup * @extends BI.Widget */ BI.ColorChooserPopup = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ColorChooserPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-color-chooser-popup", width: 200, height: 145 }); }, _init: function () { BI.ColorChooserPopup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.colorEditor = BI.createWidget({ type: "bi.color_picker_editor" }); this.colorEditor.on(BI.ColorPickerEditor.EVENT_CHANGE, function () { self.setValue(this.getValue()); self.fireEvent(BI.ColorChooserPopup.EVENT_VALUE_CHANGE, arguments); }); this.storeColors = BI.createWidget({ type: "bi.color_picker", items: [[{ value: "", disabled: true }, { value: "", disabled: true }, { value: "", disabled: true }, { value: "", disabled: true }, { value: "", disabled: true }, { value: "", disabled: true }, { value: "", disabled: true }, { value: "", disabled: true }]], width: 190, height: 25 }); this.storeColors.on(BI.ColorPicker.EVENT_CHANGE, function () { self.setValue(this.getValue()[0]); self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); }); this.colorPicker = BI.createWidget({ type: "bi.color_picker", width: 190, height: 50 }); this.colorPicker.on(BI.ColorPicker.EVENT_CHANGE, function () { self.setValue(this.getValue()[0]); self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); }); this.customColorChooser = BI.createWidget({ type: "bi.custom_color_chooser" }); var panel = BI.createWidget({ type: "bi.popup_panel", buttons: [BI.i18nText("BI-Basic_Cancel"), BI.i18nText("BI-Basic_Save")], title: BI.i18nText("BI-Custom_Color"), el: this.customColorChooser, stopPropagation: false, bgap: -1, rgap: 1, lgap: 1, minWidth: 227 }); this.more = BI.createWidget({ type: "bi.combo", direction: "right,top", isNeedAdjustHeight: false, el: { type: "bi.text_item", cls: "color-chooser-popup-more bi-list-item", textAlign: "center", height: 20, text: BI.i18nText("BI-Basic_More") + "..." }, popup: panel }); this.more.on(BI.Combo.EVENT_AFTER_POPUPVIEW, function () { self.customColorChooser.setValue(self.getValue()); }); panel.on(BI.PopupPanel.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { switch (index) { case 0: self.more.hideView(); break; case 1: self.setValue(self.customColorChooser.getValue()); self.more.hideView(); self.fireEvent(BI.ColorChooserPopup.EVENT_CHANGE, arguments); break; } }); BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: { type: "bi.absolute", cls: "bi-background bi-border-bottom", items: [{ el: this.colorEditor, left: 0, right: 0, top: 5 }] }, height: 30 }, { el: { type: "bi.absolute", items: [{ el: this.storeColors, left: 5, right: 5, top: 5 }] }, height: 30 }, { el: { type: "bi.absolute", items: [{ el: this.colorPicker, left: 5, right: 5, top: 5 }] }, height: 65 }, { el: this.more, height: 20 }] }); }, setStoreColors: function (colors) { if (BI.isArray(colors)) { var items = BI.map(colors, function (i, color) { return { value: color }; }); BI.count(colors.length, 8, function (i) { items.push({ value: "", disabled: true }); }); this.storeColors.populate([items]); } }, setValue: function (color) { this.colorEditor.setValue(color); this.colorPicker.setValue(color); this.storeColors.setValue(color); }, getValue: function () { return this.colorEditor.getValue(); } }); BI.ColorChooserPopup.EVENT_VALUE_CHANGE = "ColorChooserPopup.EVENT_VALUE_CHANGE"; BI.ColorChooserPopup.EVENT_CHANGE = "ColorChooserPopup.EVENT_CHANGE"; BI.shortcut("bi.color_chooser_popup", BI.ColorChooserPopup);/** * 选色控件 * * Created by GUY on 2015/11/17. * @class BI.ColorChooserTrigger * @extends BI.Trigger */ BI.ColorChooserTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { var conf = BI.ColorChooserTrigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-color-chooser-trigger", height: 30 }); }, _init: function () { BI.ColorChooserTrigger.superclass._init.apply(this, arguments); this.colorContainer = BI.createWidget({ type: "bi.layout", cls: "bi-card color-chooser-trigger-content" }); var down = BI.createWidget({ type: "bi.icon_button", disableSelected: true, cls: "icon-combo-down-icon trigger-triangle-font", width: 12, height: 8 }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.colorContainer, left: 3, right: 3, top: 3, bottom: 3 }, { el: down, right: 3, bottom: 3 }] }); if (this.options.value) { this.setValue(this.options.value); } }, setValue: function (color) { BI.ColorChooserTrigger.superclass.setValue.apply(this, arguments); if (color === "") { this.colorContainer.element.css("background-color", "").removeClass("trans-color-background").addClass("auto-color-background"); } else if (color === "transparent") { this.colorContainer.element.css("background-color", "").removeClass("auto-color-background").addClass("trans-color-background"); } else { this.colorContainer.element.css({"background-color": color}).removeClass("auto-color-background").removeClass("trans-color-background"); } } }); BI.ColorChooserTrigger.EVENT_CHANGE = "ColorChooserTrigger.EVENT_CHANGE"; BI.shortcut("bi.color_chooser_trigger", BI.ColorChooserTrigger);/** * 简单选色控件按钮 * * Created by GUY on 2015/11/16. * @class BI.ColorPickerButton * @extends BI.BasicButton */ BI.ColorPickerButton = BI.inherit(BI.BasicButton, { _defaultConfig: function () { var conf = BI.ColorPickerButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-color-picker-button bi-background bi-border-top bi-border-left" }); }, _init: function () { BI.ColorPickerButton.superclass._init.apply(this, arguments); var self = this, o = this.options; if (o.value) { this.element.css("background-color", o.value); var name = this.getName(); this.element.hover(function () { self._createMask(); if (self.isEnabled()) { BI.Maskers.show(name); } }, function () { if (!self.isSelected()) { BI.Maskers.hide(name); } }); } }, _createMask: function () { var o = this.options, name = this.getName(); if (this.isEnabled() && !BI.Maskers.has(name)) { var w = BI.Maskers.make(name, this, { offset: { left: -1, top: -1, right: -1, bottom: -1 } }); w.element.addClass("color-picker-button-mask").css("background-color", o.value); } }, setSelected: function (b) { BI.ColorPickerButton.superclass.setSelected.apply(this, arguments); if (b) { this._createMask(); } BI.Maskers[b ? "show" : "hide"](this.getName()); } }); BI.ColorPickerButton.EVENT_CHANGE = "ColorPickerButton.EVENT_CHANGE"; BI.shortcut("bi.color_picker_button", BI.ColorPickerButton);/** * 简单选色控件 * * Created by GUY on 2015/11/16. * @class BI.ColorPicker * @extends BI.Widget */ BI.ColorPicker = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ColorPicker.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-color-picker", items: null }); }, _items: [ [{ value: "#ffffff" }, { value: "#f2f2f2" }, { value: "#e5e5e5" }, { value: "#d9d9d9" }, { value: "#cccccc" }, { value: "#bfbfbf" }, { value: "#b2b2b2" }, { value: "#a6a6a6" }, { value: "#999999" }, { value: "#8c8c8c" }, { value: "#808080" }, { value: "#737373" }, { value: "#666666" }, { value: "#4d4d4d" }, { value: "#333333" }, { value: "#000000" }], [{ value: "#d8b5a6" }, { value: "#ff9e9a" }, { value: "#ffc17d" }, { value: "#f5e56b" }, { value: "#d8e698" }, { value: "#e0ebaf" }, { value: "#c3d825" }, { value: "#bce2e8" }, { value: "#85d3cd" }, { value: "#bce2e8" }, { value: "#a0d8ef" }, { value: "#89c3eb" }, { value: "#bbc8e6" }, { value: "#bbbcde" }, { value: "#d6b4cc" }, { value: "#fbc0d3" }], [{ value: "#bb9581" }, { value: "#f37d79" }, { value: "#fba74f" }, { value: "#ffdb4f" }, { value: "#c7dc68" }, { value: "#b0ca71" }, { value: "#99ab4e" }, { value: "#84b9cb" }, { value: "#00a3af" }, { value: "#2ca9e1" }, { value: "#0095d9" }, { value: "#4c6cb3" }, { value: "#8491c3" }, { value: "#a59aca" }, { value: "#cc7eb1" }, { value: "#e89bb4" }], [{ value: "#9d775f" }, { value: "#dd4b4b" }, { value: "#ef8b07" }, { value: "#fcc800" }, { value: "#aacf53" }, { value: "#82ae46" }, { value: "#69821b" }, { value: "#59b9c6" }, { value: "#2a83a2" }, { value: "#007bbb" }, { value: "#19448e" }, { value: "#274a78" }, { value: "#4a488e" }, { value: "#7058a3" }, { value: "#884898" }, { value: "#d47596" }] ], _init: function () { BI.ColorPicker.superclass._init.apply(this, arguments); var self = this, o = this.options; this.colors = BI.createWidget({ type: "bi.button_group", element: this, items: BI.createItems(o.items || this._items, { type: "bi.color_picker_button", once: false }), layouts: [{ type: "bi.grid" }] }); this.colors.on(BI.ButtonGroup.EVENT_CHANGE, function () { self.fireEvent(BI.ColorPicker.EVENT_CHANGE, arguments); }); }, populate: function (items) { var args = [].slice.call(arguments); args[0] = BI.createItems(items, { type: "bi.color_picker_button", once: false }); this.colors.populate.apply(this.colors, args); }, setValue: function (color) { this.colors.setValue(color); }, getValue: function () { return this.colors.getValue(); } }); BI.ColorPicker.EVENT_CHANGE = "ColorPicker.EVENT_CHANGE"; BI.shortcut("bi.color_picker", BI.ColorPicker);/** * 简单选色控件 * * Created by GUY on 2015/11/16. * @class BI.ColorPickerEditor * @extends BI.Widget */ BI.ColorPickerEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ColorPickerEditor.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-color-picker-editor", // width: 200, height: 20 }); }, _init: function () { BI.ColorPickerEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.colorShow = BI.createWidget({ type: "bi.layout", cls: "color-picker-editor-display bi-card", height: 20 }); var RGB = BI.createWidgets(BI.createItems([{text: "R"}, {text: "G"}, {text: "B"}], { type: "bi.label", cls: "color-picker-editor-label", width: 10, height: 20 })); var checker = function (v) { return BI.isNumeric(v) && (v | 0) >= 0 && (v | 0) <= 255; }; var Ws = BI.createWidgets([{}, {}, {}], { type: "bi.small_text_editor", cls: "color-picker-editor-input", validationChecker: checker, errorText: BI.i18nText("BI-Color_Picker_Error_Text"), allowBlank: true, value: 255, width: 32, height: 20 }); BI.each(Ws, function (i, w) { w.on(BI.TextEditor.EVENT_CHANGE, function () { if (self.R.isValid() && self.G.isValid() && self.B.isValid()) { self.colorShow.element.css("background-color", self.getValue()); self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); } }); }); this.R = Ws[0]; this.G = Ws[1]; this.B = Ws[2]; this.none = BI.createWidget({ type: "bi.checkbox", title: BI.i18nText("BI-Basic_Auto") }); this.none.on(BI.Checkbox.EVENT_CHANGE, function () { if (this.isSelected()) { self.lastColor = self.getValue(); self.setValue(""); } else { self.setValue(self.lastColor || "#000000"); } if (self.R.isValid() && self.G.isValid() && self.B.isValid()) { self.colorShow.element.css("background-color", self.getValue()); self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); } }); this.transparent = BI.createWidget({ type: "bi.checkbox", title: BI.i18nText("BI-Transparent_Color") }); this.transparent.on(BI.Checkbox.EVENT_CHANGE, function () { if (this.isSelected()) { self.lastColor = self.getValue(); self.setValue("transparent"); } else { self.setValue(self.lastColor || "#000000"); } if (self.R.isValid() && self.G.isValid() && self.B.isValid()) { self.colorShow.element.css("background-color", self.getValue()); self.fireEvent(BI.ColorPickerEditor.EVENT_CHANGE); } }); BI.createWidget({ type: "bi.htape", element: this, items: [{ el: this.colorShow, width: "fill" }, { el: RGB[0], lgap: 10, width: 16 }, { el: this.R, width: 32 }, { el: RGB[1], lgap: 10, width: 16 }, { el: this.G, width: 32 }, { el: RGB[2], lgap: 10, width: 16 }, { el: this.B, width: 32 }, { el: { type: "bi.center_adapt", items: [this.none] }, width: 18 }, { el: { type: "bi.center_adapt", items: [this.transparent] }, width: 18 }] }); }, setValue: function (color) { if (color === "transparent") { this.transparent.setSelected(true); this.none.setSelected(false); this.R.setValue(""); this.G.setValue(""); this.B.setValue(""); return; } if (!color) { color = ""; this.none.setSelected(true); } else { this.none.setSelected(false); } this.transparent.setSelected(false); this.colorShow.element.css("background-color", color); var json = BI.DOM.rgb2json(BI.DOM.hex2rgb(color)); this.R.setValue(BI.isNull(json.r) ? "" : json.r); this.G.setValue(BI.isNull(json.g) ? "" : json.g); this.B.setValue(BI.isNull(json.b) ? "" : json.b); }, getValue: function () { if (this.transparent.isSelected()) { return "transparent"; } return BI.DOM.rgb2hex(BI.DOM.json2rgb({ r: this.R.getValue(), g: this.G.getValue(), b: this.B.getValue() })); } }); BI.ColorPickerEditor.EVENT_CHANGE = "ColorPickerEditor.EVENT_CHANGE"; BI.shortcut("bi.color_picker_editor", BI.ColorPickerEditor);/** * 选色控件 * * Created by GUY on 2015/11/16. * @class BI.Farbtastic * @extends BI.Widget */ BI.Farbtastic = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.Farbtastic.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-farbtastic", width: 195, height: 195 }); }, _init: function () { BI.Farbtastic.superclass._init.apply(this, arguments); }, mounted: function () { var self = this; this.farbtastic = $.farbtastic(this.element, function (v) { self.fireEvent(BI.Farbtastic.EVENT_CHANGE, self.getValue(), self); }); }, setValue: function (color) { this.farbtastic.setColor(color); }, getValue: function () { return this.farbtastic.color; } }); BI.Farbtastic.EVENT_CHANGE = "Farbtastic.EVENT_CHANGE"; BI.shortcut("bi.farbtastic", BI.Farbtastic);/** * Farbtastic Color Picker 1.2 * © 2008 Steven Wittens * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ jQuery.fn.farbtastic = function (callback) { $.farbtastic(this, callback); return this; }; jQuery.farbtastic = function (container, callback) { var container = $(container).get(0); return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback)); }; jQuery._farbtastic = function (container, callback) { // Store farbtastic object var fb = this; // Insert markup $(container).html("<div class=\"farbtastic\"><div class=\"color\"></div><div class=\"wheel\"></div><div class=\"overlay\"></div><div class=\"h-marker marker\"></div><div class=\"sl-marker marker\"></div></div>"); var e = $(".farbtastic", container); fb.wheel = $(".wheel", container).get(0); // Dimensions fb.radius = 84; fb.square = 100; fb.width = 194; // Fix background PNGs in IE6 if (navigator.appVersion.match(/MSIE [0-6]\./)) { $("*", e).each(function () { if (this.currentStyle.backgroundImage != "none") { var image = this.currentStyle.backgroundImage; image = this.currentStyle.backgroundImage.substring(5, image.length - 2); $(this).css({ backgroundImage: "none", filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')" }); } }); } /** * Link to the given element(s) or callback. */ fb.linkTo = function (callback) { // Unbind previous nodes if (typeof fb.callback === "object") { $(fb.callback).unbind("keyup", fb.updateValue); } // Reset color fb.color = null; // Bind callback or elements if (typeof callback === "function") { fb.callback = callback; } else if (typeof callback === "object" || typeof callback === "string") { fb.callback = $(callback); fb.callback.bind("keyup", fb.updateValue); if (fb.callback.get(0).value) { fb.setColor(fb.callback.get(0).value); } } return this; }; fb.updateValue = function (event) { if (this.value && this.value != fb.color) { fb.setColor(this.value); } }; /** * Change color with HTML syntax #123456 */ fb.setColor = function (color) { var unpack = fb.unpack(color); if (fb.color != color && unpack) { fb.color = color; fb.rgb = unpack; fb.hsl = fb.RGBToHSL(fb.rgb); fb.updateDisplay(); } return this; }; /** * Change color with HSL triplet [0..1, 0..1, 0..1] */ fb.setHSL = function (hsl) { fb.hsl = hsl; fb.rgb = fb.HSLToRGB(hsl); fb.color = fb.pack(fb.rgb); fb.updateDisplay(); return this; }; // /////////////////////////////////////////////////// /** * Retrieve the coordinates of the given event relative to the center * of the widget. */ fb.widgetCoords = function (event) { var x, y; var el = event.target || event.srcElement; var reference = fb.wheel; if (typeof event.offsetX !== "undefined") { // Use offset coordinates and find common offsetParent var pos = { x: event.offsetX, y: event.offsetY }; // Send the coordinates upwards through the offsetParent chain. var e = el; while (e) { e.mouseX = pos.x; e.mouseY = pos.y; pos.x += e.offsetLeft; pos.y += e.offsetTop; e = e.offsetParent; } // Look for the coordinates starting from the wheel widget. var e = reference; var offset = { x: 0, y: 0 }; while (e) { if (typeof e.mouseX !== "undefined") { x = e.mouseX - offset.x; y = e.mouseY - offset.y; break; } offset.x += e.offsetLeft; offset.y += e.offsetTop; e = e.offsetParent; } // Reset stored coordinates e = el; while (e) { e.mouseX = undefined; e.mouseY = undefined; e = e.offsetParent; } } else { // Use absolute coordinates var pos = fb.absolutePosition(reference); x = (event.pageX || 0 * (event.clientX + $("html").get(0).scrollLeft)) - pos.x; y = (event.pageY || 0 * (event.clientY + $("html").get(0).scrollTop)) - pos.y; } // Subtract distance to middle return { x: x - fb.width / 2, y: y - fb.width / 2 }; }; /** * Mousedown handler */ fb.click = function (event) { // Capture mouse // if (!document.dragging) { // $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup); // document.dragging = true; // } // Check which area is being dragged var pos = fb.widgetCoords(event); fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square; // Process fb.mousemove(event); return false; }; /** * Mousemove handler */ fb.mousemove = function (event) { // Get coordinates relative to color picker center var pos = fb.widgetCoords(event); // Set new HSL parameters if (fb.circleDrag) { var hue = Math.atan2(pos.x, -pos.y) / 6.28; if (hue < 0) hue += 1; fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]); } else { var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5)); var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5)); fb.setHSL([fb.hsl[0], sat, lum]); } return false; }; /** * Mouseup handler */ // fb.mouseup = function () { // // Uncapture mouse // $(document).unbind('mousemove', fb.mousemove); // $(document).unbind('mouseup', fb.mouseup); // document.dragging = false; // } /** * Update the markers and styles */ fb.updateDisplay = function () { // Markers var angle = fb.hsl[0] * 6.28; $(".h-marker", e).css({ left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + "px", top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + "px" }); $(".sl-marker", e).css({ left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + "px", top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + "px" }); // Saturation/Luminance gradient $(".color", e).css("backgroundColor", fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5]))); // Linked elements or callback if (typeof fb.callback === "object") { // Set background/foreground color $(fb.callback).css({ backgroundColor: fb.color, color: fb.hsl[2] > 0.5 ? "#000" : "#fff" }); // Change linked value $(fb.callback).each(function () { if (this.value && this.value != fb.color) { this.value = fb.color; } }); } else if (typeof fb.callback === "function") { fb.callback.call(fb, fb.color); } }; /** * Get absolute position of element */ fb.absolutePosition = function (el) { var r = { x: el.offsetLeft, y: el.offsetTop }; // Resolve relative to offsetParent if (el.offsetParent) { var tmp = fb.absolutePosition(el.offsetParent); r.x += tmp.x; r.y += tmp.y; } return r; }; /* Various color utility functions */ fb.pack = function (rgb) { var r = Math.round(rgb[0] * 255); var g = Math.round(rgb[1] * 255); var b = Math.round(rgb[2] * 255); return "#" + (r < 16 ? "0" : "") + r.toString(16) + (g < 16 ? "0" : "") + g.toString(16) + (b < 16 ? "0" : "") + b.toString(16); }; fb.unpack = function (color) { if (color.length == 7) { return [parseInt("0x" + color.substring(1, 3)) / 255, parseInt("0x" + color.substring(3, 5)) / 255, parseInt("0x" + color.substring(5, 7)) / 255]; } else if (color.length == 4) { return [parseInt("0x" + color.substring(1, 2)) / 15, parseInt("0x" + color.substring(2, 3)) / 15, parseInt("0x" + color.substring(3, 4)) / 15]; } }; fb.HSLToRGB = function (hsl) { var m1, m2, r, g, b; var h = hsl[0], s = hsl[1], l = hsl[2]; m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s; m1 = l * 2 - m2; return [this.hueToRGB(m1, m2, h + 0.33333), this.hueToRGB(m1, m2, h), this.hueToRGB(m1, m2, h - 0.33333)]; }; fb.hueToRGB = function (m1, m2, h) { h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; if (h * 2 < 1) return m2; if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; return m1; }; fb.RGBToHSL = function (rgb) { var min, max, delta, h, s, l; var r = rgb[0], g = rgb[1], b = rgb[2]; min = Math.min(r, Math.min(g, b)); max = Math.max(r, Math.max(g, b)); delta = max - min; l = (min + max) / 2; s = 0; if (l > 0 && l < 1) { s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); } h = 0; if (delta > 0) { if (max == r && max != g) h += (g - b) / delta; if (max == g && max != b) h += (2 + (b - r) / delta); if (max == b && max != r) h += (4 + (r - g) / delta); h /= 6; } return [h, s, l]; }; // Install mousedown handler (the others are set on the document on-demand) $("*", e).click(fb.click); // Init color fb.setColor("#000000"); // Set linked elements/callback if (callback) { fb.linkTo(callback); } };/** * Created by GUY on 2017/2/8. * * @class BI.BubbleCombo * @extends BI.Widget */ BI.BubbleCombo = BI.inherit(BI.Widget, { _const: { TRIANGLE_LENGTH: 6 }, _defaultConfig: function () { return BI.extend(BI.BubbleCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-bubble-combo", trigger: "click", toggle: true, direction: "bottom", // top||bottom||left||right||top,left||top,right||bottom,left||bottom,right isDefaultInit: false, destroyWhenHide: false, isNeedAdjustHeight: true, // 是否需要高度调整 isNeedAdjustWidth: true, stopPropagation: false, adjustLength: 0, // 调整的距离 // adjustXOffset: 0, // adjustYOffset: 10, hideChecker: BI.emptyFn, offsetStyle: "left", // left,right,center el: {}, popup: {} }); }, _init: function () { BI.BubbleCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.combo = BI.createWidget({ type: "bi.combo", element: this, trigger: o.trigger, toggle: o.toggle, direction: o.direction, isDefaultInit: o.isDefaultInit, destroyWhenHide: o.destroyWhenHide, isNeedAdjustHeight: o.isNeedAdjustHeight, isNeedAdjustWidth: o.isNeedAdjustWidth, adjustLength: this._getAdjustLength(), stopPropagation: o.stopPropagation, adjustXOffset: 0, adjustYOffset: 0, hideChecker: o.hideChecker, offsetStyle: o.offsetStyle, el: o.el, popup: BI.extend({ type: "bi.bubble_popup_view" }, o.popup) }); this.combo.on(BI.Combo.EVENT_TRIGGER_CHANGE, function () { self.fireEvent(BI.BubbleCombo.EVENT_TRIGGER_CHANGE, arguments); }); this.combo.on(BI.Combo.EVENT_CHANGE, function () { self.fireEvent(BI.BubbleCombo.EVENT_CHANGE, arguments); }); this.combo.on(BI.Combo.EVENT_EXPAND, function () { self.fireEvent(BI.BubbleCombo.EVENT_EXPAND, arguments); }); this.combo.on(BI.Combo.EVENT_COLLAPSE, function () { self.fireEvent(BI.BubbleCombo.EVENT_COLLAPSE, arguments); }); this.combo.on(BI.Combo.EVENT_AFTER_INIT, function () { self.fireEvent(BI.BubbleCombo.EVENT_AFTER_INIT, arguments); }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW, arguments); }); this.combo.on(BI.Combo.EVENT_AFTER_POPUPVIEW, function () { self._showTriangle(); self.fireEvent(BI.BubbleCombo.EVENT_AFTER_POPUPVIEW, arguments); }); this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { self._hideTriangle(); self.fireEvent(BI.BubbleCombo.EVENT_BEFORE_HIDEVIEW, arguments); }); this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { self.fireEvent(BI.BubbleCombo.EVENT_AFTER_HIDEVIEW, arguments); }); }, _getAdjustLength: function () { return this._const.TRIANGLE_LENGTH + this.options.adjustLength; }, _createTriangle: function (direction) { var pos = {}, op = {}; var adjustLength = this.options.adjustLength; var offset = this.element.offset(); var left = offset.left, right = offset.left + this.element.outerWidth(); var top = offset.top, bottom = offset.top + this.element.outerHeight(); switch (direction) { case "left": pos = { top: top, height: this.element.outerHeight(), left: left - adjustLength - this._const.TRIANGLE_LENGTH }; op = {width: this._const.TRIANGLE_LENGTH}; break; case "right": pos = { top: top, height: this.element.outerHeight(), left: right + adjustLength }; op = {width: this._const.TRIANGLE_LENGTH}; break; case "top": pos = { left: left, width: this.element.outerWidth(), top: top - adjustLength - this._const.TRIANGLE_LENGTH }; op = {height: this._const.TRIANGLE_LENGTH}; break; case "bottom": pos = { left: left, width: this.element.outerWidth(), top: bottom + adjustLength }; op = {height: this._const.TRIANGLE_LENGTH}; break; default: break; } this.triangle && this.triangle.destroy(); this.triangle = BI.createWidget(op, { type: "bi.center_adapt", cls: "button-combo-triangle-wrapper", items: [{ type: "bi.layout", cls: "bubble-combo-triangle-" + direction + " bi-high-light-border" }] }); pos.el = this.triangle; BI.createWidget({ type: "bi.absolute", element: this, items: [pos] }); }, _createLeftTriangle: function () { this._createTriangle("left"); }, _createRightTriangle: function () { this._createTriangle("right"); }, _createTopTriangle: function () { this._createTriangle("top"); }, _createBottomTriangle: function () { this._createTriangle("bottom"); }, _showTriangle: function () { var pos = this.combo.getPopupPosition(); switch (pos.dir) { case "left,top": case "left,bottom": this._createLeftTriangle(); this.combo.getView().showLine("right"); break; case "right,top": case "right,bottom": this._createRightTriangle(); this.combo.getView().showLine("left"); break; case "top,left": case "top,right": this._createTopTriangle(); this.combo.getView().showLine("bottom"); break; case "bottom,left": case "bottom,right": this._createBottomTriangle(); this.combo.getView().showLine("top"); break; } }, _hideTriangle: function () { this.triangle && this.triangle.destroy(); this.triangle = null; this.combo.getView() && this.combo.getView().hideLine(); }, hideView: function () { this._hideTriangle(); this.combo && this.combo.hideView(); }, showView: function () { this.combo && this.combo.showView(); }, isViewVisible: function () { return this.combo.isViewVisible(); } }); BI.BubbleCombo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; BI.BubbleCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.BubbleCombo.EVENT_EXPAND = "EVENT_EXPAND"; BI.BubbleCombo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; BI.BubbleCombo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; BI.BubbleCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.BubbleCombo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; BI.BubbleCombo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; BI.BubbleCombo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; BI.shortcut("bi.bubble_combo", BI.BubbleCombo);/** * Created by GUY on 2017/2/8. * * @class BI.BubblePopupView * @extends BI.PopupView */ BI.BubblePopupView = BI.inherit(BI.PopupView, { _defaultConfig: function () { var config = BI.BubblePopupView.superclass._defaultConfig.apply(this, arguments); return BI.extend(config, { baseCls: config.baseCls + " bi-bubble-popup-view" }); }, _init: function () { BI.BubblePopupView.superclass._init.apply(this, arguments); }, showLine: function (direction) { var pos = {}, op = {}; switch (direction) { case "left": pos = { top: 0, bottom: 0, left: -1 }; op = {width: 3}; break; case "right": pos = { top: 0, bottom: 0, right: -1 }; op = {width: 3}; break; case "top": pos = { left: 0, right: 0, top: -1 }; op = {height: 3}; break; case "bottom": pos = { left: 0, right: 0, bottom: -1 }; op = {height: 3}; break; default: break; } this.line = BI.createWidget(op, { type: "bi.layout", cls: "bubble-popup-line bi-high-light-background" }); pos.el = this.line; BI.createWidget({ type: "bi.absolute", element: this, items: [pos] }); }, hideLine: function () { this.line && this.line.destroy(); } }); BI.shortcut("bi.bubble_popup_view", BI.BubblePopupView); /** * Created by GUY on 2017/2/8. * * @class BI.BubblePopupBarView * @extends BI.BubblePopupView */ BI.BubblePopupBarView = BI.inherit(BI.BubblePopupView, { _defaultConfig: function () { return BI.extend(BI.BubblePopupBarView.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-bubble-bar-popup-view", buttons: [{value: BI.i18nText(BI.i18nText("BI-Basic_Sure"))}, {value: BI.i18nText("BI-Basic_Cancel"), level: "ignore"}] }); }, _init: function () { BI.BubblePopupBarView.superclass._init.apply(this, arguments); }, _createToolBar: function () { var o = this.options, self = this; var items = []; BI.each(o.buttons.reverse(), function (i, buttonOpt) { if(BI.isWidget(buttonOpt)) { items.push(buttonOpt); }else{ items.push(BI.extend({ type: "bi.button", height: 30, handler: function (v) { self.fireEvent(BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON, v); } }, buttonOpt)); } }); return BI.createWidget({ type: "bi.right_vertical_adapt", height: 40, hgap: 10, bgap: 10, items: items }); } }); BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; BI.shortcut("bi.bubble_bar_popup_view", BI.BubblePopupBarView);/** * Created by Young's on 2016/4/28. */ BI.EditorIconCheckCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.EditorIconCheckCombo.superclass._defaultConfig.apply(this, arguments), { baseClass: "bi-check-editor-combo", width: 100, height: 24, chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: true, watermark: "", errorText: "" }); }, _init: function () { BI.EditorIconCheckCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.editor_trigger", items: o.items, height: o.height, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.trigger.on(BI.EditorTrigger.EVENT_CHANGE, function () { self.popup.setValue(this.getValue()); self.fireEvent(BI.EditorIconCheckCombo.EVENT_CHANGE); }); this.popup = BI.createWidget({ type: "bi.text_value_check_combo_popup", chooseType: o.chooseType, items: o.items }); this.popup.on(BI.TextValueCheckComboPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.editorIconCheckCombo.hideView(); self.fireEvent(BI.EditorIconCheckCombo.EVENT_CHANGE); }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editorIconCheckCombo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup, maxHeight: 300 } }); }, setValue: function (v) { this.editorIconCheckCombo.setValue(v); }, getValue: function () { return this.trigger.getValue(); }, populate: function (items) { this.options.items = items; this.editorIconCheckCombo.populate(items); } }); BI.EditorIconCheckCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.editor_icon_check_combo", BI.EditorIconCheckCombo);/** * Created by GUY on 2016/2/2. * * @class BI.IconCombo * @extend BI.Widget */ BI.IconCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.IconCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-icon-combo", width: 24, height: 24, iconClass: "", el: {}, popup: {}, minWidth: 100, maxWidth: "auto", maxHeight: 300, direction: "bottom", adjustLength: 3, // 调整的距离 adjustXOffset: 0, adjustYOffset: 0, offsetStyle: "left", chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE }); }, _init: function () { BI.IconCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(o.el, { type: "bi.icon_combo_trigger", iconClass: o.iconClass, title: o.title, items: o.items, width: o.width, height: o.height, iconWidth: o.iconWidth, iconHeight: o.iconHeight }); this.popup = BI.createWidget(o.popup, { type: "bi.icon_combo_popup", chooseType: o.chooseType, items: o.items }); this.popup.on(BI.IconComboPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.iconCombo.hideView(); self.fireEvent(BI.IconCombo.EVENT_CHANGE); }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.iconCombo = BI.createWidget({ type: "bi.combo", element: this, direction: o.direction, trigger: o.trigger, container: o.container, adjustLength: o.adjustLength, adjustXOffset: o.adjustXOffset, adjustYOffset: o.adjustYOffset, offsetStyle: o.offsetStyle, el: this.trigger, popup: { el: this.popup, maxWidth: o.maxWidth, maxHeight: o.maxHeight, minWidth: o.minWidth } }); }, showView: function () { this.iconCombo.showView(); }, hideView: function () { this.iconCombo.hideView(); }, setValue: function (v) { this.iconCombo.setValue(v); }, getValue: function () { return this.iconCombo.getValue(); }, populate: function (items) { this.options.items = items; this.iconCombo.populate(items); } }); BI.IconCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.icon_combo", BI.IconCombo);/** * Created by GUY on 2016/2/2. * * @class BI.IconComboPopup * @extend BI.Pane */ BI.IconComboPopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.IconComboPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi.icon-combo-popup", chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE }); }, _init: function () { BI.IconComboPopup.superclass._init.apply(this, arguments); var o = this.options, self = this; this.popup = BI.createWidget({ type: "bi.button_group", items: BI.createItems(o.items, { type: "bi.single_select_icon_text_item", height: 30 }), chooseType: o.chooseType, layouts: [{ type: "bi.vertical" }] }); this.popup.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.IconComboPopup.EVENT_CHANGE, val, obj); } }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.popup] }); }, populate: function (items) { BI.IconComboPopup.superclass.populate.apply(this, arguments); items = BI.createItems(items, { type: "bi.single_select_icon_text_item", height: 30 }); this.popup.populate(items); }, getValue: function () { return this.popup.getValue(); }, setValue: function (v) { this.popup.setValue(v); } }); BI.IconComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.icon_combo_popup", BI.IconComboPopup);/** * Created by GUY on 2016/2/2. * * @class BI.IconComboTrigger * @extend BI.Widget */ BI.IconComboTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend(BI.IconComboTrigger.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-icon-combo-trigger", el: {}, items: [], iconClass: "", width: 25, height: 25, isShowDown: true }); }, _init: function () { BI.IconComboTrigger.superclass._init.apply(this, arguments); var o = this.options, self = this; this.button = BI.createWidget(o.el, { type: "bi.icon_change_button", cls: "icon-combo-trigger-icon " + o.iconClass, disableSelected: true, width: o.width, height: o.height, iconWidth: o.iconWidth, iconHeight: o.iconHeight }); this.down = BI.createWidget({ type: "bi.icon_button", disableSelected: true, cls: "icon-combo-down-icon trigger-triangle-font", width: 12, height: 8 }); this.down.setVisible(o.isShowDown); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.button, left: 0, right: 0, top: 0, bottom: 0 }, { el: this.down, right: 0, bottom: 0 }] }); if (BI.isKey(o.value)) { this.setValue(o.value); } }, populate: function (items) { var o = this.options; this.options.items = items || []; this.button.setIcon(o.iconClass); this.button.setSelected(false); this.down.setSelected(false); }, setValue: function (v) { BI.IconComboTrigger.superclass.setValue.apply(this, arguments); var o = this.options; var iconClass = ""; v = BI.isArray(v) ? v[0] : v; if (BI.any(this.options.items, function (i, item) { if (v === item.value) { iconClass = item.iconClass; return true; } })) { this.button.setIcon(iconClass); this.button.setSelected(true); this.down.setSelected(true); } else { this.button.setIcon(o.iconClass); this.button.setSelected(false); this.down.setSelected(false); } } }); BI.IconComboTrigger.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.icon_combo_trigger", BI.IconComboTrigger);/** * Created by Windy on 2017/12/12. * combo : icon + text + icon, popup : icon + text */ BI.IconTextValueCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.IconTextValueCombo.superclass._defaultConfig.apply(this, arguments), { baseClass: "bi-icon-text-value-combo", height: 30, value: "", el: {} }); }, _init: function () { BI.IconTextValueCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(o.el, { type: "bi.select_icon_text_trigger", items: o.items, height: o.height, text: o.text, value: o.value }); this.popup = BI.createWidget({ type: "bi.icon_text_value_combo_popup", items: o.items }); this.popup.on(BI.IconTextValueComboPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.textIconCombo.hideView(); self.fireEvent(BI.IconTextValueCombo.EVENT_CHANGE, arguments); }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.textIconCombo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup, maxHeight: 300 } }); if (BI.isKey(o.value)) { this.setValue(o.value); } }, setValue: function (v) { this.textIconCombo.setValue(v); }, getValue: function () { return this.textIconCombo.getValue(); }, populate: function (items) { this.options.items = items; this.textIconCombo.populate(items); } }); BI.IconTextValueCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.icon_text_value_combo", BI.IconTextValueCombo);/** * Created by Windy on 2017/12/12. */ BI.IconTextValueComboPopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.IconTextValueComboPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-icon-text-icon-popup" }); }, _init: function () { BI.IconTextValueComboPopup.superclass._init.apply(this, arguments); var o = this.options, self = this; this.popup = BI.createWidget({ type: "bi.button_group", items: BI.createItems(o.items, { type: "bi.single_select_icon_text_item", height: 30 }), chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, layouts: [{ type: "bi.vertical" }] }); this.popup.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.IconTextValueComboPopup.EVENT_CHANGE, val, obj); } }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.popup] }); }, populate: function (items) { BI.IconTextValueComboPopup.superclass.populate.apply(this, arguments); items = BI.createItems(items, { type: "bi.single_select_icon_text_item", height: 30 }); this.popup.populate(items); }, getValue: function () { return this.popup.getValue(); }, setValue: function (v) { this.popup.setValue(v); } }); BI.IconTextValueComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.icon_text_value_combo_popup", BI.IconTextValueComboPopup);/** * 单选combo * * @class BI.StaticCombo * @extend BI.Widget */ BI.StaticCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.StaticCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-static-combo", height: 24, text: "", el: {}, items: [], chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE }); }, _init: function () { BI.StaticCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(o.el, { type: "bi.text_icon_item", cls: "bi-select-text-trigger bi-border pull-down-font", text: o.text, value: o.value, readonly: true, textLgap: 5, height: o.height - 2 }); this.popup = BI.createWidget({ type: "bi.text_value_combo_popup", textAlign: o.textAlign, chooseType: o.chooseType, items: o.items, value: o.value }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.popup.on(BI.TextValueComboPopup.EVENT_CHANGE, function () { self.combo.hideView(); self.fireEvent(BI.StaticCombo.EVENT_CHANGE, arguments); }); this.combo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup } }); }, populate: function (items) { this.combo.populate(items); }, setValue: function (v) { this.combo.setValue(v); }, getValue: function () { return this.combo.getValue(); } }); BI.StaticCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.static_combo", BI.StaticCombo);/** * @class BI.TextValueCheckCombo * @extend BI.Widget * combo : text + icon, popup : check + text */ BI.TextValueCheckCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.TextValueCheckCombo.superclass._defaultConfig.apply(this, arguments), { baseClass: "bi-text-value-check-combo", width: 100, height: 24, chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, value: "" }); }, _init: function () { BI.TextValueCheckCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.select_text_trigger", items: o.items, height: o.height }); this.popup = BI.createWidget({ type: "bi.text_value_check_combo_popup", chooseType: o.chooseType, items: o.items }); this.popup.on(BI.TextValueCheckComboPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.textIconCheckCombo.hideView(); self.fireEvent(BI.TextValueCheckCombo.EVENT_CHANGE); }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.textIconCheckCombo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup, maxHeight: 300 } }); if (BI.isKey(o.value)) { this.setValue(o.value); } }, setTitle: function (title) { this.trigger.setTitle(title); }, setValue: function (v) { this.textIconCheckCombo.setValue(v); }, setWarningTitle: function (title) { this.trigger.setWarningTitle(title); }, getValue: function () { return this.textIconCheckCombo.getValue(); }, populate: function (items) { this.options.items = items; this.textIconCheckCombo.populate(items); } }); BI.TextValueCheckCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.text_value_check_combo", BI.TextValueCheckCombo);/** * @class BI.SmallTextValueCheckCombo * @extend BI.Widget * combo : text + icon, popup : check + text */ BI.SmallTextValueCheckCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SmallTextValueCheckCombo.superclass._defaultConfig.apply(this, arguments), { width: 100, height: 24, chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, text: "" }); }, _init: function () { BI.SmallTextValueCheckCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.small_select_text_trigger", items: o.items, height: o.height, text: o.text }); this.popup = BI.createWidget({ type: "bi.text_value_check_combo_popup", chooseType: o.chooseType, items: o.items }); this.popup.on(BI.TextValueCheckComboPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.SmallTextIconCheckCombo.hideView(); self.fireEvent(BI.SmallTextValueCheckCombo.EVENT_CHANGE); }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.SmallTextIconCheckCombo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup, maxHeight: 300 } }); }, setValue: function (v) { this.SmallTextIconCheckCombo.setValue(v); }, getValue: function () { return this.SmallTextIconCheckCombo.getValue(); }, populate: function (items) { this.options.items = items; this.SmallTextIconCheckCombo.populate(items); } }); BI.SmallTextValueCheckCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.small_text_value_check_combo", BI.SmallTextValueCheckCombo);BI.TextValueCheckComboPopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.TextValueCheckComboPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-text-icon-popup", chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE }); }, _init: function () { BI.TextValueCheckComboPopup.superclass._init.apply(this, arguments); var o = this.options, self = this; this.popup = BI.createWidget({ type: "bi.button_group", items: this._formatItems(o.items), chooseType: o.chooseType, layouts: [{ type: "bi.vertical" }] }); this.popup.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.TextValueCheckComboPopup.EVENT_CHANGE, val, obj); } }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.popup] }); }, _formatItems: function (items) { return BI.map(items, function (i, item) { return BI.extend({ type: "bi.icon_text_item", cls: "item-check-font bi-list-item", height: 30 }, item); }); }, populate: function (items) { BI.TextValueCheckComboPopup.superclass.populate.apply(this, arguments); this.popup.populate(this._formatItems(items)); }, getValue: function () { return this.popup.getValue(); }, setValue: function (v) { this.popup.setValue(v); } }); BI.TextValueCheckComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.text_value_check_combo_popup", BI.TextValueCheckComboPopup);/** * @class BI.TextValueCombo * @extend BI.Widget * combo : text + icon, popup : text * 参见场景dashboard布局方式选择 */ BI.TextValueCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.TextValueCombo.superclass._defaultConfig.apply(this, arguments), { baseClass: "bi-text-value-combo", height: 30, chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, value: "", el: {} }); }, _init: function () { BI.TextValueCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(o.el, { type: "bi.select_text_trigger", items: o.items, height: o.height, text: o.value }); this.popup = BI.createWidget({ type: "bi.text_value_combo_popup", chooseType: o.chooseType, items: o.items }); this.popup.on(BI.TextValueComboPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.textIconCombo.hideView(); self.fireEvent(BI.TextValueCombo.EVENT_CHANGE, arguments); }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.textIconCombo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup, maxHeight: 300 } }); if (BI.isKey(o.value)) { this.setValue(o.value); } }, setValue: function (v) { this.textIconCombo.setValue(v); }, getValue: function () { return this.textIconCombo.getValue(); }, populate: function (items) { this.options.items = items; this.textIconCombo.populate(items); } }); BI.TextValueCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.text_value_combo", BI.TextValueCombo);/** * @class BI.SmallTextValueCombo * @extend BI.Widget * combo : text + icon, popup : text * 参见场景dashboard布局方式选择 */ BI.SmallTextValueCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SmallTextValueCombo.superclass._defaultConfig.apply(this, arguments), { width: 100, height: 24, chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, el: {}, text: "" }); }, _init: function () { BI.SmallTextValueCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(o.el, { type: "bi.small_select_text_trigger", items: o.items, height: o.height, text: o.text }); this.popup = BI.createWidget({ type: "bi.text_value_combo_popup", chooseType: o.chooseType, items: o.items }); this.popup.on(BI.TextValueComboPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.SmallTextValueCombo.hideView(); self.fireEvent(BI.SmallTextValueCombo.EVENT_CHANGE); }); this.popup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.SmallTextValueCombo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup, maxHeight: 300 } }); }, setValue: function (v) { this.SmallTextValueCombo.setValue(v); }, getValue: function () { return this.SmallTextValueCombo.getValue(); }, populate: function (items) { this.options.items = items; this.SmallTextValueCombo.populate(items); } }); BI.SmallTextValueCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.small_text_value_combo", BI.SmallTextValueCombo);BI.TextValueComboPopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.TextValueComboPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-text-icon-popup", chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE }); }, _init: function () { BI.TextValueComboPopup.superclass._init.apply(this, arguments); var o = this.options, self = this; this.popup = BI.createWidget({ type: "bi.button_group", items: BI.createItems(o.items, { type: "bi.single_select_item", textAlign: o.textAlign, height: 30 }), chooseType: o.chooseType, layouts: [{ type: "bi.vertical" }], value: o.value }); this.popup.on(BI.Controller.EVENT_CHANGE, function (type, val, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.TextValueComboPopup.EVENT_CHANGE, val, obj); } }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.popup] }); }, populate: function (items) { BI.TextValueComboPopup.superclass.populate.apply(this, arguments); items = BI.createItems(items, { type: "bi.single_select_item", height: 30 }); this.popup.populate(items); }, getValue: function () { return this.popup.getValue(); }, setValue: function (v) { this.popup.setValue(v); } }); BI.TextValueComboPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.text_value_combo_popup", BI.TextValueComboPopup);/** * @class BI.TextValueDownListCombo * @extend BI.Widget */ BI.TextValueDownListCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.TextValueDownListCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-text-value-down-list-combo", height: 30 }); }, _init: function () { BI.TextValueDownListCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this._createValueMap(); this.trigger = BI.createWidget({ type: "bi.down_list_select_text_trigger", height: o.height, items: o.items }); this.combo = BI.createWidget({ type: "bi.down_list_combo", element: this, chooseType: BI.Selection.Single, adjustLength: 2, height: o.height, el: this.trigger, items: BI.deepClone(o.items) }); this.combo.on(BI.DownListCombo.EVENT_CHANGE, function () { self.setValue(self.combo.getValue()[0].value); self.fireEvent(BI.TextValueDownListCombo.EVENT_CHANGE); }); this.combo.on(BI.DownListCombo.EVENT_SON_VALUE_CHANGE, function () { self.setValue(self.combo.getValue()[0].childValue); self.fireEvent(BI.TextValueDownListCombo.EVENT_CHANGE); }); }, _createValueMap: function () { var self = this; this.valueMap = {}; BI.each(BI.flatten(this.options.items), function (idx, item) { if (BI.has(item, "el")) { BI.each(item.children, function (id, it) { self.valueMap[it.value] = {value: item.el.value, childValue: it.value}; }); } else { self.valueMap[item.value] = {value: item.value}; } }); }, setValue: function (v) { v = this.valueMap[v]; this.combo.setValue([v]); this.trigger.setValue(v.childValue || v.value); }, getValue: function () { var v = this.combo.getValue()[0]; return [v.childValue || v.value]; }, populate: function (items) { this.options.items = BI.flatten(items); this.combo.populate(items); this._createValueMap(); } }); BI.TextValueDownListCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.text_value_down_list_combo", BI.TextValueDownListCombo);/** * 选择字段trigger, downlist专用 * 显示形式为 父亲值(儿子值) * * @class BI.DownListSelectTextTrigger * @extends BI.Trigger */ BI.DownListSelectTextTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend(BI.DownListSelectTextTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-down-list-select-text-trigger", height: 24, text: "" }); }, _init: function () { BI.DownListSelectTextTrigger.superclass._init.apply(this, arguments); var o = this.options; this.trigger = BI.createWidget({ type: "bi.select_text_trigger", element: this, height: o.height, items: this._formatItemArray(o.items), text: o.text }); }, _formatItemArray: function () { var sourceArray = BI.flatten(BI.deepClone(this.options.items)); var targetArray = []; BI.each(sourceArray, function (idx, item) { if(BI.has(item, "el")) { BI.each(item.children, function (id, it) { it.text = item.el.text + "(" + it.text + ")"; }); targetArray = BI.concat(targetArray, item.children); }else{ targetArray.push(item); } }); return targetArray; }, setValue: function (vals) { this.trigger.setValue(vals); }, populate: function (items) { this.trigger.populate(this._formatItemArray(items)); } }); BI.shortcut("bi.down_list_select_text_trigger", BI.DownListSelectTextTrigger);/** * 有清楚按钮的文本框 * Created by GUY on 2015/9/29. * @class BI.SmallTextEditor * @extends BI.SearchEditor */ BI.ClearEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.ClearEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-clear-editor", height: 24, errorText: "", watermark: "", validationChecker: BI.emptyFn, quitChecker: BI.emptyFn }); }, _init: function () { BI.ClearEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, watermark: o.watermark, allowBlank: true, errorText: o.errorText, validationChecker: o.validationChecker, quitChecker: o.quitChecker }); this.clear = BI.createWidget({ type: "bi.icon_button", stopEvent: true, cls: "search-close-h-font" }); this.clear.on(BI.IconButton.EVENT_CHANGE, function () { self.setValue(""); self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT); self.fireEvent(BI.ClearEditor.EVENT_CLEAR); }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: this.editor }, { el: this.clear, width: 25 }] }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.ClearEditor.EVENT_FOCUS); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.ClearEditor.EVENT_BLUR); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.ClearEditor.EVENT_CLICK); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self._checkClear(); self.fireEvent(BI.ClearEditor.EVENT_CHANGE); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.ClearEditor.EVENT_KEY_DOWN, v); }); this.editor.on(BI.Editor.EVENT_SPACE, function () { self.fireEvent(BI.ClearEditor.EVENT_SPACE); }); this.editor.on(BI.Editor.EVENT_BACKSPACE, function () { self.fireEvent(BI.ClearEditor.EVENT_BACKSPACE); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.ClearEditor.EVENT_VALID); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self.fireEvent(BI.ClearEditor.EVENT_ERROR); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.ClearEditor.EVENT_ENTER); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.ClearEditor.EVENT_RESTRICT); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self._checkClear(); self.fireEvent(BI.ClearEditor.EVENT_EMPTY); }); this.editor.on(BI.Editor.EVENT_REMOVE, function () { self.fireEvent(BI.ClearEditor.EVENT_REMOVE); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self.fireEvent(BI.ClearEditor.EVENT_CONFIRM); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.ClearEditor.EVENT_START); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.ClearEditor.EVENT_PAUSE); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.ClearEditor.EVENT_STOP); }); this.clear.invisible(); }, _checkClear: function () { if (!this.getValue()) { this.clear.invisible(); } else { this.clear.visible(); } }, focus: function () { this.editor.focus(); }, blur: function () { this.editor.blur(); }, getValue: function () { if (this.isValid()) { var res = this.editor.getValue().match(/[\S]+/g); return BI.isNull(res) ? "" : res[res.length - 1]; } }, setValue: function (v) { this.editor.setValue(v); if (BI.isKey(v)) { this.clear.visible(); } }, isValid: function () { return this.editor.isValid(); } }); BI.ClearEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.ClearEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.ClearEditor.EVENT_BLUR = "EVENT_BLUR"; BI.ClearEditor.EVENT_CLICK = "EVENT_CLICK"; BI.ClearEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.ClearEditor.EVENT_SPACE = "EVENT_SPACE"; BI.ClearEditor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; BI.ClearEditor.EVENT_CLEAR = "EVENT_CLEAR"; BI.ClearEditor.EVENT_START = "EVENT_START"; BI.ClearEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.ClearEditor.EVENT_STOP = "EVENT_STOP"; BI.ClearEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.ClearEditor.EVENT_VALID = "EVENT_VALID"; BI.ClearEditor.EVENT_ERROR = "EVENT_ERROR"; BI.ClearEditor.EVENT_ENTER = "EVENT_ENTER"; BI.ClearEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.ClearEditor.EVENT_REMOVE = "EVENT_REMOVE"; BI.ClearEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.clear_editor", BI.ClearEditor);/** * 带标记的文本框 * Created by GUY on 2016/1/25. * @class BI.ShelterEditor * @extends BI.Widget */ BI.ShelterEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.ShelterEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-shelter-editor", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: true, watermark: "", errorText: "", height: 24, textAlign: "left" }); }, _init: function () { BI.ShelterEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, value: o.value, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.text = BI.createWidget({ type: "bi.text_button", cls: "shelter-editor-text", title: o.title, warningTitle: o.warningTitle, tipType: o.tipType, textAlign: o.textAlign, height: o.height, hgap: 4 }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.text, left: 0, right: 0, top: 0, bottom: 0 }] }); this.text.on(BI.Controller.EVENT_CHANGE, function () { arguments[2] = self; self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.text.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.ShelterEditor.EVENT_CLICK_LABEL); }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.ShelterEditor.EVENT_FOCUS, arguments); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.ShelterEditor.EVENT_BLUR, arguments); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.ShelterEditor.EVENT_CLICK, arguments); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self.fireEvent(BI.ShelterEditor.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.ShelterEditor.EVENT_KEY_DOWN, arguments); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.ShelterEditor.EVENT_VALID, arguments); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self._showHint(); self._checkText(); self.fireEvent(BI.ShelterEditor.EVENT_CONFIRM, arguments); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.ShelterEditor.EVENT_START, arguments); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.ShelterEditor.EVENT_PAUSE, arguments); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.ShelterEditor.EVENT_STOP, arguments); }); this.editor.on(BI.Editor.EVENT_SPACE, function () { self.fireEvent(BI.ShelterEditor.EVENT_SPACE, arguments); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self._checkText(); self.fireEvent(BI.ShelterEditor.EVENT_ERROR, arguments); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.ShelterEditor.EVENT_ENTER, arguments); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.ShelterEditor.EVENT_RESTRICT, arguments); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self.fireEvent(BI.ShelterEditor.EVENT_EMPTY, arguments); }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [this.editor] }); this._showHint(); self._checkText(); }, _checkText: function () { var o = this.options; if (this.editor.getValue() === "") { this.text.setValue(o.watermark || ""); this.text.element.addClass("bi-water-mark"); } else { this.text.setValue(this.editor.getValue()); this.text.element.removeClass("bi-water-mark"); } }, _showInput: function () { this.editor.visible(); this.text.invisible(); }, _showHint: function () { this.editor.invisible(); this.text.visible(); }, setTitle: function (title) { this.text.setTitle(title); }, setWarningTitle: function (title) { this.text.setWarningTitle(title); }, focus: function () { this._showInput(); this.editor.focus(); }, blur: function () { this.editor.blur(); this._showHint(); this._checkText(); }, doRedMark: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, isValid: function () { return this.editor.isValid(); }, setErrorText: function (text) { this.editor.setErrorText(text); }, getErrorText: function () { return this.editor.getErrorText(); }, isEditing: function () { return this.editor.isEditing(); }, getLastValidValue: function () { return this.editor.getLastValidValue(); }, setTextStyle: function (style) { this.text.setStyle(style); }, setValue: function (k) { this.editor.setValue(k); this._checkText(); }, getValue: function () { return this.editor.getValue(); }, getState: function () { return this.text.getValue(); }, setState: function (v) { this._showHint(); this.text.setValue(v); } }); BI.ShelterEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.ShelterEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.ShelterEditor.EVENT_BLUR = "EVENT_BLUR"; BI.ShelterEditor.EVENT_CLICK = "EVENT_CLICK"; BI.ShelterEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.ShelterEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; BI.ShelterEditor.EVENT_START = "EVENT_START"; BI.ShelterEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.ShelterEditor.EVENT_STOP = "EVENT_STOP"; BI.ShelterEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.ShelterEditor.EVENT_VALID = "EVENT_VALID"; BI.ShelterEditor.EVENT_ERROR = "EVENT_ERROR"; BI.ShelterEditor.EVENT_ENTER = "EVENT_ENTER"; BI.ShelterEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.ShelterEditor.EVENT_SPACE = "EVENT_SPACE"; BI.ShelterEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.shelter_editor", BI.ShelterEditor);/** * Created by User on 2017/7/28. */ BI.SignInitialEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.SignInitialEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-sign-initial-editor", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: true, watermark: "", errorText: "", value: "", text: "", height: 24 }); }, _init: function () { BI.SignInitialEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, value: o.value, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.text = BI.createWidget({ type: "bi.text_button", cls: "sign-editor-text", title: o.title, warningTitle: o.warningTitle, tipType: o.tipType, textAlign: "left", height: o.height, hgap: 4, handler: function () { self._showInput(); self.editor.focus(); self.editor.selectAll(); } }); this.text.on(BI.TextButton.EVENT_CHANGE, function () { BI.nextTick(function () { self.fireEvent(BI.SignInitialEditor.EVENT_CLICK_LABEL); }); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.text, left: 0, right: 0, top: 0, bottom: 0 }] }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.SignInitialEditor.EVENT_FOCUS, arguments); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.SignInitialEditor.EVENT_BLUR, arguments); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.SignInitialEditor.EVENT_CLICK, arguments); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self.fireEvent(BI.SignInitialEditor.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.SignInitialEditor.EVENT_KEY_DOWN, arguments); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.SignInitialEditor.EVENT_VALID, arguments); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self._showHint(); self._checkText(); self.fireEvent(BI.SignInitialEditor.EVENT_CONFIRM, arguments); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.SignInitialEditor.EVENT_START, arguments); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.SignInitialEditor.EVENT_PAUSE, arguments); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.SignInitialEditor.EVENT_STOP, arguments); }); this.editor.on(BI.Editor.EVENT_SPACE, function () { self.fireEvent(BI.SignInitialEditor.EVENT_SPACE, arguments); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self._checkText(); self.fireEvent(BI.SignInitialEditor.EVENT_ERROR, arguments); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.SignInitialEditor.EVENT_ENTER, arguments); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.SignInitialEditor.EVENT_RESTRICT, arguments); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self.fireEvent(BI.SignInitialEditor.EVENT_EMPTY, arguments); }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [this.editor] }); this._showHint(); self._checkText(); }, _checkText: function () { var o = this.options; BI.nextTick(BI.bind(function () { if (this.editor.getValue() === "") { this.text.setValue(o.watermark || ""); this.text.element.addClass("bi-water-mark"); } else { var v = this.editor.getValue(); v = (BI.isEmpty(v) || v == o.text) ? o.text : v + "(" + o.text + ")"; this.text.setValue(v); this.text.element.removeClass("bi-water-mark"); } }, this)); }, _showInput: function () { this.editor.visible(); this.text.invisible(); }, _showHint: function () { this.editor.invisible(); this.text.visible(); }, setTitle: function (title) { this.text.setTitle(title); }, setWarningTitle: function (title) { this.text.setWarningTitle(title); }, focus: function () { this._showInput(); this.editor.focus(); }, blur: function () { this.editor.blur(); this._showHint(); this._checkText(); }, doRedMark: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, isValid: function () { return this.editor.isValid(); }, setErrorText: function (text) { this.editor.setErrorText(text); }, getErrorText: function () { return this.editor.getErrorText(); }, isEditing: function () { return this.editor.isEditing(); }, getLastValidValue: function () { return this.editor.getLastValidValue(); }, setValue: function (v) { var o = this.options; this.editor.setValue(v.value); o.text = v.text || o.text; this._checkText(); }, getValue: function () { return { value: this.editor.getValue(), text: this.options.text }; }, getState: function () { return this.text.getValue(); }, setState: function (v) { var o = this.options; this._showHint(); v = (BI.isEmpty(v) || v == o.text) ? o.text : v + "(" + o.text + ")"; this.text.setValue(v); } }); BI.SignInitialEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.SignInitialEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.SignInitialEditor.EVENT_BLUR = "EVENT_BLUR"; BI.SignInitialEditor.EVENT_CLICK = "EVENT_CLICK"; BI.SignInitialEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.SignInitialEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; BI.SignInitialEditor.EVENT_START = "EVENT_START"; BI.SignInitialEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.SignInitialEditor.EVENT_STOP = "EVENT_STOP"; BI.SignInitialEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.SignInitialEditor.EVENT_VALID = "EVENT_VALID"; BI.SignInitialEditor.EVENT_ERROR = "EVENT_ERROR"; BI.SignInitialEditor.EVENT_ENTER = "EVENT_ENTER"; BI.SignInitialEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.SignInitialEditor.EVENT_SPACE = "EVENT_SPACE"; BI.SignInitialEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.sign_initial_editor", BI.SignInitialEditor);/** * 带标记的文本框 * Created by GUY on 2015/8/28. * @class BI.SignEditor * @extends BI.Widget */ BI.SignEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.SignEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-sign-editor", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: true, watermark: "", errorText: "", height: 24 }); }, _init: function () { BI.SignEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, value: o.value, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.text = BI.createWidget({ type: "bi.text_button", cls: "sign-editor-text", title: o.title, warningTitle: o.warningTitle, tipType: o.tipType, textAlign: "left", height: o.height, hgap: 4, handler: function () { self._showInput(); self.editor.focus(); self.editor.selectAll(); } }); this.text.on(BI.TextButton.EVENT_CHANGE, function () { BI.nextTick(function () { self.fireEvent(BI.SignEditor.EVENT_CLICK_LABEL); }); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.text, left: 0, right: 0, top: 0, bottom: 0 }] }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.SignEditor.EVENT_FOCUS, arguments); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.SignEditor.EVENT_BLUR, arguments); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.SignEditor.EVENT_CLICK, arguments); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self.fireEvent(BI.SignEditor.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.SignEditor.EVENT_KEY_DOWN, arguments); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.SignEditor.EVENT_VALID, arguments); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self._showHint(); self._checkText(); self.fireEvent(BI.SignEditor.EVENT_CONFIRM, arguments); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.SignEditor.EVENT_START, arguments); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.SignEditor.EVENT_PAUSE, arguments); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.SignEditor.EVENT_STOP, arguments); }); this.editor.on(BI.Editor.EVENT_SPACE, function () { self.fireEvent(BI.SignEditor.EVENT_SPACE, arguments); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self._checkText(); self.fireEvent(BI.SignEditor.EVENT_ERROR, arguments); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.SignEditor.EVENT_ENTER, arguments); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.SignEditor.EVENT_RESTRICT, arguments); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self.fireEvent(BI.SignEditor.EVENT_EMPTY, arguments); }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [this.editor] }); this._showHint(); self._checkText(); }, _checkText: function () { var o = this.options; BI.nextTick(BI.bind(function () { if (this.editor.getValue() === "") { this.text.setValue(o.watermark || ""); this.text.element.addClass("bi-water-mark"); } else { this.text.setValue(this.editor.getValue()); this.text.element.removeClass("bi-water-mark"); } }, this)); }, _showInput: function () { this.editor.visible(); this.text.invisible(); }, _showHint: function () { this.editor.invisible(); this.text.visible(); }, setTitle: function (title) { this.text.setTitle(title); }, setWarningTitle: function (title) { this.text.setWarningTitle(title); }, focus: function () { this._showInput(); this.editor.focus(); }, blur: function () { this.editor.blur(); this._showHint(); this._checkText(); }, doRedMark: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, isValid: function () { return this.editor.isValid(); }, setErrorText: function (text) { this.editor.setErrorText(text); }, getErrorText: function () { return this.editor.getErrorText(); }, isEditing: function () { return this.editor.isEditing(); }, getLastValidValue: function () { return this.editor.getLastValidValue(); }, setValue: function (k) { this.editor.setValue(k); this._checkText(); }, getValue: function () { return this.editor.getValue(); }, getState: function () { return this.text.getValue(); }, setState: function (v) { this._showHint(); this.text.setValue(v); } }); BI.SignEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.SignEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.SignEditor.EVENT_BLUR = "EVENT_BLUR"; BI.SignEditor.EVENT_CLICK = "EVENT_CLICK"; BI.SignEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.SignEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; BI.SignEditor.EVENT_START = "EVENT_START"; BI.SignEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.SignEditor.EVENT_STOP = "EVENT_STOP"; BI.SignEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.SignEditor.EVENT_VALID = "EVENT_VALID"; BI.SignEditor.EVENT_ERROR = "EVENT_ERROR"; BI.SignEditor.EVENT_ENTER = "EVENT_ENTER"; BI.SignEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.SignEditor.EVENT_SPACE = "EVENT_SPACE"; BI.SignEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.sign_editor", BI.SignEditor);/** * guy * 记录状态的输入框 * @class BI.StateEditor * @extends BI.Single */ BI.StateEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.StateEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-state-editor", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: true, watermark: "", errorText: "", height: 24 }); }, _init: function () { BI.StateEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, value: o.value, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.text = BI.createWidget({ type: "bi.text_button", cls: "state-editor-infinite-text bi-disabled", textAlign: "left", height: o.height, text: BI.i18nText("BI-Basic_Unrestricted"), hgap: 4, handler: function () { self._showInput(); self.editor.focus(); self.editor.setValue(""); } }); this.text.on(BI.TextButton.EVENT_CHANGE, function () { BI.nextTick(function () { self.fireEvent(BI.StateEditor.EVENT_CLICK_LABEL); }); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.text, left: 0, right: 0, top: 0, bottom: 0 }] }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.StateEditor.EVENT_FOCUS, arguments); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.StateEditor.EVENT_BLUR, arguments); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.StateEditor.EVENT_CLICK, arguments); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self.fireEvent(BI.StateEditor.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.StateEditor.EVENT_KEY_DOWN, arguments); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.StateEditor.EVENT_VALID, arguments); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self._showHint(); self.fireEvent(BI.StateEditor.EVENT_CONFIRM, arguments); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.StateEditor.EVENT_START, arguments); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.StateEditor.EVENT_PAUSE, arguments); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.StateEditor.EVENT_STOP, arguments); }); this.editor.on(BI.Editor.EVENT_SPACE, function () { self.fireEvent(BI.StateEditor.EVENT_SPACE, arguments); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self.fireEvent(BI.StateEditor.EVENT_ERROR, arguments); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.StateEditor.EVENT_ENTER, arguments); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.StateEditor.EVENT_RESTRICT, arguments); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self.fireEvent(BI.StateEditor.EVENT_EMPTY, arguments); }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [this.editor] }); this._showHint(); }, doRedMark: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, focus: function () { if (this.options.disabled === false) { this._showInput(); this.editor.focus(); } }, blur: function () { this.editor.blur(); this._showHint(); }, _showInput: function () { this.editor.visible(); this.text.invisible(); }, _showHint: function () { this.editor.invisible(); this.text.visible(); }, isValid: function () { return this.editor.isValid(); }, setErrorText: function (text) { this.editor.setErrorText(text); }, getErrorText: function () { return this.editor.getErrorText(); }, isEditing: function () { return this.editor.isEditing(); }, getLastValidValue: function () { return this.editor.getLastValidValue(); }, setValue: function (k) { this.editor.setValue(k); }, getValue: function () { return this.editor.getValue(); }, getState: function () { return this.editor.getValue().match(/[^\s]+/g); }, setState: function (v) { BI.StateEditor.superclass.setValue.apply(this, arguments); if (BI.isNumber(v)) { if (v === BI.Selection.All) { this.text.setText(BI.i18nText("BI-Select_All")); this.text.setTitle(""); this.text.element.removeClass("state-editor-infinite-text"); } else if (v === BI.Selection.Multi) { this.text.setText(BI.i18nText("BI-Select_Part")); this.text.setTitle(""); this.text.element.removeClass("state-editor-infinite-text"); } else { this.text.setText(BI.i18nText("BI-Basic_Unrestricted")); this.text.setTitle(""); this.text.element.addClass("state-editor-infinite-text"); } return; } if (BI.isString(v)) { // if (BI.isEmpty(v)) { // this.text.setText(BI.i18nText("BI-Basic_Unrestricted")); // this.text.setTitle(""); // this.text.element.addClass("state-editor-infinite-text"); // } else { this.text.setText(v); this.text.setTitle(v); this.text.element.removeClass("state-editor-infinite-text"); // } return; } if (BI.isArray(v)) { if (BI.isEmpty(v)) { this.text.setText(BI.i18nText("BI-Basic_Unrestricted")); this.text.element.addClass("state-editor-infinite-text"); } else if (v.length === 1) { this.text.setText(v[0]); this.text.setTitle(v[0]); this.text.element.removeClass("state-editor-infinite-text"); } else { this.text.setText(BI.i18nText("BI-Select_Part")); this.text.setTitle(""); this.text.element.removeClass("state-editor-infinite-text"); } } } }); BI.StateEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.StateEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.StateEditor.EVENT_BLUR = "EVENT_BLUR"; BI.StateEditor.EVENT_CLICK = "EVENT_CLICK"; BI.StateEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.StateEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; BI.StateEditor.EVENT_START = "EVENT_START"; BI.StateEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.StateEditor.EVENT_STOP = "EVENT_STOP"; BI.StateEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.StateEditor.EVENT_VALID = "EVENT_VALID"; BI.StateEditor.EVENT_ERROR = "EVENT_ERROR"; BI.StateEditor.EVENT_ENTER = "EVENT_ENTER"; BI.StateEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.StateEditor.EVENT_SPACE = "EVENT_SPACE"; BI.StateEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.state_editor", BI.StateEditor);/** * 无限制-已选择状态输入框 * Created by GUY on 2016/5/18. * @class BI.SimpleStateEditor * @extends BI.Single */ BI.SimpleStateEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.SimpleStateEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-simple-state-editor", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, mouseOut: false, allowBlank: true, watermark: "", errorText: "", height: 24 }); }, _init: function () { BI.SimpleStateEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, value: o.value, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.text = BI.createWidget({ type: "bi.text_button", cls: "state-editor-infinite-text bi-disabled", textAlign: "left", height: o.height, text: BI.i18nText("BI-Basic_Unrestricted"), hgap: 4, handler: function () { self._showInput(); self.editor.focus(); self.editor.setValue(""); } }); this.text.on(BI.TextButton.EVENT_CHANGE, function () { BI.nextTick(function () { self.fireEvent(BI.SimpleStateEditor.EVENT_CLICK_LABEL); }); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.text, left: 0, right: 0, top: 0, bottom: 0 }] }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_FOCUS, arguments); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_BLUR, arguments); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_CLICK, arguments); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.SimpleStateEditor.EVENT_KEY_DOWN, arguments); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_VALID, arguments); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self._showHint(); self.fireEvent(BI.SimpleStateEditor.EVENT_CONFIRM, arguments); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_START, arguments); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_PAUSE, arguments); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_STOP, arguments); }); this.editor.on(BI.Editor.EVENT_SPACE, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_SPACE, arguments); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_ERROR, arguments); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_ENTER, arguments); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_RESTRICT, arguments); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self.fireEvent(BI.SimpleStateEditor.EVENT_EMPTY, arguments); }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [this.editor] }); this._showHint(); }, doRedMark: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, focus: function () { this._showInput(); this.editor.focus(); }, blur: function () { this.editor.blur(); this._showHint(); }, _showInput: function () { this.editor.visible(); this.text.invisible(); }, _showHint: function () { this.editor.invisible(); this.text.visible(); }, isValid: function () { return this.editor.isValid(); }, setErrorText: function (text) { this.editor.setErrorText(text); }, getErrorText: function () { return this.editor.getErrorText(); }, isEditing: function () { return this.editor.isEditing(); }, getLastValidValue: function () { return this.editor.getLastValidValue(); }, setValue: function (k) { this.editor.setValue(k); }, getValue: function () { return this.editor.getValue(); }, getState: function () { return this.editor.getValue().match(/[^\s]+/g); }, setState: function (v) { BI.SimpleStateEditor.superclass.setValue.apply(this, arguments); if (BI.isNumber(v)) { if (v === BI.Selection.All) { this.text.setText(BI.i18nText("BI-Already_Selected")); this.text.element.removeClass("state-editor-infinite-text"); } else if (v === BI.Selection.Multi) { this.text.setText(BI.i18nText("BI-Already_Selected")); this.text.element.removeClass("state-editor-infinite-text"); } else { this.text.setText(BI.i18nText("BI-Basic_Unrestricted")); this.text.element.addClass("state-editor-infinite-text"); } return; } if (!BI.isArray(v) || v.length === 1) { this.text.setText(v); this.text.setTitle(v); this.text.element.removeClass("state-editor-infinite-text"); } else if (BI.isEmpty(v)) { this.text.setText(BI.i18nText("BI-Basic_Unrestricted")); this.text.element.addClass("state-editor-infinite-text"); } else { this.text.setText(BI.i18nText("BI-Already_Selected")); this.text.element.removeClass("state-editor-infinite-text"); } } }); BI.SimpleStateEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.SimpleStateEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.SimpleStateEditor.EVENT_BLUR = "EVENT_BLUR"; BI.SimpleStateEditor.EVENT_CLICK = "EVENT_CLICK"; BI.SimpleStateEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.SimpleStateEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; BI.SimpleStateEditor.EVENT_START = "EVENT_START"; BI.SimpleStateEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.SimpleStateEditor.EVENT_STOP = "EVENT_STOP"; BI.SimpleStateEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.SimpleStateEditor.EVENT_VALID = "EVENT_VALID"; BI.SimpleStateEditor.EVENT_ERROR = "EVENT_ERROR"; BI.SimpleStateEditor.EVENT_ENTER = "EVENT_ENTER"; BI.SimpleStateEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.SimpleStateEditor.EVENT_SPACE = "EVENT_SPACE"; BI.SimpleStateEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.simple_state_editor", BI.SimpleStateEditor);/** * 有确定取消按钮的弹出层 * @class BI.BarPopoverSection * @extends BI.PopoverSection * @abstract */ BI.BarPopoverSection = BI.inherit(BI.PopoverSection, { _defaultConfig: function () { return BI.extend(BI.BarPopoverSection.superclass._defaultConfig.apply(this, arguments), { btns: [BI.i18nText(BI.i18nText("BI-Basic_Sure")), BI.i18nText(BI.i18nText("BI-Basic_Cancel"))] }); }, _init: function () { BI.BarPopoverSection.superclass._init.apply(this, arguments); }, rebuildSouth: function (south) { var self = this, o = this.options; this.sure = BI.createWidget({ type: "bi.button", text: this.options.btns[0], warningTitle: o.warningTitle, height: 30, value: 0, handler: function (v) { self.end(); self.close(v); } }); this.cancel = BI.createWidget({ type: "bi.button", text: this.options.btns[1], height: 30, value: 1, level: "ignore", handler: function (v) { self.close(v); } }); BI.createWidget({ type: "bi.right_vertical_adapt", element: south, lgap: 10, items: [this.cancel, this.sure] }); }, setConfirmButtonEnable: function (v) { this.sure.setEnable(!!v); } });/** * 下拉框弹出层的多选版本,toolbar带有若干按钮, zIndex在1000w * @class BI.MultiPopupView * @extends BI.Widget */ BI.MultiPopupView = BI.inherit(BI.PopupView, { _defaultConfig: function () { var conf = BI.MultiPopupView.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-multi-list-view", buttons: [BI.i18nText("BI-Basic_Sure")] }); }, _init: function () { BI.MultiPopupView.superclass._init.apply(this, arguments); }, _createToolBar: function () { var o = this.options, self = this; if (o.buttons.length === 0) { return; } var text = []; // 构造[{text:content},……] BI.each(o.buttons, function (idx, item) { text.push({ text: item, value: idx }); }); this.buttongroup = BI.createWidget({ type: "bi.button_group", cls: "list-view-toolbar bi-high-light bi-border-top", height: 30, items: BI.createItems(text, { type: "bi.text_button", once: false, shadow: true, isShadowShowingOnSelected: true }), layouts: [{ type: "bi.center", hgap: 0, vgap: 0 }] }); this.buttongroup.on(BI.ButtonGroup.EVENT_CHANGE, function (value, obj) { self.fireEvent(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, value, obj); }); return this.buttongroup; } }); BI.MultiPopupView.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; BI.shortcut("bi.multi_popup_view", BI.MultiPopupView);/** * 可以理解为MultiPopupView和Panel两个面板的结合体 * @class BI.PopupPanel * @extends BI.MultiPopupView */ BI.PopupPanel = BI.inherit(BI.MultiPopupView, { _defaultConfig: function () { var conf = BI.PopupPanel.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-popup-panel", title: "" }); }, _init: function () { BI.PopupPanel.superclass._init.apply(this, arguments); }, _createTool: function () { var self = this, o = this.options; var close = BI.createWidget({ type: "bi.icon_button", cls: "close-h-font", width: 25, height: 25 }); close.on(BI.IconButton.EVENT_CHANGE, function () { self.setVisible(false); self.fireEvent(BI.PopupPanel.EVENT_CLOSE); }); return BI.createWidget({ type: "bi.htape", cls: "popup-panel-title bi-background bi-border", height: 25, items: [{ el: { type: "bi.label", textAlign: "left", text: o.title, height: 25, lgap: 10 } }, { el: close, width: 25 }] }); } }); BI.PopupPanel.EVENT_CHANGE = "EVENT_CHANGE"; BI.PopupPanel.EVENT_CLOSE = "EVENT_CLOSE"; BI.PopupPanel.EVENT_CLICK_TOOLBAR_BUTTON = "EVENT_CLICK_TOOLBAR_BUTTON"; BI.shortcut("bi.popup_panel", BI.PopupPanel);/** * list面板 * * Created by GUY on 2015/10/30. * @class BI.ListPane * @extends BI.Pane */ BI.ListPane = BI.inherit(BI.Pane, { _defaultConfig: function () { var conf = BI.ListPane.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-list-pane", logic: { dynamic: true }, lgap: 0, rgap: 0, tgap: 0, bgap: 0, vgap: 0, hgap: 0, items: [], itemsCreator: BI.emptyFn, hasNext: BI.emptyFn, onLoaded: BI.emptyFn, el: { type: "bi.button_group" } }); }, _init: function () { BI.ListPane.superclass._init.apply(this, arguments); var self = this, o = this.options; this.button_group = BI.createWidget(o.el, { type: "bi.button_group", chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, behaviors: {}, items: o.items, itemsCreator: function (op, calback) { if (op.times === 1) { self.empty(); BI.nextTick(function () { self.loading(); }); } o.itemsCreator(op, function () { calback.apply(self, arguments); op.times === 1 && BI.nextTick(function () { self.loaded(); }); }); }, hasNext: o.hasNext, layouts: [{ type: "bi.vertical" }] }); this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.ListPane.EVENT_CHANGE, value, obj); } }); this.check(); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Top), BI.extend({ scrolly: true, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, vgap: o.vgap, hgap: o.hgap }, o.logic, { items: BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Top, this.button_group) })))); }, hasPrev: function () { return this.button_group.hasPrev && this.button_group.hasPrev(); }, hasNext: function () { return this.button_group.hasNext && this.button_group.hasNext(); }, prependItems: function (items) { this.options.items = items.concat(this.options.items); this.button_group.prependItems.apply(this.button_group, arguments); this.check(); }, addItems: function (items) { this.options.items = this.options.items.concat(items); this.button_group.addItems.apply(this.button_group, arguments); this.check(); }, removeItemAt: function (indexes) { indexes = indexes || []; BI.removeAt(this.options.items, indexes); this.button_group.removeItemAt.apply(this.button_group, arguments); this.check(); }, populate: function (items) { var self = this, o = this.options; if (arguments.length === 0 && (BI.isFunction(this.button_group.attr("itemsCreator")))) {// 接管loader的populate方法 this.button_group.attr("itemsCreator").apply(this, [{times: 1}, function () { if (arguments.length === 0) { throw new Error("参数不能为空"); } self.populate.apply(self, arguments); }]); return; } BI.ListPane.superclass.populate.apply(this, arguments); this.button_group.populate.apply(this.button_group, arguments); }, empty: function () { this.button_group.empty(); }, setNotSelectedValue: function () { this.button_group.setNotSelectedValue.apply(this.button_group, arguments); }, getNotSelectedValue: function () { return this.button_group.getNotSelectedValue(); }, setValue: function () { this.button_group.setValue.apply(this.button_group, arguments); }, getValue: function () { return this.button_group.getValue.apply(this.button_group, arguments); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, getAllLeaves: function () { return this.button_group.getAllLeaves(); }, getSelectedButtons: function () { return this.button_group.getSelectedButtons(); }, getNotSelectedButtons: function () { return this.button_group.getNotSelectedButtons(); }, getIndexByValue: function (value) { return this.button_group.getIndexByValue(value); }, getNodeById: function (id) { return this.button_group.getNodeById(id); }, getNodeByValue: function (value) { return this.button_group.getNodeByValue(value); } }); BI.ListPane.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.list_pane", BI.ListPane);/** * 带有标题栏的pane * @class BI.Panel * @extends BI.Widget */ BI.Panel = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.Panel.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-panel bi-border", title: "", titleButtons: [], el: {}, logic: { dynamic: false } }); }, _init: function () { BI.Panel.superclass._init.apply(this, arguments); var o = this.options; BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic("vertical", BI.extend(o.logic, { items: BI.LogicFactory.createLogicItemsByDirection("top", this._createTitle() , this.options.el) })))); }, _createTitle: function () { var self = this, o = this.options; this.text = BI.createWidget({ type: "bi.label", cls: "panel-title-text", text: o.title, height: 30 }); this.button_group = BI.createWidget({ type: "bi.button_group", items: o.titleButtons, layouts: [{ type: "bi.center_adapt", lgap: 10 }] }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button_group.on(BI.ButtonGroup.EVENT_CHANGE, function (value, obj) { self.fireEvent(BI.Panel.EVENT_CHANGE, value, obj); }); return { el: { type: "bi.left_right_vertical_adapt", cls: "panel-title bi-border-bottom bi-background", height: 29, items: { left: [this.text], right: [this.button_group] }, lhgap: 10, rhgap: 10 }, height: 30 }; }, setTitle: function (title) { this.text.setValue(title); } }); BI.Panel.EVENT_CHANGE = "Panel.EVENT_CHANGE"; BI.shortcut("bi.panel", BI.Panel);/** * 选择列表 * * Created by GUY on 2015/11/1. * @class BI.SelectList * @extends BI.Widget */ BI.SelectList = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SelectList.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-select-list", direction: BI.Direction.Top, // toolbar的位置 logic: { dynamic: true }, items: [], itemsCreator: BI.emptyFn, hasNext: BI.emptyFn, onLoaded: BI.emptyFn, toolbar: { type: "bi.multi_select_bar" }, el: { type: "bi.list_pane" } }); }, _init: function () { BI.SelectList.superclass._init.apply(this, arguments); var self = this, o = this.options; // 全选 this.toolbar = BI.createWidget(o.toolbar); this.allSelected = false; this.toolbar.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { self.allSelected = this.isSelected(); if (type === BI.Events.CLICK) { self.setAllSelected(self.allSelected); self.fireEvent(BI.SelectList.EVENT_CHANGE, value, obj); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.list = BI.createWidget(o.el, { type: "bi.list_pane", items: o.items, itemsCreator: function (op, callback) { op.times === 1 && self.toolbar.setVisible(false); o.itemsCreator(op, function (items) { callback.apply(self, arguments); if (op.times === 1) { self.toolbar.setVisible(items && items.length > 0); self.toolbar.setEnable(items && items.length > 0); } self._checkAllSelected(); }); }, onLoaded: o.onLoaded, hasNext: o.hasNext }); this.list.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { if (type === BI.Events.CLICK) { self._checkAllSelected(); self.fireEvent(BI.SelectList.EVENT_CHANGE, value, obj); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ scrolly: true }, o.logic, { items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.toolbar, this.list) })))); if (o.items.length <= 0) { this.toolbar.setVisible(false); this.toolbar.setEnable(false); } }, _checkAllSelected: function () { var selectLength = this.list.getValue().length; var notSelectLength = this.getAllLeaves().length - selectLength; var hasNext = this.list.hasNext(); var isAlreadyAllSelected = this.toolbar.isSelected(); var isHalf = selectLength > 0 && (notSelectLength > 0 || (!isAlreadyAllSelected && hasNext)); isHalf = isHalf || (notSelectLength > 0 && hasNext && isAlreadyAllSelected); this.toolbar.setHalfSelected(isHalf); !isHalf && this.toolbar.setSelected(selectLength > 0 && notSelectLength <= 0 && (!hasNext || isAlreadyAllSelected)); }, setAllSelected: function (v) { BI.each(this.getAllButtons(), function (i, btn) { (btn.setSelected || btn.setAllSelected).apply(btn, [v]); }); this.allSelected = !!v; this.toolbar.setSelected(v); this.toolbar.setHalfSelected(false); }, setToolBarVisible: function (b) { this.toolbar.setVisible(b); }, isAllSelected: function () { return this.allSelected; // return this.toolbar.isSelected(); }, hasPrev: function () { return this.list.hasPrev(); }, hasNext: function () { return this.list.hasNext(); }, prependItems: function (items) { this.list.prependItems.apply(this.list, arguments); }, addItems: function (items) { this.list.addItems.apply(this.list, arguments); }, setValue: function (data) { var selectAll = data.type === BI.ButtonGroup.CHOOSE_TYPE_ALL; this.setAllSelected(selectAll); this.list[selectAll ? "setNotSelectedValue" : "setValue"](data.value); this._checkAllSelected(); }, getValue: function () { if (this.isAllSelected() === false) { return { type: BI.ButtonGroup.CHOOSE_TYPE_MULTI, value: this.list.getValue(), assist: this.list.getNotSelectedValue() }; } return { type: BI.ButtonGroup.CHOOSE_TYPE_ALL, value: this.list.getNotSelectedValue(), assist: this.list.getValue() }; }, empty: function () { this.list.empty(); }, populate: function (items) { this.toolbar.setVisible(!BI.isEmptyArray(items)); this.toolbar.setEnable(!BI.isEmptyArray(items)); this.list.populate.apply(this.list, arguments); this._checkAllSelected(); }, _setEnable: function (enable) { BI.SelectList.superclass._setEnable.apply(this, arguments); this.toolbar.setEnable(enable); }, resetHeight: function (h) { var toolHeight = ( this.toolbar.element.outerHeight() || 25) * ( this.toolbar.isVisible() ? 1 : 0); this.list.resetHeight ? this.list.resetHeight(h - toolHeight) : this.list.element.css({"max-height": h - toolHeight + "px"}); }, setNotSelectedValue: function () { this.list.setNotSelectedValue.apply(this.list, arguments); this._checkAllSelected(); }, getNotSelectedValue: function () { return this.list.getNotSelectedValue(); }, getAllButtons: function () { return this.list.getAllButtons(); }, getAllLeaves: function () { return this.list.getAllLeaves(); }, getSelectedButtons: function () { return this.list.getSelectedButtons(); }, getNotSelectedButtons: function () { return this.list.getNotSelectedButtons(); }, getIndexByValue: function (value) { return this.list.getIndexByValue(value); }, getNodeById: function (id) { return this.list.getNodeById(id); }, getNodeByValue: function (value) { return this.list.getNodeByValue(value); } }); BI.SelectList.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.select_list", BI.SelectList);/** * Created by roy on 15/11/6. */ BI.LazyLoader = BI.inherit(BI.Widget, { _const: { PAGE: 100 }, _defaultConfig: function () { return BI.extend(BI.LazyLoader.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-lazy-loader", el: {} }); }, _init: function () { var self = this, o = this.options; BI.LazyLoader.superclass._init.apply(this, arguments); var all = o.items.length; this.loader = BI.createWidget({ type: "bi.loader", element: this, // 下面是button_group的属性 el: o.el, itemsCreator: function (options, populate) { populate(self._getNextItems(options)); }, hasNext: function (option) { return option.count < all; } }); this.loader.on(BI.Loader.EVENT_CHANGE, function (obj) { self.fireEvent(BI.LazyLoader.EVENT_CHANGE, obj); }); }, _getNextItems: function (options) { var self = this, o = this.options; var lastNum = o.items.length - this._const.PAGE * (options.times - 1); var lastItems = BI.last(o.items, lastNum); var nextItems = BI.first(lastItems, this._const.PAGE); return nextItems; }, populate: function (items) { this.loader.populate(items); }, addItems: function (items) { this.loader.addItems(items); }, empty: function () { this.loader.empty(); }, setNotSelectedValue: function () { this.loader.setNotSelectedValue.apply(this.loader, arguments); }, getNotSelectedValue: function () { return this.loader.getNotSelectedValue(); }, setValue: function () { this.loader.setValue.apply(this.loader, arguments); }, getValue: function () { return this.loader.getValue.apply(this.loader, arguments); }, getAllButtons: function () { return this.loader.getAllButtons(); }, getAllLeaves: function () { return this.loader.getAllLeaves(); }, getSelectedButtons: function () { return this.loader.getSelectedButtons(); }, getNotSelectedButtons: function () { return this.loader.getNotSelectedButtons(); }, getIndexByValue: function (value) { return this.loader.getIndexByValue(value); }, getNodeById: function (id) { return this.loader.getNodeById(id); }, getNodeByValue: function (value) { return this.loader.getNodeByValue(value); } }); BI.LazyLoader.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.lazy_loader", BI.LazyLoader);/** * 恶心的加载控件, 为解决排序问题引入的控件 * * Created by GUY on 2015/11/12. * @class BI.ListLoader * @extends BI.Widget */ BI.ListLoader = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ListLoader.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-list-loader", isDefaultInit: true, // 是否默认初始化数据 // 下面是button_group的属性 el: { type: "bi.button_group" }, items: [], itemsCreator: BI.emptyFn, onLoaded: BI.emptyFn, // 下面是分页信息 count: false, next: {}, hasNext: BI.emptyFn }); }, _nextLoad: function () { var self = this, o = this.options; this.next.setLoading(); o.itemsCreator.apply(this, [{times: ++this.times}, function () { self.next.setLoaded(); self.addItems.apply(self, arguments); }]); }, _init: function () { BI.ListLoader.superclass._init.apply(this, arguments); var self = this, o = this.options; if (o.itemsCreator === false) { o.next = false; } this.button_group = BI.createWidget(o.el, { type: "bi.button_group", element: this, chooseType: 0, items: o.items, behaviors: {}, layouts: [{ type: "bi.vertical" }] }); this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.ListLoader.EVENT_CHANGE, obj); } }); if (o.next !== false) { this.next = BI.createWidget(BI.extend({ type: "bi.loading_bar" }, o.next)); this.next.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self._nextLoad(); } }); } BI.createWidget({ type: "bi.vertical", element: this, items: [this.next] }); o.isDefaultInit && BI.isEmpty(o.items) && BI.nextTick(BI.bind(function () { this.populate(); }, this)); if (BI.isNotEmptyArray(o.items)) { this.populate(o.items); } }, hasNext: function () { var o = this.options; if (BI.isNumber(o.count)) { return this.count < o.count; } return !!o.hasNext.apply(this, [{ times: this.times, count: this.count }]); }, addItems: function (items) { this.count += items.length; if (BI.isObject(this.next)) { if (this.hasNext()) { this.options.items = this.options.items.concat(items); this.next.setLoaded(); } else { this.next.setEnd(); } } this.button_group.addItems.apply(this.button_group, arguments); this.next.element.appendTo(this.element); }, populate: function (items) { var self = this, o = this.options; if (arguments.length === 0 && (BI.isFunction(o.itemsCreator))) { o.itemsCreator.apply(this, [{times: 1}, function () { if (arguments.length === 0) { throw new Error("参数不能为空"); } self.populate.apply(self, arguments); o.onLoaded(); }]); return; } this.options.items = items; this.times = 1; this.count = 0; this.count += items.length; if (BI.isObject(this.next)) { if (this.hasNext()) { this.next.setLoaded(); } else { this.next.invisible(); } } BI.DOM.hang([this.next]); this.button_group.populate.apply(this.button_group, arguments); this.next.element.appendTo(this.element); }, empty: function () { BI.DOM.hang([this.next]); this.button_group.empty(); this.next.element.appendTo(this.element); BI.each([this.next], function (i, ob) { ob && ob.setVisible(false); }); }, setNotSelectedValue: function () { this.button_group.setNotSelectedValue.apply(this.button_group, arguments); }, getNotSelectedValue: function () { return this.button_group.getNotSelectedValue(); }, setValue: function () { this.button_group.setValue.apply(this.button_group, arguments); }, getValue: function () { return this.button_group.getValue.apply(this.button_group, arguments); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, getAllLeaves: function () { return this.button_group.getAllLeaves(); }, getSelectedButtons: function () { return this.button_group.getSelectedButtons(); }, getNotSelectedButtons: function () { return this.button_group.getNotSelectedButtons(); }, getIndexByValue: function (value) { return this.button_group.getIndexByValue(value); }, getNodeById: function (id) { return this.button_group.getNodeById(id); }, getNodeByValue: function (value) { return this.button_group.getNodeByValue(value); } }); BI.ListLoader.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.list_loader", BI.ListLoader);/** * Created by GUY on 2016/4/29. * * @class BI.SortList * @extends BI.Widget */ BI.SortList = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SortList.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-sort-list", isDefaultInit: true, // 是否默认初始化数据 // 下面是button_group的属性 el: { type: "bi.button_group" }, items: [], itemsCreator: BI.emptyFn, onLoaded: BI.emptyFn, // 下面是分页信息 count: false, next: {}, hasNext: BI.emptyFn // containment: this.element, // connectWith: ".bi-sort-list", }); }, _init: function () { BI.SortList.superclass._init.apply(this, arguments); var self = this, o = this.options; this.loader = BI.createWidget({ type: "bi.list_loader", element: this, isDefaultInit: o.isDefaultInit, el: o.el, items: this._formatItems(o.items), itemsCreator: function (op, callback) { o.itemsCreator(op, function (items) { callback(self._formatItems(items)); }); }, onLoaded: o.onLoaded, count: o.count, next: o.next, hasNext: o.hasNext }); this.loader.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.SortList.EVENT_CHANGE, value, obj); } }); this.loader.element.sortable({ containment: o.containment || this.element, connectWith: o.connectWith || ".bi-sort-list", items: ".sort-item", cursor: o.cursor || "drag", tolerance: o.tolerance || "intersect", placeholder: { element: function ($currentItem) { var holder = BI.createWidget({ type: "bi.layout", cls: "bi-sortable-holder", height: $currentItem.outerHeight() }); holder.element.css({ "margin-left": $currentItem.css("margin-left"), "margin-right": $currentItem.css("margin-right"), "margin-top": $currentItem.css("margin-top"), "margin-bottom": $currentItem.css("margin-bottom"), margin: $currentItem.css("margin") }); return holder.element; }, update: function () { } }, start: function (event, ui) { }, stop: function (event, ui) { self.fireEvent(BI.SortList.EVENT_CHANGE); }, over: function (event, ui) { } }); }, _formatItems: function (items) { BI.each(items, function (i, item) { item = BI.stripEL(item); item.cls = item.cls ? item.cls + " sort-item" : "sort-item"; item.attributes = { sorted: item.value }; }); return items; }, hasNext: function () { return this.loader.hasNext(); }, addItems: function (items) { this.loader.addItems(items); }, populate: function (items) { if (items) { arguments[0] = this._formatItems(items); } this.loader.populate.apply(this.loader, arguments); }, empty: function () { this.loader.empty(); }, setNotSelectedValue: function () { this.loader.setNotSelectedValue.apply(this.loader, arguments); }, getNotSelectedValue: function () { return this.loader.getNotSelectedValue(); }, setValue: function () { this.loader.setValue.apply(this.loader, arguments); }, getValue: function () { return this.loader.getValue(); }, getAllButtons: function () { return this.loader.getAllButtons(); }, getAllLeaves: function () { return this.loader.getAllLeaves(); }, getSelectedButtons: function () { return this.loader.getSelectedButtons(); }, getNotSelectedButtons: function () { return this.loader.getNotSelectedButtons(); }, getIndexByValue: function (value) { return this.loader.getIndexByValue(value); }, getNodeById: function (id) { return this.loader.getNodeById(id); }, getNodeByValue: function (value) { return this.loader.getNodeByValue(value); }, getSortedValues: function () { return this.loader.element.sortable("toArray", {attribute: "sorted"}); } }); BI.SortList.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.sort_list", BI.SortList);/** * 有总页数和总行数的分页控件 * Created by Young's on 2016/10/13. */ BI.AllCountPager = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.AllCountPager.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-all-count-pager", height: 30, pages: 1, // 必选项 curr: 1, // 初始化当前页, pages为数字时可用, count: 1 // 总行数 }); }, _init: function () { BI.AllCountPager.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.small_text_editor", cls: "pager-editor", validationChecker: function (v) { return (self.rowCount.getValue() === 0 && v === "0") || BI.isPositiveInteger(v); }, hgap: 4, vgap: 0, value: o.curr, errorText: BI.i18nText("BI-Please_Input_Positive_Integer"), width: 35, height: 20 }); this.pager = BI.createWidget({ type: "bi.pager", width: 36, layouts: [{ type: "bi.horizontal", hgap: 1, vgap: 1 }], dynamicShow: false, pages: o.pages, curr: o.curr, groups: 0, first: false, last: false, prev: { type: "bi.icon_button", value: "prev", title: BI.i18nText("BI-Previous_Page"), warningTitle: BI.i18nText("BI-Current_Is_First_Page"), height: 20, cls: "all-pager-prev column-pre-page-h-font" }, next: { type: "bi.icon_button", value: "next", title: BI.i18nText("BI-Next_Page"), warningTitle: BI.i18nText("BI-Current_Is_Last_Page"), height: 20, cls: "all-pager-next column-next-page-h-font" }, hasPrev: o.hasPrev, hasNext: o.hasNext, firstPage: o.firstPage, lastPage: o.lastPage }); this.editor.on(BI.TextEditor.EVENT_CONFIRM, function () { self.pager.setValue(BI.parseInt(self.editor.getValue())); self.fireEvent(BI.AllCountPager.EVENT_CHANGE); }); this.pager.on(BI.Pager.EVENT_CHANGE, function () { self.fireEvent(BI.AllCountPager.EVENT_CHANGE); }); this.pager.on(BI.Pager.EVENT_AFTER_POPULATE, function () { self.editor.setValue(self.pager.getCurrentPage()); }); this.allPages = BI.createWidget({ type: "bi.label", width: 30, title: o.pages, text: "/" + o.pages }); this.rowCount = BI.createWidget({ type: "bi.label", height: o.height, hgap: 5, text: o.count, title: o.count }); var count = BI.createWidget({ type: "bi.left", height: o.height, scrollable: false, items: [{ type: "bi.label", height: o.height, text: BI.i18nText("BI-Basic_Total"), width: 15 }, this.rowCount, { type: "bi.label", height: o.height, text: BI.i18nText("BI-Tiao_Data"), width: 50, textAlign: "left" }] }); BI.createWidget({ type: "bi.center_adapt", element: this, columnSize: ["", 35, 40, 36], items: [count, this.editor, this.allPages, this.pager] }); }, alwaysShowPager: true, setAllPages: function (v) { this.allPages.setText("/" + v); this.allPages.setTitle(v); this.pager.setAllPages(v); this.editor.setEnable(v >= 1); }, setValue: function (v) { this.pager.setValue(v); }, setVPage: function (v) { this.pager.setValue(v); }, setCount: function (count) { this.rowCount.setText(count); this.rowCount.setTitle(count); }, getCurrentPage: function () { return this.pager.getCurrentPage(); }, hasPrev: function () { return this.pager.hasPrev(); }, hasNext: function () { return this.pager.hasNext(); }, setPagerVisible: function (b) { this.editor.setVisible(b); this.allPages.setVisible(b); this.pager.setVisible(b); }, populate: function () { this.pager.populate(); } }); BI.AllCountPager.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.all_count_pager", BI.AllCountPager);/** * 显示页码的分页控件 * * Created by GUY on 2016/6/30. * @class BI.DirectionPager * @extends BI.Widget */ BI.DirectionPager = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DirectionPager.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-direction-pager", height: 30, horizontal: { pages: false, // 总页数 curr: 1, // 初始化当前页, pages为数字时可用 hasPrev: BI.emptyFn, hasNext: BI.emptyFn, firstPage: 1, lastPage: BI.emptyFn }, vertical: { pages: false, // 总页数 curr: 1, // 初始化当前页, pages为数字时可用 hasPrev: BI.emptyFn, hasNext: BI.emptyFn, firstPage: 1, lastPage: BI.emptyFn } }); }, _init: function () { BI.DirectionPager.superclass._init.apply(this, arguments); var self = this, o = this.options; var v = o.vertical, h = o.horizontal; this._createVPager(); this._createHPager(); this.layout = BI.createWidget({ type: "bi.absolute", scrollable: false, element: this, items: [{ el: this.vpager, top: 5, right: 74 }, { el: this.vlabel, top: 5, right: 111 }, { el: this.hpager, top: 5, right: -9 }, { el: this.hlabel, top: 5, right: 28 }] }); }, _createVPager: function () { var self = this, o = this.options; var v = o.vertical; this.vlabel = BI.createWidget({ type: "bi.label", width: 24, height: 20, value: v.curr, title: v.curr, invisible: true }); this.vpager = BI.createWidget({ type: "bi.pager", width: 76, layouts: [{ type: "bi.horizontal", scrollx: false, rgap: 24, vgap: 1 }], invisible: true, dynamicShow: false, pages: v.pages, curr: v.curr, groups: 0, first: false, last: false, prev: { type: "bi.icon_button", value: "prev", title: BI.i18nText("BI-Up_Page"), warningTitle: BI.i18nText("BI-Current_Is_First_Page"), height: 20, iconWidth: 16, iconHeight: 16, cls: "direction-pager-prev column-pre-page-h-font" }, next: { type: "bi.icon_button", value: "next", title: BI.i18nText("BI-Down_Page"), warningTitle: BI.i18nText("BI-Current_Is_Last_Page"), height: 20, iconWidth: 16, iconHeight: 16, cls: "direction-pager-next column-next-page-h-font" }, hasPrev: v.hasPrev, hasNext: v.hasNext, firstPage: v.firstPage, lastPage: v.lastPage }); this.vpager.on(BI.Pager.EVENT_CHANGE, function () { self.fireEvent(BI.DirectionPager.EVENT_CHANGE); }); this.vpager.on(BI.Pager.EVENT_AFTER_POPULATE, function () { self.vlabel.setValue(this.getCurrentPage()); self.vlabel.setTitle(this.getCurrentPage()); }); }, _createHPager: function () { var self = this, o = this.options; var h = o.horizontal; this.hlabel = BI.createWidget({ type: "bi.label", width: 24, height: 20, value: h.curr, title: h.curr, invisible: true }); this.hpager = BI.createWidget({ type: "bi.pager", width: 76, layouts: [{ type: "bi.horizontal", scrollx: false, rgap: 24, vgap: 1 }], invisible: true, dynamicShow: false, pages: h.pages, curr: h.curr, groups: 0, first: false, last: false, prev: { type: "bi.icon_button", value: "prev", title: BI.i18nText("BI-Left_Page"), warningTitle: BI.i18nText("BI-Current_Is_First_Page"), height: 20, iconWidth: 16, iconHeight: 16, cls: "direction-pager-prev row-pre-page-h-font" }, next: { type: "bi.icon_button", value: "next", title: BI.i18nText("BI-Right_Page"), warningTitle: BI.i18nText("BI-Current_Is_Last_Page"), height: 20, iconWidth: 16, iconHeight: 16, cls: "direction-pager-next row-next-page-h-font" }, hasPrev: h.hasPrev, hasNext: h.hasNext, firstPage: h.firstPage, lastPage: h.lastPage }); this.hpager.on(BI.Pager.EVENT_CHANGE, function () { self.fireEvent(BI.DirectionPager.EVENT_CHANGE); }); this.hpager.on(BI.Pager.EVENT_AFTER_POPULATE, function () { self.hlabel.setValue(this.getCurrentPage()); self.hlabel.setTitle(this.getCurrentPage()); }); }, getVPage: function () { return this.vpager.getCurrentPage(); }, getHPage: function () { return this.hpager.getCurrentPage(); }, setVPage: function (v) { this.vpager.setValue(v); this.vlabel.setValue(v); this.vlabel.setTitle(v); }, setHPage: function (v) { this.hpager.setValue(v); this.hlabel.setValue(v); this.hlabel.setTitle(v); }, hasVNext: function () { return this.vpager.hasNext(); }, hasHNext: function () { return this.hpager.hasNext(); }, hasVPrev: function () { return this.vpager.hasPrev(); }, hasHPrev: function () { return this.hpager.hasPrev(); }, setHPagerVisible: function (b) { this.hpager.setVisible(b); this.hlabel.setVisible(b); }, setVPagerVisible: function (b) { this.vpager.setVisible(b); this.vlabel.setVisible(b); }, populate: function () { this.vpager.populate(); this.hpager.populate(); var vShow = false, hShow = false; if (!this.hasHNext() && !this.hasHPrev()) { this.setHPagerVisible(false); } else { this.setHPagerVisible(true); hShow = true; } if (!this.hasVNext() && !this.hasVPrev()) { this.setVPagerVisible(false); } else { this.setVPagerVisible(true); vShow = true; } this.setVisible(hShow || vShow); var num = [74, 111, -9, 28]; var items = this.layout.attr("items"); if (vShow === true && hShow === true) { items[0].right = num[0]; items[1].right = num[1]; items[2].right = num[2]; items[3].right = num[3]; } else if (vShow === true) { items[0].right = num[2]; items[1].right = num[3]; } else if (hShow === true) { items[2].right = num[2]; items[3].right = num[3]; } this.layout.attr("items", items); this.layout.resize(); }, clear: function () { this.vpager.attr("curr", 1); this.hpager.attr("curr", 1); } }); BI.DirectionPager.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.direction_pager", BI.DirectionPager);/** * 分页控件 * * Created by GUY on 2015/8/31. * @class BI.DetailPager * @extends BI.Widget */ BI.DetailPager = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DetailPager.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-detail-pager", behaviors: {}, layouts: [{ type: "bi.horizontal", hgap: 10, vgap: 0 }], dynamicShow: true, // 是否动态显示上一页、下一页、首页、尾页, 若为false,则指对其设置使能状态 // dynamicShow为false时以下两个有用 dynamicShowFirstLast: false, // 是否动态显示首页、尾页 dynamicShowPrevNext: false, // 是否动态显示上一页、下一页 pages: false, // 总页数 curr: function () { return 1; }, // 初始化当前页 groups: 0, // 连续显示分页数 jump: BI.emptyFn, // 分页的回调函数 first: false, // 是否显示首页 last: false, // 是否显示尾页 prev: "上一页", next: "下一页", firstPage: 1, lastPage: function () { // 在万不得已时才会调用这个函数获取最后一页的页码, 主要作用于setValue方法 return 1; }, hasPrev: BI.emptyFn, // pages不可用时有效 hasNext: BI.emptyFn // pages不可用时有效 }); }, _init: function () { BI.DetailPager.superclass._init.apply(this, arguments); var self = this; this.currPage = BI.result(this.options, "curr"); // 翻页太灵敏 this._lock = false; this._debouce = BI.debounce(function () { self._lock = false; }, 300); this._populate(); }, _populate: function () { var self = this, o = this.options, view = [], dict = {}; this.empty(); var pages = BI.result(o, "pages"); var curr = BI.result(this, "currPage"); var groups = BI.result(o, "groups"); var first = BI.result(o, "first"); var last = BI.result(o, "last"); var prev = BI.result(o, "prev"); var next = BI.result(o, "next"); if (pages === false) { groups = 0; first = false; last = false; } else { groups > pages && (groups = pages); } // 计算当前组 dict.index = Math.ceil((curr + ((groups > 1 && groups !== pages) ? 1 : 0)) / (groups === 0 ? 1 : groups)); // 当前页非首页,则输出上一页 if (((!o.dynamicShow && !o.dynamicShowPrevNext) || curr > 1) && prev !== false) { if (BI.isKey(prev)) { view.push({ text: prev, value: "prev", disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) }); } else { view.push(BI.extend({ disabled: pages === false ? o.hasPrev(curr) === false : !(curr > 1 && prev !== false) }, prev)); } } // 当前组非首组,则输出首页 if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (dict.index > 1 && groups !== 0)) && first) { view.push({ text: first, value: "first", disabled: !(dict.index > 1 && groups !== 0) }); if (dict.index > 1 && groups !== 0) { view.push({ type: "bi.label", cls: "page-ellipsis", text: "\u2026" }); } } // 输出当前页组 dict.poor = Math.floor((groups - 1) / 2); dict.start = dict.index > 1 ? curr - dict.poor : 1; dict.end = dict.index > 1 ? (function () { var max = curr + (groups - dict.poor - 1); return max > pages ? pages : max; }()) : groups; if (dict.end - dict.start < groups - 1) { // 最后一组状态 dict.start = dict.end - groups + 1; } var s = dict.start, e = dict.end; if (first && last && (dict.index > 1 && groups !== 0) && (pages > groups && dict.end < pages && groups !== 0)) { s++; e--; } for (; s <= e; s++) { if (s === curr) { view.push({ text: s, value: s, selected: true }); } else { view.push({ text: s, value: s }); } } // 总页数大于连续分页数,且当前组最大页小于总页,输出尾页 if (((!o.dynamicShow && !o.dynamicShowFirstLast) || (pages > groups && dict.end < pages && groups !== 0)) && last) { if (pages > groups && dict.end < pages && groups !== 0) { view.push({ type: "bi.label", cls: "page-ellipsis", text: "\u2026" }); } view.push({ text: last, value: "last", disabled: !(pages > groups && dict.end < pages && groups !== 0) }); } // 当前页不为尾页时,输出下一页 dict.flow = !prev && groups === 0; if (((!o.dynamicShow && !o.dynamicShowPrevNext) && next) || (curr !== pages && next || dict.flow)) { view.push((function () { if (BI.isKey(next)) { if (pages === false) { return {text: next, value: "next", disabled: o.hasNext(curr) === false}; } return (dict.flow && curr === pages) ? {text: next, value: "next", disabled: true} : {text: next, value: "next", disabled: !(curr !== pages && next || dict.flow)}; } return BI.extend({ disabled: pages === false ? o.hasNext(curr) === false : !(curr !== pages && next || dict.flow) }, next); }())); } this.button_group = BI.createWidget({ type: "bi.button_group", element: this, items: BI.createItems(view, { cls: "page-item bi-border bi-list-item-active", height: 23, hgap: 10 }), behaviors: o.behaviors, layouts: o.layouts }); this.button_group.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { if (self._lock === true) { return; } self._lock = true; self._debouce(); if (type === BI.Events.CLICK) { var v = self.button_group.getValue()[0]; switch (v) { case "first": self.currPage = 1; break; case "last": self.currPage = pages; break; case "prev": self.currPage--; break; case "next": self.currPage++; break; default: self.currPage = v; break; } o.jump.apply(self, [{ pages: pages, curr: self.currPage }]); self._populate(); self.fireEvent(BI.DetailPager.EVENT_CHANGE, obj); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.fireEvent(BI.DetailPager.EVENT_AFTER_POPULATE); }, getCurrentPage: function () { return this.currPage; }, setAllPages: function (pages) { this.options.pages = pages; }, hasPrev: function (v) { v || (v = 1); var o = this.options; var pages = this.options.pages; return pages === false ? o.hasPrev(v) : v > 1; }, hasNext: function (v) { v || (v = 1); var o = this.options; var pages = this.options.pages; return pages === false ? o.hasNext(v) : v < pages; }, setValue: function (v) { var o = this.options; v = v | 0; v = v < 1 ? 1 : v; if (o.pages === false) { var lastPage = BI.result(o, "lastPage"), firstPage = 1; this.currPage = v > lastPage ? lastPage : ((firstPage = BI.result(o, "firstPage")), (v < firstPage ? firstPage : v)); } else { v = v > o.pages ? o.pages : v; this.currPage = v; } this._populate(); }, getValue: function () { var val = this.button_group.getValue()[0]; switch (val) { case "prev": return -1; case "next": return 1; case "first": return BI.MIN; case "last": return BI.MAX; default : return val; } }, attr: function (key, value) { BI.DetailPager.superclass.attr.apply(this, arguments); if (key === "curr") { this.currPage = BI.result(this.options, "curr"); } }, populate: function () { this._populate(); } }); BI.DetailPager.EVENT_CHANGE = "EVENT_CHANGE"; BI.DetailPager.EVENT_AFTER_POPULATE = "EVENT_AFTER_POPULATE"; BI.shortcut("bi.detail_pager", BI.DetailPager);/** * * Created by GUY on 2017/09/18. * @class BI.TextToolbar * @extends BI.Widget */ BI.RichEditorAction = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.RichEditorAction.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "" }); }, _init: function () { BI.RichEditorAction.superclass._init.apply(this, arguments); var self = this, o = this.options; o.editor.on(BI.NicEditor.EVENT_SELECTED, function (e) { self.setEnable(true); self.checkNodes(e.target); self.key(e); }); o.editor.on(BI.NicEditor.EVENT_BLUR, function () { self.setEnable(false); }); o.editor.on(BI.NicEditor.EVENT_KEYDOWN, BI.bind(this.keydown, this)); }, checkNodes: function (e) { if (!e) { return false; } var elm = e; do { if (this.options.tags && this.options.tags.contains(elm.nodeName)) { this.activate(); return true; } } while (elm = elm.parentNode && elm.className && elm.className.indexOf("bi-nic-editor") >= -1); elm = e; while (elm.nodeType == 3) { elm = elm.parentNode; } if (this.options.css) { for (var itm in this.options.css) { if ($(elm).css(itm) == this.options.css[itm]) { this.activate(); return true; } } } this.deactivate(); return false; }, start: function () { }, key: function () { }, keydown: function () { }, hideIf: function (e) { }, activate: function () { }, deactivate: function () { }, doCommand: function (args) { if (this.options.command) { this.options.editor.nicCommand(this.options.command, args); } } });/** * * Created by GUY on 2017/09/18. * @class BI.RichEditorParamAction * @extends BI.Widget */ BI.RichEditorParamAction = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorParamAction.superclass._defaultConfig.apply(this, arguments), {}); }, _init: function () { BI.RichEditorParamAction.superclass._init.apply(this, arguments); }, _createBlankNode: function () { return $("<span>").html(" "); }, _addBlank: function ($param) { var o = this.options; var instance = o.editor.selectedInstance; var next = $param.next(); if (next.length === 0) { var nextNode = this._createBlankNode(); $param.after(nextNode); instance.setFocus(nextNode[0]); } else { instance.setFocus(next[0]); } }, addParam: function (param) { var o = this.options; var instance = o.editor.instance; var image = new Image(); var canvas = document.createElement("canvas"); $("body").append(canvas); canvas.width = BI.DOM.getTextSizeWidth(param, 14) + 6; canvas.height = 16; var ctx = canvas.getContext("2d"); ctx.font = "14px Georgia"; ctx.fillStyle = "#ffffff"; ctx.fillText(param, 3, 14); image.src = canvas.toDataURL("image/png"); image.alt = param; $(image).css({"background-color": "#3f8ce8", "vertical-align": "sub", "margin": "0 3px;"}); instance.getElm().element.append(image); this._addBlank($(image)); $(canvas).destroy(); } }); // /** // * // * Created by GUY on 2017/09/18. // * @class BI.RichEditorParamAction // * @extends BI.Widget // */ // BI.RichEditorParamAction = BI.inherit(BI.RichEditorAction, { // _defaultConfig: function () { // return BI.extend(BI.RichEditorParamAction.superclass._defaultConfig.apply(this, arguments), {}); // }, // // _init: function () { // BI.RichEditorParamAction.superclass._init.apply(this, arguments); // }, // // _isParam: function (sel) { // return sel.attr("data-type") === "param"; // }, // // _createBlankNode: function () { // return $("<span>").html(" "); // }, // // _addBlank: function ($param) { // var o = this.options; // var instance = o.editor.selectedInstance; // var next = $param.next(); // if (next.length === 0 || this._isParam(next)) { // var preNode = this._createBlankNode(); // var nextNode = this._createBlankNode(); // $param.before(preNode); // $param.after(nextNode); // instance.setFocus(nextNode[0]); // } else { // instance.setFocus(next[0]); // } // }, // // _get$Sel: function () { // var o = this.options; // var instance = o.editor.selectedInstance; // var sel = $(instance.selElm()); // if (sel[0].nodeType === 3 && this._isParam(sel.parent())) { // sel = sel.parent(); // } // return sel; // }, // // addParam: function (param) { // var o = this.options; // var sel = this._get$Sel(); // var $param = $("<span>").attr({ // "data-type": "param", // "data-value": param // }).css({ // color: "white", // backgroundColor: "#009de3", // padding: "0 5px" // }).text(param).keydown(function (e) { // if (e.keyCode === BI.KeyCode.BACKSPACE || e.keyCode === BI.KeyCode.DELETE) { // $param.destroy(); // } // e.stopEvent(); // return false; // }); // var wrapper = o.editor.instance.getElm().element; // if (wrapper.find(sel).length <= 0) { // wrapper.append($param); // } else { // sel.after($param); // } // this._addBlank($param); // }, // // keydown: function (e) { // var o = this.options; // var sel = this._get$Sel(); // if (e.keyCode === 229) {// 中文输入法 // if (this._isParam(sel)) { // this._addBlank(sel); // e.stopEvent(); // return false; // } // } // if (BI.Key[e.keyCode] || e.keyCode === BI.KeyCode.TAB || e.keyCode === BI.KeyCode.ENTER || e.keyCode === BI.KeyCode.SPACE) { // if (this._isParam(sel)) { // e.stopEvent(); // return false; // } // } // if (e.keyCode === BI.KeyCode.BACKSPACE || e.keyCode === BI.KeyCode.DELETE) { // if (this._isParam(sel)) { // sel.destroy(); // e.preventDefault(); // return false; // } // } // }, // // key: function (e) { // } // }); /** * 颜色选择 * * Created by GUY on 2015/11/26. * @class BI.RichEditorTextToolbar * @extends BI.Widget */ BI.RichEditorTextToolbar = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.RichEditorTextToolbar.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-rich-editor-text-toolbar bi-background", buttons: [ {type: "bi.rich_editor_size_chooser"}, {type: "bi.rich_editor_bold_button"}, {type: "bi.rich_editor_italic_button"}, {type: "bi.rich_editor_underline_button"}, {type: "bi.rich_editor_color_chooser"}, {type: "bi.rich_editor_background_color_chooser"}, {type: "bi.rich_editor_align_left_button"}, {type: "bi.rich_editor_align_center_button"}, {type: "bi.rich_editor_align_right_button"}, {type: "bi.rich_editor_param_button"} ], height: 28 }); }, _init: function () { BI.RichEditorTextToolbar.superclass._init.apply(this, arguments); var self = this, o = this.options; var buttons = BI.createWidgets(BI.map(o.buttons, function (i, btn) { return BI.extend(btn, { editor: o.editor }); })); this.element.mousedown(function (e) { BI.each(buttons, function (i, btn) { btn.hideIf(e); }); }); BI.createWidget({ type: "bi.left", element: this, items: buttons, hgap: 3, vgap: 3 }); }, mounted: function () { var self = this; if (BI.isIE9Below()) {// IE8下必须要设置unselectable才能不blur输入框 this.element.mousedown(function () { self._noSelect(self.element[0]); }); this._noSelect(this.element[0]); } }, _noSelect: function (element) { if (element.setAttribute && element.nodeName.toLowerCase() != "input" && element.nodeName.toLowerCase() != "textarea") { element.setAttribute("unselectable", "on"); } for (var i = 0; i < element.childNodes.length; i++) { this._noSelect(element.childNodes[i]); } } }); BI.shortcut("bi.rich_editor_text_toolbar", BI.RichEditorTextToolbar);/** * 富文本编辑器 * * Created by GUY on 2017/9/15. * @class BI.NicEditor * @extends BI.Widget */ !(function () { BI.NicEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.NicEditor.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-nic-editor" }); }, _init: function () { BI.NicEditor.superclass._init.apply(this, arguments); var o = this.options; $(document).bind("mousedown." + this.getName(), BI.bind(this.selectCheck, this)); BI.createWidget({ type: "bi.vertical", element: this, items: [{ type: "bi.layout", height: 1 }, this.instance = this.addInstance()] }); }, addInstance: function () { var o = this.options; var conf = { ne: this, height: o.height - 1, maxHeight: o.maxHeight ? o.maxHeight : null }; if (this.element[0].contentEditable || !!window.opera) { var newInstance = new nicEditorInstance(conf); } else { console.error("不支持此浏览器"); } return newInstance; }, nicCommand: function (cmd, args) { if (this.selectedInstance) { this.selectedInstance.nicCommand(cmd, args); } }, selectCheck: function (e) { var t = e.target; var found = false; do { if (t.nodeName !== "svg" && t.className && t.className.indexOf(prefix) != -1) { return; // return false; } } while (t = t.parentNode); this.fireEvent("blur", t); this.lastSelectedInstance = this.selectedInstance; this.selectedInstance = null; // return false; }, setValue: function (v) { this.instance.setContent(v); }, getValue: function () { return this.instance.getContent(); }, destroyed: function () { $(document).unbind("mousedown." + this.getName()); } }); BI.NicEditor.EVENT_SELECTED = "selected"; BI.NicEditor.EVENT_BLUR = "blur"; BI.NicEditor.EVENT_KEYDOWN = "keydown"; BI.shortcut("bi.nic_editor", BI.NicEditor); var prefix = "niceditor-"; var nicEditorInstance = BI.inherit(BI.Layout, { isSelected: false, _init: function () { nicEditorInstance.superclass._init.apply(this, arguments); var o = this.options; this.ne = this.options.ne; this.elm = BI.createWidget({ type: "bi.layout", width: o.width - 8, scrollable: false }); this.elm.element.css({ margin: "4px", minHeight: (o.height - 8) + "px", outline: "none" }).html(o.value); this.element.css("maxHeight", (o.maxHeight) ? o.maxHeight + "px" : null); this.e = BI.createWidget({ type: "bi.layout", invisible: true, tagName: "textarea" }); BI.createWidget({ type: "bi.default", element: this, scrolly: true, items: [this.elm, this.e] }); this.ne.on("blur", BI.bind(this.blur, this)); this.start(); this.blur(); }, start: function () { this.elm.element.attr("contentEditable", true); if (this.getContent() == "") { // this.setContent("<br />"); } this.instanceDoc = document.defaultView; this.elm.element.on("mousedown", BI.bind(this.selected, this)); this.elm.element.on("keydown", BI.bind(this.keyDown, this)); this.elm.element.on("focus", BI.bind(this.selected, this)); this.elm.element.on("blur", BI.bind(this.blur, this)); this.elm.element.on("keyup", BI.bind(this.selected, this)); this.ne.fireEvent("add"); }, disable: function () { this.elm.element.attr("contentEditable", false); }, getSel: function () { return (window.getSelection) ? window.getSelection() : document.selection; }, getRng: function () { var s = this.getSel(); if (!s || s.rangeCount === 0) { return; } return (s.rangeCount > 0) ? s.getRangeAt(0) : s.createRange(); }, selRng: function (rng, s) { if (window.getSelection) { s.removeAllRanges(); s.addRange(rng); } else { rng.select(); } }, selElm: function () { var r = this.getRng(); if (!r) { return; } if (r.startContainer) { var contain = r.startContainer; if (r.cloneContents().childNodes.length == 1) { for (var i = 0; i < contain.childNodes.length; i++) { var rng = contain.childNodes[i].ownerDocument.createRange(); rng.selectNode(contain.childNodes[i]); if (r.compareBoundaryPoints(Range.START_TO_START, rng) != 1 && r.compareBoundaryPoints(Range.END_TO_END, rng) != -1) { return contain.childNodes[i]; } } } return contain; } return (this.getSel().type == "Control") ? r.item(0) : r.parentElement(); }, saveRng: function () { this.savedRange = this.getRng(); this.savedSel = this.getSel(); }, setFocus: function (el) { try { el.focus(); } catch (e) { } if (!window.getSelection) { var rng; try { el.focus(); } catch (e) { } rng = document.selection.createRange(); rng.moveStart("character", -el.innerText.length); var text = rng.text; for (var i = 0; i < el.innerText.length; i++) { if (el.innerText.substring(0, i + 1) == text.substring(text.length - i - 1, text.length)) { result = i + 1; } } } else { var range = document.createRange(); range.selectNodeContents(el); range.collapse(false); var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } }, restoreRng: function () { if (this.savedRange) { this.selRng(this.savedRange, this.savedSel); } }, keyDown: function (e, t) { this.ne.fireEvent("keydown", e); }, selected: function (e) { var t = e.target; if (!t && !(t = this.selElm())) { t = this.selElm(); } if (!e.ctrlKey) { var selInstance = this.ne.selectedInstance; if (selInstance != this) { if (selInstance) { this.ne.fireEvent("blur", e); } this.ne.selectedInstance = this; this.ne.fireEvent("focus", e); } this.ne.fireEvent("selected", e); this.isFocused = true; this.elm.element.addClass(prefix + "selected"); } // return false; }, blur: function () { this.isFocused = false; this.elm.element.removeClass(prefix + "selected"); }, saveContent: function () { this.ne.fireEvent("save"); this.e.element.value(this.getContent()); }, getElm: function () { return this.elm; }, getContent: function () { this.content = this.getElm().element.html(); this.ne.fireEvent("get"); return this.content; }, setContent: function (e) { this.content = e; this.ne.fireEvent("set"); this.elm.element.html(this.content); }, nicCommand: function (cmd, args) { document.execCommand(cmd, false, args); } }); }()); /** * 颜色选择trigger * * Created by GUY on 2015/11/26. * @class BI.RichEditorBackgroundChooserTrigger * @extends BI.Widget */ BI.RichEditorBackgroundChooserTrigger = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.RichEditorBackgroundChooserTrigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { width: 20, height: 20 }); }, _init: function () { BI.RichEditorBackgroundChooserTrigger.superclass._init.apply(this, arguments); this.font = BI.createWidget({ type: "bi.icon_button", cls: "text-background-font" }); this.underline = BI.createWidget({ type: "bi.icon_button", cls: "text-color-underline-font" }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.font, top: 2, left: 2 }, { el: this.underline, top: 7, left: 2 }] }); }, setValue: function (color) { this.underline.element.css("color", color); }, getValue: function () { return this.font.element.css("color"); } }); BI.shortcut("bi.rich_editor_background_color_chooser_trigger", BI.RichEditorBackgroundChooserTrigger);/** * * Created by GUY on 2015/11/26. * @class BI.RichEditorAlignCenterButton * @extends BI.RichEditorAction */ BI.RichEditorAlignCenterButton = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorAlignCenterButton.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "justifycenter" }); }, _init: function () { BI.RichEditorAlignCenterButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.align = BI.createWidget({ type: "bi.icon_button", element: this, forceNotSelected: true, title: BI.i18nText("BI-Word_Align_Center"), height: 20, width: 20, cls: "text-toolbar-button bi-list-item-active text-align-center-font" }); this.align.on(BI.IconButton.EVENT_CHANGE, function () { self.doCommand(); }); }, activate: function () { }, deactivate: function () { } }); BI.shortcut("bi.rich_editor_align_center_button", BI.RichEditorAlignCenterButton);/** * * Created by GUY on 2015/11/26. * @class BI.RichEditorAlignLeftButton * @extends BI.RichEditorAction */ BI.RichEditorAlignLeftButton = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorAlignLeftButton.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "justifyleft" }); }, _init: function () { BI.RichEditorAlignLeftButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.align = BI.createWidget({ type: "bi.icon_button", element: this, forceNotSelected: true, title: BI.i18nText("BI-Word_Align_Left"), height: 20, width: 20, cls: "text-toolbar-button bi-list-item-active text-align-left-font" }); this.align.on(BI.IconButton.EVENT_CHANGE, function () { self.doCommand(); }); }, activate: function () { }, deactivate: function () { } }); BI.shortcut("bi.rich_editor_align_left_button", BI.RichEditorAlignLeftButton);/** * * Created by GUY on 2015/11/26. * @class BI.RichEditorAlignRightButton * @extends BI.RichEditorAction */ BI.RichEditorAlignRightButton = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorAlignRightButton.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "justifyright" }); }, _init: function () { BI.RichEditorAlignRightButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.align = BI.createWidget({ type: "bi.icon_button", element: this, forceNotSelected: true, title: BI.i18nText("BI-Word_Align_Right"), height: 20, width: 20, cls: "text-toolbar-button bi-list-item-active text-align-right-font" }); this.align.on(BI.IconButton.EVENT_CHANGE, function () { self.doCommand(); }); }, activate: function () { }, deactivate: function () { } }); BI.shortcut("bi.rich_editor_align_right_button", BI.RichEditorAlignRightButton);/** * * Created by GUY on 2015/11/26. * @class BI.RichEditorBoldButton * @extends BI.RichEditorAction */ BI.RichEditorBoldButton = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorBoldButton.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "Bold", tags: ["B", "STRONG"], css: {fontWeight: "bold"} }); }, _init: function () { BI.RichEditorBoldButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.bold = BI.createWidget({ type: "bi.icon_button", element: this, title: BI.i18nText("BI-Basic_Bold"), height: 20, width: 20, cls: "text-toolbar-button bi-list-item-active text-bold-font" }); this.bold.on(BI.IconButton.EVENT_CHANGE, function () { self.doCommand(); }); }, activate: function () { this.bold.setSelected(true); }, deactivate: function () { this.bold.setSelected(false); } }); BI.shortcut("bi.rich_editor_bold_button", BI.RichEditorBoldButton);/** * * Created by GUY on 2015/11/26. * @class BI.RichEditorItalicButton * @extends BI.RichEditorAction */ BI.RichEditorItalicButton = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorItalicButton.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "Italic", tags: ["EM", "I"], css: {fontStyle: "italic"} }); }, _init: function () { BI.RichEditorItalicButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.italic = BI.createWidget({ type: "bi.icon_button", element: this, title: BI.i18nText("BI-Basic_Italic"), height: 20, width: 20, cls: "text-toolbar-button bi-list-item-active text-italic-font" }); this.italic.on(BI.IconButton.EVENT_CHANGE, function () { self.doCommand(); }); }, activate: function () { this.italic.setSelected(true); }, deactivate: function () { this.italic.setSelected(false); } }); BI.shortcut("bi.rich_editor_italic_button", BI.RichEditorItalicButton);/** * * Created by GUY on 2015/11/26. * @class BI.RichEditorParamButton * @extends BI.RichEditorParamAction */ BI.RichEditorParamButton = BI.inherit(BI.RichEditorParamAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorParamButton.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20 }); }, _init: function () { BI.RichEditorParamButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.param = BI.createWidget({ type: "bi.button", element: this, level: "ignore", minWidth: 0, text: BI.i18nText("BI-Formula_Insert"), height: 20, width: 30 }); this.param.on(BI.Button.EVENT_CHANGE, function () { self.addParam("参数"); }); }, activate: function () { }, deactivate: function () { } }); BI.shortcut("bi.rich_editor_param_button", BI.RichEditorParamButton);/** * * Created by GUY on 2015/11/26. * @class BI.RichEditorItalicButton * @extends BI.RichEditorAction */ BI.RichEditorUnderlineButton = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorUnderlineButton.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "Underline", tags: ["U"], css: {textDecoration: "underline"} }); }, _init: function () { BI.RichEditorUnderlineButton.superclass._init.apply(this, arguments); var self = this, o = this.options; this.underline = BI.createWidget({ type: "bi.icon_button", element: this, title: BI.i18nText("BI-Basic_Underline"), height: 20, width: 20, cls: "text-toolbar-button bi-list-item-active text-underline-font" }); this.underline.on(BI.IconButton.EVENT_CHANGE, function () { self.doCommand(); }); }, activate: function () { this.underline.setSelected(true); }, deactivate: function () { this.underline.setSelected(false); } }); BI.shortcut("bi.rich_editor_underline_button", BI.RichEditorUnderlineButton);/** * 颜色选择trigger * * Created by GUY on 2015/11/26. * @class BI.RichEditorColorChooserTrigger * @extends BI.Widget */ BI.RichEditorColorChooserTrigger = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.RichEditorColorChooserTrigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { width: 20, height: 20 }); }, _init: function () { BI.RichEditorColorChooserTrigger.superclass._init.apply(this, arguments); this.font = BI.createWidget({ type: "bi.icon_button", cls: "text-color-font" }); this.underline = BI.createWidget({ type: "bi.icon_button", cls: "text-color-underline-font" }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.font, top: 2, left: 2 }, { el: this.underline, top: 7, left: 2 }] }); }, setValue: function (color) { this.underline.element.css("color", color); }, getValue: function () { return this.font.element.css("color"); } }); BI.shortcut("bi.rich_editor_color_chooser_trigger", BI.RichEditorColorChooserTrigger);/** * 颜色选择 * * Created by GUY on 2015/11/26. * @class BI.RichEditorBackgroundColorChooser * @extends BI.RichEditorAction */ BI.RichEditorBackgroundColorChooser = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorBackgroundColorChooser.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20 }); }, _init: function () { BI.RichEditorBackgroundColorChooser.superclass._init.apply(this, arguments); var self = this, o = this.options; this.colorchooser = BI.createWidget({ type: "bi.color_chooser", element: this, width: o.width, height: o.height, el: { type: "bi.rich_editor_background_color_chooser_trigger", title: BI.i18nText("BI-Widget_Background_Colour"), cls: "text-toolbar-button" } }); this.colorchooser.on(BI.ColorChooser.EVENT_CHANGE, function () { var backgroundColor = this.getValue(); o.editor.element.css({ backgroundColor: backgroundColor, color: BI.DOM.getContrastColor(backgroundColor) }); this.setValue(""); }); }, hideIf: function (e) { if(!this.colorchooser.element.find(e.target).length > 0) { this.colorchooser.hideView(); } }, deactivate: function () { } }); BI.shortcut("bi.rich_editor_background_color_chooser", BI.RichEditorBackgroundColorChooser);/** * 颜色选择 * * Created by GUY on 2015/11/26. * @class BI.RichEditorColorChooser * @extends BI.RichEditorAction */ BI.RichEditorColorChooser = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorColorChooser.superclass._defaultConfig.apply(this, arguments), { width: 20, height: 20, command: "foreColor" }); }, _init: function () { BI.RichEditorColorChooser.superclass._init.apply(this, arguments); var self = this, o = this.options; this.colorchooser = BI.createWidget({ type: "bi.color_chooser", element: this, width: o.width, height: o.height, el: { type: "bi.rich_editor_color_chooser_trigger", title: BI.i18nText("BI-Font_Colour"), cls: "text-toolbar-button" } }); this.colorchooser.on(BI.ColorChooser.EVENT_CHANGE, function () { self.doCommand(this.getValue()); }); }, hideIf: function (e) { if(!this.colorchooser.element.find(e.target).length > 0) { this.colorchooser.hideView(); } }, deactivate: function () { this.colorchooser.setValue(""); } }); BI.shortcut("bi.rich_editor_color_chooser", BI.RichEditorColorChooser);/** * 字体大小选择 * * Created by GUY on 2015/11/26. * @class BI.RichEditorSizeChooser * @extends BI.RichEditorAction */ BI.RichEditorSizeChooser = BI.inherit(BI.RichEditorAction, { _defaultConfig: function () { return BI.extend(BI.RichEditorSizeChooser.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-rich-editor-size-chooser bi-border bi-card", command: "FontSize", width: 50, height: 20 }); }, _items: [{ value: 1, text: "1(8pt)" }, { value: 2, text: "2(10pt)" }, { value: 3, text: "3(12pt)" }, { value: 4, text: "4(14pt)" }, { value: 5, text: "5(18pt)" }, { value: 6, text: "6(24pt)" }], _init: function () { BI.RichEditorSizeChooser.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.text_trigger", readonly: true, height: o.height, triggerWidth: 16, text: BI.i18nText("BI-Font_Size") }); this.combo = BI.createWidget({ type: "bi.combo", element: this, el: this.trigger, adjustLength: 1, popup: { maxWidth: 70, minWidth: 70, el: { type: "bi.button_group", items: BI.createItems(this._items, { type: "bi.single_select_item" }), layouts: [{ type: "bi.vertical" }] } } }); this.combo.on(BI.Combo.EVENT_CHANGE, function () { var val = this.getValue()[0]; self.doCommand(val); this.hideView(); this.setValue([]); }); }, hideIf: function (e) { if(!this.combo.element.find(e.target).length > 0) { this.combo.hideView(); } } }); BI.shortcut("bi.rich_editor_size_chooser", BI.RichEditorSizeChooser);/** * 富文本编辑器 * * Created by GUY on 2017/9/15. * @class BI.RichEditor * @extends BI.Widget */ BI.RichEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.RichEditor.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-rich-editor bi-card", toolbar: {} }); }, _init: function () { BI.RichEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.nic_editor", width: o.width, height: o.height }); this.editor.on(BI.NicEditor.EVENT_BLUR, function () { self.fireEvent(BI.RichEditor.EVENT_CONFIRM); }); this.combo = BI.createWidget({ type: "bi.combo", element: this, toggle: false, direction: "top,left", isNeedAdjustWidth: false, isNeedAdjustHeight: false, adjustLength: 1, el: this.editor, popup: { el: BI.extend({ type: "bi.rich_editor_text_toolbar", editor: this.editor }, o.toolbar), height: 30, stopPropagation: true, stopEvent: true } }); this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { }); }, setValue: function (v) { this.editor.setValue(v); }, getValue: function () { return this.editor.getValue(); } }); BI.RichEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.shortcut("bi.rich_editor", BI.RichEditor);/** * 分段控件使用的button * * Created by GUY on 2015/9/7. * @class BI.SegmentButton * @extends BI.BasicButton */ BI.SegmentButton = BI.inherit(BI.BasicButton, { _defaultConfig: function () { var conf = BI.SegmentButton.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-segment-button bi-list-item-active", shadow: true, readonly: true, hgap: 5 }); }, _init: function () { BI.SegmentButton.superclass._init.apply(this, arguments); var opts = this.options, self = this; // if (BI.isNumber(opts.height) && BI.isNull(opts.lineHeight)) { // this.element.css({lineHeight : (opts.height - 2) + 'px'}); // } this.text = BI.createWidget({ type: "bi.label", element: this, height: opts.height - 2, whiteSpace: opts.whiteSpace, text: opts.text, value: opts.value, hgap: opts.hgap }); }, setSelected: function () { BI.SegmentButton.superclass.setSelected.apply(this, arguments); }, setText: function (text) { BI.SegmentButton.superclass.setText.apply(this, arguments); this.text.setText(text); }, destroy: function () { BI.SegmentButton.superclass.destroy.apply(this, arguments); } }); BI.shortcut("bi.segment_button", BI.SegmentButton);/** * 单选按钮组 * * Created by GUY on 2015/9/7. * @class BI.Segment * @extends BI.Widget */ BI.Segment = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.Segment.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-segment", items: [], height: 24 }); }, _init: function () { BI.Segment.superclass._init.apply(this, arguments); var self = this, o = this.options; this.buttonGroup = BI.createWidget({ element: this, type: "bi.button_group", items: BI.createItems(o.items, { type: "bi.segment_button", height: o.height - 2, whiteSpace: o.whiteSpace }), layout: [ { type: "bi.center" } ] }); this.buttonGroup.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.buttonGroup.on(BI.ButtonGroup.EVENT_CHANGE, function (value, obj) { self.fireEvent(BI.Segment.EVENT_CHANGE, value, obj); }); }, setValue: function (v) { this.buttonGroup.setValue(v); }, setEnabledValue: function (v) { this.buttonGroup.setEnabledValue(v); }, getValue: function () { return this.buttonGroup.getValue(); } }); BI.Segment.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.segment", BI.Segment);/** * 自适应宽度的表格 * * Created by GUY on 2016/2/3. * @class BI.AdaptiveTable * @extends BI.Widget */ BI.AdaptiveTable = BI.inherit(BI.Widget, { _const: { perColumnSize: 100 }, _defaultConfig: function () { return BI.extend(BI.AdaptiveTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-adaptive-table", el: { type: "bi.resizable_table" }, isNeedResize: true, isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为true时生效 isNeedMerge: false, // 是否需要合并单元格 mergeCols: [], // 合并的单元格列号 mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], headerRowSize: 25, rowSize: 25, regionColumnSize: [], header: [], items: [], // 二维数组 // 交叉表头 crossHeader: [], crossItems: [] }); }, _init: function () { BI.AdaptiveTable.superclass._init.apply(this, arguments); var self = this, o = this.options; var data = this._digest(); this.table = BI.createWidget(o.el, { type: "bi.resizable_table", element: this, width: o.width, height: o.height, isNeedResize: o.isNeedResize, isResizeAdapt: false, isNeedFreeze: o.isNeedFreeze, freezeCols: data.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: o.mergeCols, mergeRule: o.mergeRule, columnSize: data.columnSize, headerRowSize: o.headerRowSize, rowSize: o.rowSize, regionColumnSize: data.regionColumnSize, header: o.header, items: o.items, // 交叉表头 crossHeader: o.crossHeader, crossItems: o.crossItems }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); self._populate(); self.table.populate(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { o.columnSize = this.getColumnSize(); self._populate(); self.table.populate(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); }, _getFreezeColLength: function () { var o = this.options; return o.isNeedFreeze === true ? BI.clamp(o.freezeCols.length, 0, o.columnSize.length) : 0; }, _digest: function () { var o = this.options; var columnSize = o.columnSize.slice(); var regionColumnSize = o.regionColumnSize.slice(); var freezeCols = o.freezeCols.slice(); var regionSize = o.regionColumnSize[0]; var freezeColLength = this._getFreezeColLength(); if (!regionSize || regionSize > o.width - 10 || regionSize < 10) { regionSize = (freezeColLength > o.columnSize.length / 2 ? 2 / 3 : 1 / 3) * o.width; } if (freezeColLength === 0) { regionSize = 0; } if (freezeCols.length >= columnSize.length) { freezeCols = []; } if (!BI.isNumber(columnSize[0])) { columnSize = o.minColumnSize.slice(); } var summaryFreezeColumnSize = 0, summaryColumnSize = 0; BI.each(columnSize, function (i, size) { if (i < freezeColLength) { summaryFreezeColumnSize += size; } summaryColumnSize += size; }); if (freezeColLength > 0) { columnSize[freezeColLength - 1] = BI.clamp(regionSize - (summaryFreezeColumnSize - columnSize[freezeColLength - 1]), o.minColumnSize[freezeColLength - 1] || 10, o.maxColumnSize[freezeColLength - 1] || Number.MAX_VALUE); } if (columnSize.length > 0) { columnSize[columnSize.length - 1] = BI.clamp(o.width - BI.GridTableScrollbar.SIZE - regionSize - (summaryColumnSize - summaryFreezeColumnSize - columnSize[columnSize.length - 1]), o.minColumnSize[columnSize.length - 1] || 10, o.maxColumnSize[columnSize.length - 1] || Number.MAX_VALUE); } regionColumnSize[0] = regionSize; return { freezeCols: freezeCols, columnSize: columnSize, regionColumnSize: regionColumnSize }; }, _populate: function () { var o = this.options; var data = this._digest(); o.regionColumnSize = data.regionColumnSize; o.columnSize = data.columnSize; this.table.setColumnSize(data.columnSize); this.table.setRegionColumnSize(data.regionColumnSize); this.table.attr("freezeCols", data.freezeCols); }, setWidth: function (width) { BI.AdaptiveTable.superclass.setWidth.apply(this, arguments); this.table.setWidth(width); }, setHeight: function (height) { BI.AdaptiveTable.superclass.setHeight.apply(this, arguments); this.table.setHeight(height); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; }, getColumnSize: function () { return this.table.getColumnSize(); }, setRegionColumnSize: function (regionColumnSize) { this.options.regionColumnSize = regionColumnSize; }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, attr: function (key, value) { var v = BI.AdaptiveTable.superclass.attr.apply(this, arguments); if (key === "freezeCols") { return v; } return this.table.attr.apply(this.table, arguments); }, restore: function () { this.table.restore(); }, populate: function (items) { var self = this, o = this.options; this._populate(); this.table.populate.apply(this.table, arguments); }, destroy: function () { this.table.destroy(); BI.AdaptiveTable.superclass.destroy.apply(this, arguments); } }); BI.shortcut("bi.adaptive_table", BI.AdaptiveTable);/** * * 层级树状结构的表格 * * Created by GUY on 2016/8/12. * @class BI.DynamicSummaryLayerTreeTable * @extends BI.Widget */ BI.DynamicSummaryLayerTreeTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DynamicSummaryLayerTreeTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-dynamic-summary-layer-tree-table", el: { type: "bi.resizable_table" }, isNeedResize: true, // 是否需要调整列宽 isResizeAdapt: true, // 是否需要在调整列宽或区域宽度的时候它们自适应变化 isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为tree时生效 isNeedMerge: true, // 是否需要合并单元格 mergeCols: [], mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], headerRowSize: 25, footerRowSize: 25, rowSize: 25, regionColumnSize: [], // 行表头 rowHeaderCreator: null, headerCellStyleGetter: BI.emptyFn, summaryCellStyleGetter: BI.emptyFn, sequenceCellStyleGetter: BI.emptyFn, header: [], footer: false, items: [], // 交叉表头 crossHeader: [], crossItems: [] }); }, _getVDeep: function () { return this.options.crossHeader.length;// 纵向深度 }, _getHDeep: function () { var o = this.options; return Math.max(o.mergeCols.length, o.freezeCols.length, BI.TableTree.maxDeep(o.items) - 1); }, _createHeader: function (vDeep) { var self = this, o = this.options; var header = o.header || [], crossHeader = o.crossHeader || []; var items = BI.TableTree.formatCrossItems(o.crossItems, vDeep, o.headerCellStyleGetter); var result = []; BI.each(items, function (row, node) { var c = [crossHeader[row]]; result.push(c.concat(node || [])); }); if (header && header.length > 0) { var newHeader = this._formatColumns(header); var deep = this._getHDeep(); if (deep <= 0) { newHeader.unshift(o.rowHeaderCreator || { type: "bi.table_style_cell", text: BI.i18nText("BI-Row_Header"), styleGetter: o.headerCellStyleGetter }); } else { newHeader[0] = o.rowHeaderCreator || { type: "bi.table_style_cell", text: BI.i18nText("BI-Row_Header"), styleGetter: o.headerCellStyleGetter }; } result.push(newHeader); } return result; }, _formatItems: function (nodes, header, deep) { var self = this, o = this.options; var result = []; function track (node, layer) { node.type || (node.type = "bi.layer_tree_table_cell"); node.layer = layer; var next = [node]; next = next.concat(node.values || []); if (next.length > 0) { result.push(next); } if (BI.isNotEmptyArray(node.children)) { BI.each(node.children, function (index, child) { track(child, layer + 1); }); } } BI.each(nodes, function (i, node) { BI.each(node.children, function (j, c) { track(c, 0); }); if (BI.isArray(node.values)) { var next = [{ type: "bi.table_style_cell", text: BI.i18nText("BI-Summary_Values"), styleGetter: function () { return o.summaryCellStyleGetter(true); } }].concat(node.values); result.push(next); } }); return BI.DynamicSummaryTreeTable.formatSummaryItems(result, header, o.crossItems, 1); }, _formatColumns: function (columns, deep) { if (BI.isNotEmptyArray(columns)) { deep = deep || this._getHDeep(); return columns.slice(Math.max(0, deep - 1)); } return columns; }, _formatFreezeCols: function () { if (this.options.freezeCols.length > 0) { return [0]; } return []; }, _formatColumnSize: function (columnSize, deep) { if (columnSize.length <= 0) { return []; } var result = [0]; deep = deep || this._getHDeep(); BI.each(columnSize, function (i, size) { if (i < deep) { result[0] += size; return; } result.push(size); }); return result; }, _recomputeColumnSize: function () { var o = this.options; o.regionColumnSize = this.table.getRegionColumnSize(); var columnSize = this.table.getColumnSize().slice(); if (o.freezeCols.length > 1) { for (var i = 0; i < o.freezeCols.length - 1; i++) { columnSize.splice(1, 0, 0); } } o.columnSize = columnSize; }, _digest: function () { var o = this.options; var deep = this._getHDeep(); var vDeep = this._getVDeep(); var header = this._createHeader(vDeep); var data = this._formatItems(o.items, header, deep); var columnSize = o.columnSize.slice(); var minColumnSize = o.minColumnSize.slice(); var maxColumnSize = o.maxColumnSize.slice(); BI.removeAt(columnSize, data.deletedCols); BI.removeAt(minColumnSize, data.deletedCols); BI.removeAt(maxColumnSize, data.deletedCols); return { header: data.header, items: data.items, columnSize: this._formatColumnSize(columnSize, deep), minColumnSize: this._formatColumns(minColumnSize, deep), maxColumnSize: this._formatColumns(maxColumnSize, deep), freezeCols: this._formatFreezeCols() }; }, _init: function () { BI.DynamicSummaryLayerTreeTable.superclass._init.apply(this, arguments); var self = this, o = this.options; var data = this._digest(); this.table = BI.createWidget(o.el, { type: "bi.resizable_table", element: this, width: o.width, height: o.height, isNeedResize: o.isNeedResize, isResizeAdapt: o.isResizeAdapt, isNeedFreeze: o.isNeedFreeze, freezeCols: data.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: [], mergeRule: o.mergeRule, columnSize: data.columnSize, minColumnSize: data.minColumnSize, maxColumnSize: data.maxColumnSize, headerRowSize: o.headerRowSize, rowSize: o.rowSize, regionColumnSize: o.regionColumnSize, header: data.header, items: data.items }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { self._recomputeColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { self._recomputeColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); }, setWidth: function (width) { BI.DynamicSummaryLayerTreeTable.superclass.setWidth.apply(this, arguments); this.table.setWidth(width); }, setHeight: function (height) { BI.DynamicSummaryLayerTreeTable.superclass.setHeight.apply(this, arguments); this.table.setHeight(height); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; }, getColumnSize: function () { return this.options.columnSize; }, setRegionColumnSize: function (columnSize) { this.options.regionColumnSize = columnSize; this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, attr: function (key, value) { var self = this; if (BI.isObject(key)) { BI.each(key, function (k, v) { self.attr(k, v); }); return; } BI.DynamicSummaryLayerTreeTable.superclass.attr.apply(this, arguments); switch (key) { case "columnSize": case "minColumnSize": case "maxColumnSize": case "freezeCols": case "mergeCols": return; } this.table.attr.apply(this.table, [key, value]); }, restore: function () { this.table.restore(); }, populate: function (items, header, crossItems, crossHeader) { var o = this.options; if (items) { o.items = items; } if (header) { o.header = header; } if (crossItems) { o.crossItems = crossItems; } if (crossHeader) { o.crossHeader = crossHeader; } var data = this._digest(); this.table.setColumnSize(data.columnSize); this.table.attr("minColumnSize", data.minColumnSize); this.table.attr("maxColumnSize", data.maxColumnSize); this.table.attr("freezeCols", data.freezeCols); this.table.populate(data.items, data.header); }, destroy: function () { this.table.destroy(); BI.DynamicSummaryLayerTreeTable.superclass.destroy.apply(this, arguments); } }); BI.shortcut("bi.dynamic_summary_layer_tree_table", BI.DynamicSummaryLayerTreeTable);/** * * 树状结构的表格 * * Created by GUY on 2015/8/12. * @class BI.DynamicSummaryTreeTable * @extends BI.Widget */ BI.DynamicSummaryTreeTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DynamicSummaryTreeTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-dynamic-summary-tree-table", el: { type: "bi.resizable_table" }, isNeedResize: true, // 是否需要调整列宽 isResizeAdapt: true, // 是否需要在调整列宽或区域宽度的时候它们自适应变化 isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为tree时生效 isNeedMerge: true, // 是否需要合并单元格 mergeCols: [], mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], headerRowSize: 25, footerRowSize: 25, rowSize: 25, regionColumnSize: [], headerCellStyleGetter: BI.emptyFn, summaryCellStyleGetter: BI.emptyFn, sequenceCellStyleGetter: BI.emptyFn, header: [], footer: false, items: [], // 交叉表头 crossHeader: [], crossItems: [] }); }, _getVDeep: function () { return this.options.crossHeader.length;// 纵向深度 }, _getHDeep: function () { var o = this.options; return Math.max(o.mergeCols.length, o.freezeCols.length, BI.TableTree.maxDeep(o.items) - 1); }, _init: function () { BI.DynamicSummaryTreeTable.superclass._init.apply(this, arguments); var self = this, o = this.options; var data = this._digest(); this.table = BI.createWidget(o.el, { type: "bi.resizable_table", element: this, width: o.width, height: o.height, isNeedResize: o.isNeedResize, isResizeAdapt: o.isResizeAdapt, isNeedFreeze: o.isNeedFreeze, freezeCols: o.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: o.mergeCols, mergeRule: o.mergeRule, columnSize: o.columnSize, minColumnSize: o.minColumnSize, maxColumnSize: o.maxColumnSize, headerRowSize: o.headerRowSize, rowSize: o.rowSize, regionColumnSize: o.regionColumnSize, header: data.header, items: data.items }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); var columnSize = this.getColumnSize(); var length = o.columnSize.length - columnSize.length; o.columnSize = columnSize.slice(); o.columnSize = o.columnSize.concat(BI.makeArray(length, 0)); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); var columnSize = this.getColumnSize(); var length = o.columnSize.length - columnSize.length; o.columnSize = columnSize.slice(); o.columnSize = o.columnSize.concat(BI.makeArray(length, 0)); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); }, _digest: function () { var o = this.options; var deep = this._getHDeep(); var vDeep = this._getVDeep(); var header = BI.TableTree.formatHeader(o.header, o.crossHeader, o.crossItems, deep, vDeep, o.headerCellStyleGetter); var items = BI.DynamicSummaryTreeTable.formatHorizontalItems(o.items, deep, false, o.summaryCellStyleGetter); var data = BI.DynamicSummaryTreeTable.formatSummaryItems(items, header, o.crossItems, deep); var columnSize = o.columnSize.slice(); var minColumnSize = o.minColumnSize.slice(); var maxColumnSize = o.maxColumnSize.slice(); BI.removeAt(columnSize, data.deletedCols); BI.removeAt(minColumnSize, data.deletedCols); BI.removeAt(maxColumnSize, data.deletedCols); return { header: data.header, items: data.items, columnSize: columnSize, minColumnSize: minColumnSize, maxColumnSize: maxColumnSize }; }, setWidth: function (width) { BI.DynamicSummaryTreeTable.superclass.setWidth.apply(this, arguments); this.table.setWidth(width); }, setHeight: function (height) { BI.DynamicSummaryTreeTable.superclass.setHeight.apply(this, arguments); this.table.setHeight(height); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; }, getColumnSize: function () { return this.options.columnSize; }, setRegionColumnSize: function (columnSize) { this.options.regionColumnSize = columnSize; this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, attr: function (key) { BI.DynamicSummaryTreeTable.superclass.attr.apply(this, arguments); switch (key) { case "minColumnSize": case "maxColumnSize": return; } this.table.attr.apply(this.table, arguments); }, restore: function () { this.table.restore(); }, populate: function (items, header, crossItems, crossHeader) { var o = this.options; if (items) { o.items = items; } if (header) { o.header = header; } if (crossItems) { o.crossItems = crossItems; } if (crossHeader) { o.crossHeader = crossHeader; } var data = this._digest(); this.table.setColumnSize(data.columnSize); this.table.attr("minColumnSize", data.minColumnSize); this.table.attr("maxColumnSize", data.maxColumnSize); this.table.populate(data.items, data.header); }, destroy: function () { this.table.destroy(); BI.DynamicSummaryTreeTable.superclass.destroy.apply(this, arguments); } }); BI.extend(BI.DynamicSummaryTreeTable, { formatHorizontalItems: function (nodes, deep, isCross, styleGetter) { var result = []; function track (store, node) { var next; if (BI.isArray(node.children)) { BI.each(node.children, function (index, child) { var next; if (store != -1) { next = store.slice(); next.push(node); } else { next = []; } track(next, child); }); if (store != -1) { next = store.slice(); next.push(node); } else { next = []; } if ((store == -1 || node.children.length > 1) && BI.isNotEmptyArray(node.values)) { var summary = { text: BI.i18nText("BI-Summary_Values"), type: "bi.table_style_cell", styleGetter: function () { return styleGetter(store === -1); } }; for (var i = next.length; i < deep; i++) { next.push(summary); } if (!isCross) { next = next.concat(node.values); } if (next.length > 0) { if (!isCross) { result.push(next); } else { for (var k = 0, l = node.values.length; k < l; k++) { result.push(next); } } } } return; } if (store != -1) { next = store.slice(); for (var i = next.length; i < deep; i++) { next.push(node); } } else { next = []; } if (!isCross && BI.isArray(node.values)) { next = next.concat(node.values); } if (isCross && BI.isArray(node.values)) { for (var i = 0, len = node.values.length; i < len - 1; i++) { if (next.length > 0) { result.push(next); } } } if (next.length > 0) { result.push(next); } } BI.each(nodes, function (i, node) { track(-1, node); }); // 填充空位 BI.each(result, function (i, line) { var last = BI.last(line); for (var j = line.length; j < deep; j++) { line.push(last); } }); return result; }, formatSummaryItems: function (items, header, crossItems, deep) { // 求纵向需要去除的列 var cols = []; var leaf = 0; function track (node) { if (BI.isArray(node.children)) { BI.each(node.children, function (index, child) { track(child); }); if (BI.isNotEmptyArray(node.values)) { if (node.children.length === 1) { for (var i = 0; i < node.values.length; i++) { cols.push(leaf + i + deep); } } leaf += node.values.length; } return; } if (node.values && node.values.length > 1) { leaf += node.values.length; } else { leaf++; } } BI.each(crossItems, function (i, node) { track(node); }); if (cols.length > 0) { var nHeader = [], nItems = []; BI.each(header, function (i, node) { var nNode = node.slice(); BI.removeAt(nNode, cols); nHeader.push(nNode); }); BI.each(items, function (i, node) { var nNode = node.slice(); BI.removeAt(nNode, cols); nItems.push(nNode); }); header = nHeader; items = nItems; } return {items: items, header: header, deletedCols: cols}; } }); BI.shortcut("bi.dynamic_summary_tree_table", BI.DynamicSummaryTreeTable);/** * Created by GUY on 2016/5/7. * @class BI.LayerTreeTableCell * @extends BI.Single */ BI.LayerTreeTableCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.LayerTreeTableCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-layer-tree-table-cell", layer: 0, text: "" }); }, _init: function () { BI.LayerTreeTableCell.superclass._init.apply(this, arguments); var o = this.options; BI.createWidget({ type: "bi.label", element: this.element, textAlign: "left", whiteSpace: "nowrap", height: o.height, text: o.text, value: o.value, lgap: 5 + 30 * o.layer, rgap: 5 }); } }); BI.shortcut("bi.layer_tree_table_cell", BI.LayerTreeTableCell);/** * * 层级树状结构的表格 * * Created by GUY on 2016/5/7. * @class BI.LayerTreeTable * @extends BI.Widget */ BI.LayerTreeTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.LayerTreeTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-layer-tree-table", el: { type: "bi.resizable_table" }, isNeedResize: false, // 是否需要调整列宽 isResizeAdapt: true, // 是否需要在调整列宽或区域宽度的时候它们自适应变化 isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为tree时生效 isNeedMerge: true, // 是否需要合并单元格 mergeCols: [], mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], headerRowSize: 25, rowSize: 25, regionColumnSize: [], rowHeaderCreator: null, headerCellStyleGetter: BI.emptyFn, summaryCellStyleGetter: BI.emptyFn, sequenceCellStyleGetter: BI.emptyFn, header: [], items: [], // 交叉表头 crossHeader: [], crossItems: [] }); }, _getVDeep: function () { return this.options.crossHeader.length;// 纵向深度 }, _getHDeep: function () { var o = this.options; return Math.max(o.mergeCols.length, o.freezeCols.length, BI.TableTree.maxDeep(o.items) - 1); }, _createHeader: function (vDeep) { var self = this, o = this.options; var header = o.header || [], crossHeader = o.crossHeader || []; var items = BI.TableTree.formatCrossItems(o.crossItems, vDeep, o.headerCellStyleGetter); var result = []; BI.each(items, function (row, node) { var c = [crossHeader[row]]; result.push(c.concat(node || [])); }); if (header && header.length > 0) { var newHeader = this._formatColumns(header); var deep = this._getHDeep(); if (deep <= 0) { newHeader.unshift(o.rowHeaderCreator || { type: "bi.table_style_cell", text: BI.i18nText("BI-Row_Header"), styleGetter: o.headerCellStyleGetter }); } else { newHeader[0] = o.rowHeaderCreator || { type: "bi.table_style_cell", text: BI.i18nText("BI-Row_Header"), styleGetter: o.headerCellStyleGetter }; } result.push(newHeader); } return result; }, _formatItems: function (nodes) { var self = this, o = this.options; var result = []; function track (node, layer) { node.type || (node.type = "bi.layer_tree_table_cell"); node.layer = layer; var next = [node]; next = next.concat(node.values || []); if (next.length > 0) { result.push(next); } if (BI.isNotEmptyArray(node.children)) { BI.each(node.children, function (index, child) { track(child, layer + 1); }); } } BI.each(nodes, function (i, node) { BI.each(node.children, function (j, c) { track(c, 0); }); if (BI.isArray(node.values)) { var next = [{ type: "bi.table_style_cell", text: BI.i18nText("BI-Summary_Values"), styleGetter: function () { return o.summaryCellStyleGetter(true); } }].concat(node.values); result.push(next); } }); return result; }, _formatColumns: function (columns, deep) { if (BI.isNotEmptyArray(columns)) { deep = deep || this._getHDeep(); return columns.slice(Math.max(0, deep - 1)); } return columns; }, _formatFreezeCols: function () { if (this.options.freezeCols.length > 0) { return [0]; } return []; }, _formatColumnSize: function (columnSize, deep) { if (columnSize.length <= 0) { return []; } var result = [0]; deep = deep || this._getHDeep(); BI.each(columnSize, function (i, size) { if (i < deep) { result[0] += size; return; } result.push(size); }); return result; }, _digest: function () { var o = this.options; var deep = this._getHDeep(); var vDeep = this._getVDeep(); return { header: this._createHeader(vDeep), items: this._formatItems(o.items), columnSize: this._formatColumnSize(o.columnSize, deep), minColumnSize: this._formatColumns(o.minColumnSize, deep), maxColumnSize: this._formatColumns(o.maxColumnSize, deep), freezeCols: this._formatFreezeCols() }; }, _init: function () { BI.LayerTreeTable.superclass._init.apply(this, arguments); var self = this, o = this.options; var data = this._digest(); this.table = BI.createWidget(o.el, { type: "bi.resizable_table", element: this, width: o.width, height: o.height, isNeedResize: o.isNeedResize, isResizeAdapt: o.isResizeAdapt, isNeedFreeze: o.isNeedFreeze, freezeCols: data.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: [], mergeRule: o.mergeRule, columnSize: data.columnSize, minColumnSize: data.minColumnSize, maxColumnSize: data.maxColumnSize, headerRowSize: o.headerRowSize, rowSize: o.rowSize, regionColumnSize: o.regionColumnSize, header: data.header, items: data.items }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); }, setWidth: function (width) { BI.LayerTreeTable.superclass.setWidth.apply(this, arguments); this.table.setWidth(width); }, setHeight: function (height) { BI.LayerTreeTable.superclass.setHeight.apply(this, arguments); this.table.setHeight(height); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; }, getColumnSize: function () { var columnSize = this.table.getColumnSize(); var deep = this._getHDeep(); var pre = []; if (deep > 0) { pre = BI.makeArray(deep, columnSize[0] / deep); } return pre.concat(columnSize.slice(1)); }, setRegionColumnSize: function (columnSize) { this.options.regionColumnSize = columnSize; this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, attr: function (key, value) { var self = this; if (BI.isObject(key)) { BI.each(key, function (k, v) { self.attr(k, v); }); return; } BI.LayerTreeTable.superclass.attr.apply(this, arguments); switch (key) { case "columnSize": case "minColumnSize": case "maxColumnSize": case "freezeCols": case "mergeCols": return; } this.table.attr.apply(this.table, [key, value]); }, restore: function () { this.table.restore(); }, populate: function (items, header, crossItems, crossHeader) { var o = this.options; o.items = items || []; if (header) { o.header = header; } if (crossItems) { o.crossItems = crossItems; } if (crossHeader) { o.crossHeader = crossHeader; } var data = this._digest(); this.table.setColumnSize(data.columnSize); this.table.attr("freezeCols", data.freezeCols); this.table.attr("minColumnSize", data.minColumnSize); this.table.attr("maxColumnSize", data.maxColumnSize); this.table.populate(data.items, data.header); }, destroy: function () { this.table.destroy(); BI.LayerTreeTable.superclass.destroy.apply(this, arguments); } }); BI.shortcut("bi.layer_tree_table", BI.LayerTreeTable);/** * * Created by GUY on 2016/5/26. * @class BI.TableStyleCell * @extends BI.Single */ BI.TableStyleCell = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.TableStyleCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-table-style-cell", styleGetter: BI.emptyFn }); }, _init: function () { BI.TableStyleCell.superclass._init.apply(this, arguments); var o = this.options; this.text = BI.createWidget({ type: "bi.label", element: this, textAlign: "left", forceCenter: true, hgap: 5, text: o.text }); this._digestStyle(); }, _digestStyle: function () { var o = this.options; var style = o.styleGetter(); if (style) { this.text.element.css(style); } }, setText: function (text) { this.text.setText(text); }, populate: function () { this._digestStyle(); } }); BI.shortcut("bi.table_style_cell", BI.TableStyleCell);/** * * 树状结构的表格 * * Created by GUY on 2015/9/22. * @class BI.TableTree * @extends BI.Widget */ BI.TableTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.TableTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-table-tree", el: { type: "bi.resizable_table" }, isNeedResize: true, // 是否需要调整列宽 isResizeAdapt: true, // 是否需要在调整列宽或区域宽度的时候它们自适应变化 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为tree时生效 isNeedMerge: true, // 是否需要合并单元格 mergeCols: [], mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], headerRowSize: 25, rowSize: 25, regionColumnSize: [], headerCellStyleGetter: BI.emptyFn, summaryCellStyleGetter: BI.emptyFn, sequenceCellStyleGetter: BI.emptyFn, header: [], items: [], // 交叉表头 crossHeader: [], crossItems: [] }); }, _getVDeep: function () { return this.options.crossHeader.length;// 纵向深度 }, _getHDeep: function () { var o = this.options; return Math.max(o.mergeCols.length, o.freezeCols.length, BI.TableTree.maxDeep(o.items) - 1); }, _init: function () { BI.TableTree.superclass._init.apply(this, arguments); var self = this, o = this.options; var data = this._digest(); this.table = BI.createWidget(o.el, { type: "bi.resizable_table", element: this, width: o.width, height: o.height, isNeedResize: o.isNeedResize, isResizeAdapt: o.isResizeAdapt, isNeedFreeze: o.isNeedFreeze, freezeCols: o.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: o.mergeCols, mergeRule: o.mergeRule, columnSize: o.columnSize, minColumnSize: o.minColumnSize, maxColumnSize: o.maxColumnSize, headerRowSize: o.headerRowSize, rowSize: o.rowSize, regionColumnSize: o.regionColumnSize, header: data.header, items: data.items }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); }, _digest: function () { var self = this, o = this.options; var deep = this._getHDeep(); var vDeep = this._getVDeep(); var header = BI.TableTree.formatHeader(o.header, o.crossHeader, o.crossItems, deep, vDeep, o.headerCellStyleGetter); var items = BI.TableTree.formatItems(o.items, deep, false, o.summaryCellStyleGetter); return { header: header, items: items }; }, setWidth: function (width) { BI.TableTree.superclass.setWidth.apply(this, arguments); this.table.setWidth(width); }, setHeight: function (height) { BI.TableTree.superclass.setHeight.apply(this, arguments); this.table.setHeight(height); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; this.table.setColumnSize(columnSize); }, getColumnSize: function () { return this.table.getColumnSize(); }, setRegionColumnSize: function (columnSize) { this.options.regionColumnSize = columnSize; this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, attr: function () { BI.TableTree.superclass.attr.apply(this, arguments); this.table.attr.apply(this.table, arguments); }, restore: function () { this.table.restore(); }, populate: function (items, header, crossItems, crossHeader) { var o = this.options; if (items) { o.items = items || []; } if (header) { o.header = header; } if (crossItems) { o.crossItems = crossItems; } if (crossHeader) { o.crossHeader = crossHeader; } var data = this._digest(); this.table.populate(data.items, data.header); }, destroy: function () { this.table.destroy(); BI.TableTree.superclass.destroy.apply(this, arguments); } }); BI.extend(BI.TableTree, { formatHeader: function (header, crossHeader, crossItems, hDeep, vDeep, styleGetter) { var items = BI.TableTree.formatCrossItems(crossItems, vDeep, styleGetter); var result = []; for (var i = 0; i < vDeep; i++) { var c = []; for (var j = 0; j < hDeep; j++) { c.push(crossHeader[i]); } result.push(c.concat(items[i] || [])); } if (header && header.length > 0) { result.push(header); } return result; }, formatItems: function (nodes, deep, isCross, styleGetter) { var self = this; var result = []; function track (store, node) { var next; if (BI.isArray(node.children)) { BI.each(node.children, function (index, child) { var next; if (store != -1) { next = store.slice(); next.push(node); } else { next = []; } track(next, child); }); if (store != -1) { next = store.slice(); next.push(node); } else { next = []; } if (/** (store == -1 || node.children.length > 1) &&**/ BI.isNotEmptyArray(node.values)) { var summary = { text: BI.i18nText("BI-Summary_Values"), type: "bi.table_style_cell", styleGetter: function () { return styleGetter(store === -1); } }; for (var i = next.length; i < deep; i++) { next.push(summary); } if (!isCross) { next = next.concat(node.values); } if (next.length > 0) { if (!isCross) { result.push(next); } else { for (var k = 0, l = node.values.length; k < l; k++) { result.push(next); } } } } return; } if (store != -1) { next = store.slice(); for (var i = next.length; i < deep; i++) { next.push(node); } } else { next = []; } if (!isCross && BI.isArray(node.values)) { next = next.concat(node.values); } if (isCross && BI.isArray(node.values)) { for (var i = 0, len = node.values.length; i < len - 1; i++) { if (next.length > 0) { result.push(next); } } } if (next.length > 0) { result.push(next); } } BI.each(nodes, function (i, node) { track(-1, node); }); // 填充空位 BI.each(result, function (i, line) { var last = BI.last(line); for (var j = line.length; j < deep; j++) { line.push(last); } }); return result; }, formatCrossItems: function (nodes, deep, styleGetter) { var items = BI.TableTree.formatItems(nodes, deep, true, styleGetter); return BI.unzip(items); }, maxDeep: function (nodes) { function track (deep, node) { var d = deep; if (BI.isNotEmptyArray(node.children)) { BI.each(node.children, function (index, child) { d = Math.max(d, track(deep + 1, child)); }); } return d; } var deep = 1; if (BI.isObject(nodes)) { BI.each(nodes, function (i, node) { deep = Math.max(deep, track(1, node)); }); } return deep; } }); BI.shortcut("bi.tree_table", BI.TableTree);/** * guy * 复选导航条 * Created by GUY on 2015/8/25. * @class BI.MultiSelectBar * @extends BI.BasicButton */ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.MultiSelectBar.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-multi-select-bar", height: 25, text: BI.i18nText("BI-Select_All"), isAllCheckedBySelectedValue: BI.emptyFn, // 手动控制选中 disableSelected: true, isHalfCheckedBySelectedValue: function (selectedValues) { return selectedValues.length > 0; }, halfSelected: false }); }, _init: function () { BI.MultiSelectBar.superclass._init.apply(this, arguments); var self = this, o = this.options; var isSelect = o.selected === true; var isHalfSelect = !o.selected && o.halfSelected; this.checkbox = BI.createWidget({ type: "bi.checkbox", stopPropagation: true, handler: function () { self.setSelected(self.isSelected()); }, selected: isSelect, invisible: isHalfSelect }); this.half = BI.createWidget({ type: "bi.half_icon_button", stopPropagation: true, handler: function () { self.setSelected(true); }, invisible: isSelect || !isHalfSelect }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, self.isSelected(), self); }); this.half.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, self.isSelected(), self); }); this.half.on(BI.HalfIconButton.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, self.isSelected(), self); }); this.checkbox.on(BI.Checkbox.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, self.isSelected(), self); }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, keyword: o.keyword, value: o.value, py: o.py }); BI.createWidget({ type: "bi.htape", element: this, items: [{ width: 36, el: { type: "bi.center_adapt", items: [this.checkbox, this.half] } }, { el: this.text }] }); }, _setSelected: function (v) { this.checkbox.setSelected(!!v); }, // 自己手动控制选中 beforeClick: function () { var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); if (isHalf === true) { this.setSelected(true); } else { this.setSelected(!isSelected); } }, setSelected: function (v) { this.checkbox.setSelected(v); this.setHalfSelected(false); }, setHalfSelected: function (b) { this.halfSelected = !!b; if (b === true) { this.checkbox.setSelected(false); this.half.visible(); this.checkbox.invisible(); } else { this.half.invisible(); this.checkbox.visible(); } }, isHalfSelected: function () { return !this.isSelected() && !!this.halfSelected; }, isSelected: function () { return this.checkbox.isSelected(); }, setValue: function (selectedValues) { BI.MultiSelectBar.superclass.setValue.apply(this, arguments); var isAllChecked = this.options.isAllCheckedBySelectedValue.apply(this, arguments); this._setSelected(isAllChecked); !isAllChecked && this.setHalfSelected(this.options.isHalfCheckedBySelectedValue.apply(this, arguments)); } }); BI.MultiSelectBar.EVENT_CHANGE = "MultiSelectBar.EVENT_CHANGE"; BI.shortcut("bi.multi_select_bar", BI.MultiSelectBar);/** * 表关联树 * * Created by GUY on 2015/12/15. * @class BI.BranchRelation * @extends BI.Widget */ BI.BranchRelation = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.BranchRelation.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-branch-relation-tree", items: [], centerOffset: 0, // 重心偏移量 direction: BI.Direction.Bottom, align: BI.VerticalAlign.Top }); }, _init: function () { BI.BranchRelation.superclass._init.apply(this, arguments); this.populate(this.options.items); }, // 树分层 _stratification: function () { var levels = []; this.tree.recursion(function (node, route) { // node.isRoot = route.length <= 1; node.leaf = node.isLeaf(); if (!levels[route.length - 1]) { levels[route.length - 1] = []; } levels[route.length - 1].push(node); }); return levels; }, // 计算所有节点的叶子结点个数 _calculateLeaves: function () { var count = 0; function track (node) { var c = 0; if (node.isLeaf()) { return 1; } BI.each(node.getChildren(), function (i, child) { c += track(child); }); node.set("leaves", c); return c; } count = track(this.tree.getRoot()); return count; }, // 树平移 _translate: function (levels) { var adjust = []; var maxLevel = levels.length; BI.each(levels, function (i, nodes) { if (!adjust[i]) { adjust[i] = []; } BI.each(nodes, function (j, node) { if (node.isLeaf() && i < maxLevel - 1) { var newNode = new BI.Node(BI.UUID()); // newNode.isEmptyRoot = node.isRoot || node.isEmptyRoot; newNode.isNew = true; // 把node向下一层移 var tar = 0; if (j > 0) { var c = nodes[j - 1].getLastChild(); tar = levels[i + 1].indexOf(c) + 1; } levels[i + 1].splice(tar, 0, node); // 新增一个临时树节点 var index = node.parent.getChildIndex(node.id); node.parent.removeChildByIndex(index); node.parent.addChild(newNode, index); newNode.addChild(node); adjust[i].push(newNode); nodes[j] = newNode; } else { adjust[i].push(node); } }); }); return adjust; }, // 树补白 _fill: function (levels) { var adjust = []; var maxLevel = levels.length; BI.each(levels, function (i, nodes) { if (!adjust[i]) { adjust[i] = []; } BI.each(nodes, function (j, node) { if (node.isLeaf() && i < maxLevel - 1) { var newNode = new BI.Node(BI.UUID()); newNode.leaf = true; newNode.width = node.width; newNode.height = node.height; newNode.isNew = true; // 把node向下一层移 var tar = 0; if (j > 0) { var c = nodes[j - 1].getLastChild(); tar = levels[i + 1].indexOf(c) + 1; } levels[i + 1].splice(tar, 0, newNode); // 新增一个临时树节点 node.addChild(newNode); } adjust[i].push(node); }); }); return adjust; }, // 树调整 _adjust: function (adjust) { while (true) { var isAllNeedAjust = false; BI.backEach(adjust, function (i, nodes) { BI.each(nodes, function (j, node) { if (!node.isNew) { var needAdjust = true; BI.any(node.getChildren(), function (k, n) { if (!n.isNew) { needAdjust = false; return true; } }); if (!node.isLeaf() && needAdjust === true) { var allChilds = []; BI.each(node.getChildren(), function (k, n) { allChilds = allChilds.concat(n.getChildren()); }); node.removeAllChilds(); BI.each(allChilds, function (k, c) { node.addChild(c); }); var newNode = new BI.Node(BI.UUID()); // newNode.isEmptyRoot = node.isRoot || node.isEmptyRoot; newNode.isNew = true; var index = node.parent.getChildIndex(node.id); node.parent.removeChildByIndex(index); node.parent.addChild(newNode, index); newNode.addChild(node); isAllNeedAjust = true; } } }); }); if (isAllNeedAjust === false) { break; } else {// 树重构 adjust = this._stratification(); } } return adjust; }, _calculateWidth: function () { var o = this.options; var width = 0; function track1 (node) { var w = 0; if (node.isLeaf()) { return node.width; } BI.each(node.getChildren(), function (i, child) { w += track1(child); }); return w; } function track2 (node) { var w = 0; if (node.isLeaf()) { return node.height; } BI.each(node.getChildren(), function (i, child) { w += track2(child); }); return w; } if (this._isVertical()) { width = track1(this.tree.getRoot()); } else { width = track2(this.tree.getRoot()); } return width; }, _isVertical: function () { var o = this.options; return o.direction === BI.Direction.Top || o.direction === BI.Direction.Bottom; }, _calculateHeight: function () { var o = this.options; var height = 0; function track1 (node) { var h = 0; BI.each(node.getChildren(), function (i, child) { h = Math.max(h, track1(child)); }); return h + (node.height || 0); } function track2 (node) { var h = 0; BI.each(node.getChildren(), function (i, child) { h = Math.max(h, track2(child)); }); return h + (node.width || 0); } if (this._isVertical()) { height = track1(this.tree.getRoot()); } else { height = track2(this.tree.getRoot()); } return height; }, _calculateXY: function (levels) { var o = this.options; var width = this._calculateWidth(); var height = this._calculateHeight(); var levelCount = levels.length; var allLeavesCount = this._calculateLeaves(); // 计算坐标 var xy = {}; var levelHeight = height / levelCount; BI.each(levels, function (i, nodes) { // 计算权重 var weights = []; BI.each(nodes, function (j, node) { weights[j] = (node.get("leaves") || 1) / allLeavesCount; }); BI.each(nodes, function (j, node) { // 求前j个元素的权重 var weight = BI.sum(weights.slice(0, j)); // 求坐标 var x = weight * width + weights[j] * width / 2; var y = i * levelHeight + levelHeight / 2; xy[node.id] = {x: x, y: y}; }); }); return xy; }, _stroke: function (levels, xy) { var height = this._calculateHeight(); var levelCount = levels.length; var levelHeight = height / levelCount; var self = this, o = this.options; switch (o.direction) { case BI.Direction.Top: BI.each(levels, function (i, nodes) { BI.each(nodes, function (j, node) { if (node.getChildrenLength() > 0 && !node.leaf) { var path = ""; var start = xy[node.id]; var split = start.y + levelHeight / 2; path += "M" + start.x + "," + (start.y + o.centerOffset) + "L" + start.x + "," + split; var end = []; BI.each(node.getChildren(), function (t, c) { var e = end[t] = xy[c.id]; path += "M" + e.x + "," + (e.y + o.centerOffset) + "L" + e.x + "," + split; }); if (end.length > 0) { path += "M" + BI.first(end).x + "," + split + "L" + BI.last(end).x + "," + split; } self.svg.path(path).attr("stroke", "#d4dadd"); } }); }); break; case BI.Direction.Bottom: BI.each(levels, function (i, nodes) { BI.each(nodes, function (j, node) { if (node.getChildrenLength() > 0 && !node.leaf) { var path = ""; var start = xy[node.id]; var split = start.y - levelHeight / 2; path += "M" + start.x + "," + (start.y - o.centerOffset) + "L" + start.x + "," + split; var end = []; BI.each(node.getChildren(), function (t, c) { var e = end[t] = xy[c.id]; path += "M" + e.x + "," + (e.y - o.centerOffset) + "L" + e.x + "," + split; }); if (end.length > 0) { path += "M" + BI.first(end).x + "," + split + "L" + BI.last(end).x + "," + split; } self.svg.path(path).attr("stroke", "#d4dadd"); } }); }); break; case BI.Direction.Left: BI.each(levels, function (i, nodes) { BI.each(nodes, function (j, node) { if (node.getChildrenLength() > 0 && !node.leaf) { var path = ""; var start = xy[node.id]; var split = start.y + levelHeight / 2; path += "M" + (start.y + o.centerOffset) + "," + start.x + "L" + split + "," + start.x; var end = []; BI.each(node.getChildren(), function (t, c) { var e = end[t] = xy[c.id]; path += "M" + (e.y + o.centerOffset) + "," + e.x + "L" + split + "," + e.x; }); if (end.length > 0) { path += "M" + split + "," + BI.first(end).x + "L" + split + "," + BI.last(end).x; } self.svg.path(path).attr("stroke", "#d4dadd"); } }); }); break; case BI.Direction.Right: BI.each(levels, function (i, nodes) { BI.each(nodes, function (j, node) { if (node.getChildrenLength() > 0 && !node.leaf) { var path = ""; var start = xy[node.id]; var split = start.y - levelHeight / 2; path += "M" + (start.y - o.centerOffset) + "," + start.x + "L" + split + "," + start.x; var end = []; BI.each(node.getChildren(), function (t, c) { var e = end[t] = xy[c.id]; path += "M" + (e.y - o.centerOffset) + "," + e.x + "L" + split + "," + e.x; }); if (end.length > 0) { path += "M" + split + "," + BI.first(end).x + "L" + split + "," + BI.last(end).x; } self.svg.path(path).attr("stroke", "#d4dadd"); } }); }); break; } }, _createBranches: function (levels) { var self = this, o = this.options; if (o.direction === BI.Direction.Bottom || o.direction === BI.Direction.Right) { levels = levels.reverse(); } var xy = this._calculateXY(levels); // 画图 this._stroke(levels, xy); }, _isNeedAdjust: function () { var o = this.options; return o.direction === BI.Direction.Top && o.align === BI.VerticalAlign.Bottom || o.direction === BI.Direction.Bottom && o.align === BI.VerticalAlign.Top || o.direction === BI.Direction.Left && o.align === BI.HorizontalAlign.Right || o.direction === BI.Direction.Right && o.align === BI.HorizontalAlign.Left; }, setValue: function (value) { }, getValue: function () { }, _transformToTreeFormat: function (sNodes) { var i, l; if (!sNodes) { return []; } if (BI.isArray(sNodes)) { var r = []; var tmpMap = []; for (i = 0, l = sNodes.length; i < l; i++) { tmpMap[sNodes[i].id] = sNodes[i]; } for (i = 0, l = sNodes.length; i < l; i++) { if (tmpMap[sNodes[i].pId] && sNodes[i].id != sNodes[i].pId) { if (!tmpMap[sNodes[i].pId].children) { tmpMap[sNodes[i].pId].children = []; } tmpMap[sNodes[i].pId].children.push(sNodes[i]); } else { r.push(sNodes[i]); } } return r; } return [sNodes]; }, populate: function (items) { var self = this, o = this.options; o.items = items || []; this.empty(); items = this._transformToTreeFormat(o.items); this.tree = new BI.Tree(); this.tree.initTree(items); this.svg = BI.createWidget({ type: "bi.svg" }); // 树分层 var levels = this._stratification(); if (this._isNeedAdjust()) { // 树平移 var adjust = this._translate(levels); // 树调整 adjust = this._adjust(adjust); this._createBranches(adjust); } else { var adjust = this._fill(levels); this._createBranches(adjust); } var container = BI.createWidget({ type: "bi.layout", width: this._isVertical() ? this._calculateWidth() : this._calculateHeight(), height: this._isVertical() ? this._calculateHeight() : this._calculateWidth() }); BI.createWidget({ type: "bi.absolute", element: container, items: [{ el: this.svg, top: 0, left: 0, right: 0, bottom: 0 }] }); if (this._isVertical()) { items = [{ type: "bi.handstand_branch_tree", expander: { direction: o.direction }, el: { layouts: [{ type: "bi.horizontal_adapt", verticalAlign: o.align }] }, items: items }]; } else { items = [{ type: "bi.branch_tree", expander: { direction: o.direction }, el: { layouts: [{ type: "bi.vertical" }, { type: o.align === BI.HorizontalAlign.Left ? "bi.left" : "bi.right" }] }, items: items }]; } BI.createWidget({ type: "bi.adaptive", element: container, items: items }); BI.createWidget({ type: "bi.center_adapt", scrollable: true, element: this, items: [container] }); } }); BI.BranchRelation.EVENT_CHANGE = "BranchRelation.EVENT_CHANGE"; BI.shortcut("bi.branch_relation", BI.BranchRelation);/** * 倒立的Branch * @class BI.HandStandBranchExpander * @extend BI.Widget * create by young */ BI.HandStandBranchExpander = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.HandStandBranchExpander.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-handstand-branch-expander", direction: BI.Direction.Top, logic: { dynamic: true }, el: {type: "bi.label"}, popup: {} }); }, _init: function () { BI.HandStandBranchExpander.superclass._init.apply(this, arguments); var o = this.options; this._initExpander(); this._initBranchView(); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { items: BI.LogicFactory.createLogicItemsByDirection(o.direction, { type: "bi.center_adapt", items: [this.expander] }, this.branchView) })))); }, _initExpander: function () { var self = this, o = this.options; this.expander = BI.createWidget(o.el); this.expander.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, _initBranchView: function () { var self = this, o = this.options; this.branchView = BI.createWidget(o.popup, {}); this.branchView.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, populate: function (items) { this.branchView.populate.apply(this.branchView, arguments); }, getValue: function () { return this.branchView.getValue(); } }); BI.HandStandBranchExpander.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.handstand_branch_expander", BI.HandStandBranchExpander);/** * @class BI.BranchExpander * @extend BI.Widget * create by young */ BI.BranchExpander = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.BranchExpander.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-branch-expander", direction: BI.Direction.Left, logic: { dynamic: true }, el: {}, popup: {} }); }, _init: function () { BI.BranchExpander.superclass._init.apply(this, arguments); var o = this.options; this._initExpander(); this._initBranchView(); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.expander, this.branchView) })))); }, _initExpander: function () { var self = this, o = this.options; this.expander = BI.createWidget(o.el, { type: "bi.label", width: 30, height: "100%" }); this.expander.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, _initBranchView: function () { var self = this, o = this.options; this.branchView = BI.createWidget(o.popup, {}); this.branchView.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, populate: function (items) { this.branchView.populate.apply(this.branchView, arguments); }, getValue: function () { return this.branchView.getValue(); } }); BI.BranchExpander.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.branch_expander", BI.BranchExpander);/** * @class BI.HandStandBranchTree * @extends BI.Widget * create by young * 横向分支的树 */ BI.HandStandBranchTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.HandStandBranchTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-handstand-branch-tree", expander: {}, el: {}, items: [] }); }, _init: function () { BI.HandStandBranchTree.superclass._init.apply(this, arguments); var self = this, o = this.options; this.branchTree = BI.createWidget({ type: "bi.custom_tree", element: this, expander: BI.extend({ type: "bi.handstand_branch_expander", el: {}, popup: { type: "bi.custom_tree" } }, o.expander), el: BI.extend({ type: "bi.button_tree", chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, layouts: [{ type: "bi.horizontal_adapt" }] }, o.el), items: this.options.items }); this.branchTree.on(BI.CustomTree.EVENT_CHANGE, function () { self.fireEvent(BI.HandStandBranchTree.EVENT_CHANGE, arguments); }); this.branchTree.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, populate: function () { this.branchTree.populate.apply(this.branchTree, arguments); }, getValue: function () { return this.branchTree.getValue(); } }); BI.HandStandBranchTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.handstand_branch_tree", BI.HandStandBranchTree);/** * @class BI.BranchTree * @extends BI.Widget * create by young * 横向分支的树 */ BI.BranchTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.BranchTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-branch-tree", expander: {}, el: {}, items: [] }); }, _init: function () { BI.BranchTree.superclass._init.apply(this, arguments); var self = this, o = this.options; this.branchTree = BI.createWidget({ type: "bi.custom_tree", element: this, expander: BI.extend({ type: "bi.branch_expander", el: {}, popup: { type: "bi.custom_tree" } }, o.expander), el: BI.extend({ type: "bi.button_tree", chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, layouts: [{ type: "bi.vertical" }] }, o.el), items: this.options.items }); this.branchTree.on(BI.CustomTree.EVENT_CHANGE, function () { self.fireEvent(BI.BranchTree.EVENT_CHANGE, arguments); }); this.branchTree.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, populate: function () { this.branchTree.populate.apply(this.branchTree, arguments); }, getValue: function () { return this.branchTree.getValue(); } }); BI.BranchTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.branch_tree", BI.BranchTree);/** * guy * 异步树 * @class BI.DisplayTree * @extends BI.TreeView */ BI.DisplayTree = BI.inherit(BI.TreeView, { _defaultConfig: function () { return BI.extend(BI.DisplayTree.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-display-tree" }); }, _init: function () { BI.DisplayTree.superclass._init.apply(this, arguments); }, // 配置属性 _configSetting: function () { var setting = { view: { selectedMulti: false, dblClickExpand: false, showIcon: false, showTitle: false }, data: { key: { title: "title", name: "text" }, simpleData: { enable: true } }, callback: { beforeCollapse: beforeCollapse } }; function beforeCollapse (treeId, treeNode) { return false; } return setting; }, _dealWidthNodes: function (nodes) { nodes = BI.DisplayTree.superclass._dealWidthNodes.apply(this, arguments); var self = this, o = this.options; BI.each(nodes, function (i, node) { if (node.text == null) { if (node.count > 0) { node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; } } }); return nodes; }, initTree: function (nodes, setting) { var setting = setting || this._configSetting(); this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); }, destroy: function () { BI.DisplayTree.superclass.destroy.apply(this, arguments); } }); BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** * guy * 二级树 * @class BI.LevelTree * @extends BI.Single */ BI.LevelTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.LevelTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-level-tree", el: { chooseType: 0 }, expander: {}, items: [] }); }, _init: function () { BI.LevelTree.superclass._init.apply(this, arguments); this.initTree(this.options.items); }, _formatItems: function (nodes, layer) { var self = this; BI.each(nodes, function (i, node) { var extend = {layer: layer}; if (!BI.isKey(node.id)) { node.id = BI.UUID(); } if (node.isParent === true || BI.isNotEmptyArray(node.children)) { switch (i) { case 0 : extend.type = "bi.first_plus_group_node"; break; case nodes.length - 1 : extend.type = "bi.last_plus_group_node"; break; default : extend.type = "bi.mid_plus_group_node"; break; } BI.defaults(node, extend); self._formatItems(node.children, layer + 1); } else { switch (i) { case nodes.length - 1: extend.type = "bi.last_tree_leaf_item"; break; default : extend.type = "bi.mid_tree_leaf_item"; } BI.defaults(node, extend); } }); return nodes; }, _assertId: function (sNodes) { BI.each(sNodes, function (i, node) { if (!BI.isKey(node.id)) { node.id = BI.UUID(); } }); }, // 构造树结构, initTree: function (nodes) { var self = this, o = this.options; this.empty(); this._assertId(nodes); this.tree = BI.createWidget({ type: "bi.custom_tree", element: this, expander: BI.extend({ el: {}, popup: { type: "bi.custom_tree" } }, o.expander), items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0), el: BI.extend({ type: "bi.button_tree", chooseType: 0, layouts: [{ type: "bi.vertical" }] }, o.el) }); this.tree.on(BI.Controller.EVENT_CHANGE, function (type, value, ob) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.LevelTree.EVENT_CHANGE, value, ob); } }); }, // 生成树方法 stroke: function (nodes) { this.tree.stroke.apply(this.tree, arguments); }, populate: function (items) { items = this._formatItems(BI.Tree.transformToTreeFormat(items), 0); this.tree.populate(items); }, setValue: function (v) { this.tree.setValue(v); }, getValue: function () { return this.tree.getValue(); }, getAllLeaves: function () { return this.tree.getAllLeaves(); }, getNodeById: function (id) { return this.tree.getNodeById(id); }, getNodeByValue: function (id) { return this.tree.getNodeByValue(id); } }); BI.LevelTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.level_tree", BI.LevelTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. * @class BI.SimpleTreeView * @extends BI.Widget */ BI.SimpleTreeView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SimpleTreeView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-simple-tree", itemsCreator: BI.emptyFn, items: null }); }, _init: function () { BI.SimpleTreeView.superclass._init.apply(this, arguments); var self = this, o = this.options; this.structure = new BI.Tree(); this.tree = BI.createWidget({ type: "bi.tree_view", element: this, itemsCreator: function (op, callback) { var fn = function (items) { callback({ items: items }); self.structure.initTree(BI.Tree.transformToTreeFormat(items)); }; if (BI.isNotNull(o.items)) { fn(o.items); } else { o.itemsCreator(op, fn); } } }); this.tree.on(BI.TreeView.EVENT_CHANGE, function () { self.fireEvent(BI.SimpleTreeView.EVENT_CHANGE, arguments); }); if (BI.isNotEmptyArray(o.items)) { this.populate(); } }, populate: function (items, keyword) { if (items) { this.options.items = items; } this.tree.stroke({ keyword: keyword }); }, setValue: function (v) { v || (v = []); var self = this, map = {}; var selected = []; BI.each(v, function (i, val) { var node = self.structure.search(val, "value"); if (node) { var p = node; p = p.getParent(); if (p) { if (!map[p.value]) { map[p.value] = 0; } map[p.value]++; } while (p && p.getChildrenLength() <= map[p.value]) { selected.push(p.value); p = p.getParent(); if (p) { if (!map[p.value]) { map[p.value] = 0; } map[p.value]++; } } } }); this.tree.setValue(BI.makeObject(v.concat(selected))); }, _getValue: function () { var self = this, result = [], val = this.tree.getValue(); var track = function (nodes) { BI.each(nodes, function (key, node) { if (BI.isEmpty(node)) { result.push(key); } else { track(node); } }); }; track(val); return result; }, empty: function () { this.tree.empty(); }, getValue: function () { var self = this, result = [], val = this._getValue(); BI.each(val, function (i, key) { var target = self.structure.search(key, "value"); if (target) { self.structure._traverse(target, function (node) { if (node.isLeaf()) { result.push(node.value); } }); } }); return result; } }); BI.SimpleTreeView.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.simple_tree", BI.SimpleTreeView); /** * 文本输入框trigger * * Created by GUY on 2015/9/15. * @class BI.EditorTrigger * @extends BI.Trigger */ BI.EditorTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4 }, _defaultConfig: function () { var conf = BI.EditorTrigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-editor-trigger bi-border", height: 24, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: false, watermark: "", errorText: "" }); }, _init: function () { this.options.height -= 2; BI.EditorTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.editor = BI.createWidget({ type: "bi.sign_editor", height: o.height, value: o.value, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.SignEditor.EVENT_CHANGE, function () { self.fireEvent(BI.EditorTrigger.EVENT_CHANGE, arguments); }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: this.editor }, { el: { type: "bi.trigger_icon_button", cls: "bi-border-left", width: o.triggerWidth || o.height }, width: o.triggerWidth || o.height } ] }); }, getValue: function () { return this.editor.getValue(); }, setValue: function (value) { this.editor.setValue(value); }, setText: function (text) { this.editor.setState(text); } }); BI.EditorTrigger.EVENT_CHANGE = "BI.EditorTrigger.EVENT_CHANGE"; BI.shortcut("bi.editor_trigger", BI.EditorTrigger);/** * 图标按钮trigger * * Created by GUY on 2015/10/8. * @class BI.IconTrigger * @extends BI.Trigger */ BI.IconTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend(BI.IconTrigger.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-icon-trigger", el: {}, height: 24 }); }, _init: function () { var o = this.options; BI.IconTrigger.superclass._init.apply(this, arguments); this.iconButton = BI.createWidget(o.el, { type: "bi.trigger_icon_button", element: this, width: o.width, height: o.height }); } }); BI.shortcut("bi.icon_trigger", BI.IconTrigger);/** * 文字trigger * * Created by GUY on 2015/9/15. * @class BI.IconTextTrigger * @extends BI.Trigger */ BI.IconTextTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4 }, _defaultConfig: function () { var conf = BI.IconTextTrigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-text-trigger", height: 24 }); }, _init: function () { BI.IconTextTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.text = BI.createWidget({ type: "bi.label", textAlign: "left", height: o.height, text: o.text, title: function () { return o.text; }, hgap: c.hgap }); this.trigerButton = BI.createWidget({ type: "bi.trigger_icon_button", cls: "bi-border-left", width: o.triggerWidth || o.height }); BI.createWidget({ element: this, type: "bi.htape", ref: function (_ref) { self.wrapper = _ref; }, items: [{ el: { type: "bi.icon_change_button", cls: "icon-combo-trigger-icon " + o.iconClass, ref: function (_ref) { self.icon = _ref; }, disableSelected: true }, width: o.triggerWidth || o.height }, { el: this.text }, { el: this.trigerButton, width: o.triggerWidth || o.height } ] }); }, setValue: function (value) { this.text.setValue(value); }, setIcon: function (iconCls) { var o = this.options; this.icon.setIcon(iconCls); var iconItem = this.wrapper.attr("items")[0]; if(BI.isNull(iconCls) || BI.isEmptyString(iconCls)) { if(iconItem.width !== 0) { iconItem.width = 0; this.wrapper.resize(); } }else{ if(iconItem.width !== (o.triggerWidth || o.height)) { iconItem.width = (o.triggerWidth || o.height); this.wrapper.resize(); } } }, setText: function (text) { this.text.setText(text); } }); BI.shortcut("bi.icon_text_trigger", BI.IconTextTrigger);/** * Created by Windy on 2017/12/12. */ BI.SelectIconTextTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend(BI.SelectIconTextTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-select-text-trigger bi-border", height: 24 }); }, _init: function () { this.options.height -= 2; BI.SelectIconTextTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options; var obj = this._digist(o.value, o.items); this.trigger = BI.createWidget({ type: "bi.icon_text_trigger", element: this, text: obj.text, iconClass: obj.iconClass, height: o.height }); }, _digist: function (vals, items) { var o = this.options; vals = BI.isArray(vals) ? vals : [vals]; var result; var formatItems = BI.Tree.transformToArrayFormat(items); BI.any(formatItems, function (i, item) { if (BI.deepContains(vals, item.value)) { result = { text: item.text || item.value, iconClass: item.iconClass }; return true; } }); if (BI.isNotNull(result)) { return { text: result.text, iconClass: result.iconClass }; } else { return { text: o.text, iconClass: "" }; } }, setValue: function (vals) { var obj = this._digist(vals, this.options.items); this.trigger.setText(obj.text); this.trigger.setIcon(obj.iconClass); }, populate: function (items) { this.options.items = items; } }); BI.shortcut("bi.select_icon_text_trigger", BI.SelectIconTextTrigger);/** * 文字trigger * * Created by GUY on 2015/9/15. * @class BI.TextTrigger * @extends BI.Trigger */ BI.TextTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4 }, _defaultConfig: function () { var conf = BI.TextTrigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-text-trigger", height: 24 }); }, _init: function () { BI.TextTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.text = BI.createWidget({ type: "bi.label", textAlign: "left", height: o.height, text: o.text, title: function () { return o.text; }, hgap: c.hgap, readonly: o.readonly }); this.trigerButton = BI.createWidget({ type: "bi.trigger_icon_button", cls: "bi-border-left", width: o.triggerWidth || o.height }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: this.text }, { el: this.trigerButton, width: o.triggerWidth || o.height } ] }); }, setText: function (text) { this.text.setText(text); } }); BI.shortcut("bi.text_trigger", BI.TextTrigger);/** * 选择字段trigger * * Created by GUY on 2015/9/15. * @class BI.SelectTextTrigger * @extends BI.Trigger */ BI.SelectTextTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend(BI.SelectTextTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-select-text-trigger bi-border", height: 24 }); }, _init: function () { this.options.height -= 2; BI.SelectTextTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.text_trigger", element: this, height: o.height, text: this._digest(o.text, o.items) }); }, _digest: function(vals, items){ var o = this.options; vals = BI.isArray(vals) ? vals : [vals]; var result = []; var formatItems = BI.Tree.transformToArrayFormat(items); BI.each(formatItems, function (i, item) { if (BI.deepContains(vals, item.value) && !result.contains(item.text || item.value)) { result.push(item.text || item.value); } }); if (result.length > 0) { return result.join(","); } else { return o.text; } }, setValue: function (vals) { this.trigger.setText(this._digest(vals, this.options.items)); }, populate: function (items) { this.options.items = items; } }); BI.shortcut("bi.select_text_trigger", BI.SelectTextTrigger);/** * 选择字段trigger小一号的 * * @class BI.SmallSelectTextTrigger * @extends BI.Trigger */ BI.SmallSelectTextTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend(BI.SmallSelectTextTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-small-select-text-trigger bi-border", height: 20 }); }, _init: function () { this.options.height -= 2; BI.SmallSelectTextTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options; var obj = this._digest(o.text, o.items); this.trigger = BI.createWidget({ type: "bi.small_text_trigger", element: this, height: o.height - 2, text: obj.text, cls: obj.cls }); }, _digest: function(vals, items){ var o = this.options; vals = BI.isArray(vals) ? vals : [vals]; var result = []; var formatItems = BI.Tree.transformToArrayFormat(items); BI.each(formatItems, function (i, item) { if (BI.deepContains(vals, item.value) && !result.contains(item.text || item.value)) { result.push(item.text || item.value); } }); if (result.length > 0) { return { cls: "", text: result.join(",") } } else { return { cls: "bi-water-mark", text: o.text } } }, setValue: function (vals) { this.trigger.setText(this._digest(vals, this.options.items)); }, populate: function (items) { this.options.items = items; } }); BI.shortcut("bi.small_select_text_trigger", BI.SmallSelectTextTrigger);/** * 文字trigger(右边小三角小一号的) == * * @class BI.SmallTextTrigger * @extends BI.Trigger */ BI.SmallTextTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4 }, _defaultConfig: function () { var conf = BI.SmallTextTrigger.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-text-trigger", height: 20 }); }, _init: function () { BI.SmallTextTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.text = BI.createWidget({ type: "bi.label", textAlign: "left", height: o.height, text: o.text, hgap: c.hgap }); this.trigerButton = BI.createWidget({ type: "bi.trigger_icon_button", width: o.triggerWidth || o.height }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: this.text }, { el: this.trigerButton, width: o.triggerWidth || o.height } ] }); }, setValue: function (value) { this.text.setValue(value); }, setText: function (text) { this.text.setText(text); } }); BI.shortcut("bi.small_text_trigger", BI.SmallTextTrigger);/** * * Created by GUY on 2016/5/26. * @class BI.SequenceTableTreeNumber * @extends BI.Widget */ BI.SequenceTableTreeNumber = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SequenceTableTreeNumber.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-sequence-table-tree-number", isNeedFreeze: false, startSequence: 1, // 开始的序号 scrollTop: 0, headerRowSize: 25, rowSize: 25, sequenceHeaderCreator: null, header: [], items: [], // 二维数组 // 交叉表头 crossHeader: [], crossItems: [] }); }, _init: function () { BI.SequenceTableTreeNumber.superclass._init.apply(this, arguments); var self = this, o = this.options; this.vCurr = 1; this.hCurr = 1; this.tasks = []; this.renderedCells = []; this.renderedKeys = []; this.container = BI.createWidget({ type: "bi.absolute", width: 60, scrollable: false }); this.scrollContainer = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.container] }); this.headerContainer = BI.createWidget({ type: "bi.absolute", cls: "bi-border", width: 58, scrollable: false }); this.layout = BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.headerContainer, height: this._getHeaderHeight() - 2 }, {el: {type: "bi.layout"}, height: 2}, { el: this.scrollContainer }] }); // 缓存第一行对应的序号 this.start = this.options.startSequence; this.cache = {}; this._nextState(); this._populate(); }, _getNextSequence: function (nodes) { var self = this; var start = this.start; var cnt = this.start; function track (node) { // 如果已经有缓存了就不改计数了,复杂表会出现这种情况 self.cache[node.text || node.value] || (self.cache[node.text || node.value] = cnt); cnt++; } BI.each(nodes, function (i, node) { if (BI.isNotEmptyArray(node.children)) { BI.each(node.children, function (index, child) { if (index === 0) { if (self.cache[child.text || child.value]) { start = cnt = self.cache[child.text || child.value]; } } track(child); }); } }); this.start = cnt; return start; }, _getStart: function (nodes) { var self = this; var start = this.start; BI.some(nodes, function (i, node) { if (BI.isNotEmptyArray(node.children)) { return BI.some(node.children, function (index, child) { if (index === 0) { if (self.cache[child.text || child.value]) { start = self.cache[child.text || child.value]; return true; } } }); } }); return start; }, _formatNumber: function (nodes) { var self = this, o = this.options; var result = []; var count = this._getStart(nodes); function getLeafCount (node) { var cnt = 0; if (BI.isNotEmptyArray(node.children)) { BI.each(node.children, function (index, child) { cnt += getLeafCount(child); }); if (/** node.children.length > 1 && **/BI.isNotEmptyArray(node.values)) { cnt++; } } else { cnt++; } return cnt; } var start = 0, top = 0; BI.each(nodes, function (i, node) { if (BI.isArray(node.children)) { BI.each(node.children, function (index, child) { var cnt = getLeafCount(child); result.push({ text: count++, start: start, top: top, cnt: cnt, index: index, height: cnt * o.rowSize }); start += cnt; top += cnt * o.rowSize; }); if (BI.isNotEmptyArray(node.values)) { result.push({ text: BI.i18nText("BI-Summary_Values"), start: start++, top: top, cnt: 1, isSummary: true, height: o.rowSize }); top += o.rowSize; } } }); return result; }, _layout: function () { var self = this, o = this.options; var headerHeight = this._getHeaderHeight() - 2; var items = this.layout.attr("items"); if (o.isNeedFreeze === false) { items[0].height = 0; items[1].height = 0; } else if (o.isNeedFreeze === true) { items[0].height = headerHeight; items[1].height = 2; } this.layout.attr("items", items); this.layout.resize(); try { this.scrollContainer.element.scrollTop(o.scrollTop); } catch (e) { } }, _getHeaderHeight: function () { var o = this.options; return o.headerRowSize * (o.crossHeader.length + (o.header.length > 0 ? 1 : 0)); }, _nextState: function () { var o = this.options; this._getNextSequence(o.items); }, _prevState: function () { var self = this, o = this.options; var firstChild; BI.some(o.items, function (i, node) { if (BI.isNotEmptyArray(node.children)) { return BI.some(node.children, function (j, child) { firstChild = child; return true; }); } }); if (firstChild && BI.isNotEmptyObject(this.cache)) { this.start = this.cache[firstChild.text || firstChild.value]; } else { this.start = 1; } this._nextState(); }, _getMaxScrollTop: function (numbers) { var cnt = 0; BI.each(numbers, function (i, number) { cnt += number.cnt; }); return Math.max(0, cnt * this.options.rowSize - (this.options.height - this._getHeaderHeight()) + BI.DOM.getScrollWidth()); }, _createHeader: function () { var o = this.options; BI.createWidget({ type: "bi.absolute", element: this.headerContainer, items: [{ el: o.sequenceHeaderCreator || { type: "bi.table_style_cell", cls: "sequence-table-title-cell", styleGetter: o.headerCellStyleGetter, text: BI.i18nText("BI-Number_Index") }, left: 0, top: 0, right: 0, bottom: 0 }] }); }, _calculateChildrenToRender: function () { var self = this, o = this.options; var renderedCells = [], renderedKeys = []; var numbers = this._formatNumber(o.items); var intervalTree = BI.PrefixIntervalTree.uniform(numbers.length, 0); BI.each(numbers, function (i, number) { intervalTree.set(i, number.height); }); var scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop(numbers)); var index = intervalTree.greatestLowerBound(scrollTop); var offsetTop = -(scrollTop - (index > 0 ? intervalTree.sumTo(index - 1) : 0)); var height = offsetTop; var bodyHeight = o.height - this._getHeaderHeight(); while (height < bodyHeight && index < numbers.length) { renderedKeys.push(index); offsetTop += numbers[index].height; height += numbers[index].height; index++; } BI.each(renderedKeys, function (i, key) { var index = BI.deepIndexOf(self.renderedKeys, key); if (index > -1) { if (numbers[key].height !== self.renderedCells[index]._height) { self.renderedCells[index]._height = numbers[key].height; self.renderedCells[index].el.setHeight(numbers[key].height); } if (numbers[key].top !== self.renderedCells[index].top) { self.renderedCells[index].top = numbers[key].top; self.renderedCells[index].el.element.css("top", numbers[key].top + "px"); } renderedCells.push(self.renderedCells[index]); } else { var child = BI.createWidget(BI.extend({ type: "bi.table_style_cell", cls: "sequence-table-number-cell bi-border-left bi-border-right bi-border-bottom", width: 60, styleGetter: numbers[key].isSummary === true ? function () { return o.summaryCellStyleGetter(true); } : function (key) { return function () { return o.sequenceCellStyleGetter(key); }; }(numbers[key].index) }, numbers[key])); renderedCells.push({ el: child, left: 0, top: numbers[key].top, _height: numbers[key].height }); } }); // 已存在的, 需要添加的和需要删除的 var existSet = {}, addSet = {}, deleteArray = []; BI.each(renderedKeys, function (i, key) { if (BI.deepContains(self.renderedKeys, key)) { existSet[i] = key; } else { addSet[i] = key; } }); BI.each(this.renderedKeys, function (i, key) { if (BI.deepContains(existSet, key)) { return; } if (BI.deepContains(addSet, key)) { return; } deleteArray.push(i); }); BI.each(deleteArray, function (i, index) { self.renderedCells[index].el.destroy(); }); var addedItems = []; BI.each(addSet, function (index) { addedItems.push(renderedCells[index]); }); BI.createWidget({ type: "bi.absolute", element: this.container, items: addedItems }); this.renderedCells = renderedCells; this.renderedKeys = renderedKeys; this.container.setHeight(intervalTree.sumUntil(numbers.length)); }, _restore: function () { BI.each(this.renderedCells, function (i, cell) { cell.el.destroy(); }); this.renderedCells = []; this.renderedKeys = []; }, _populate: function () { var self = this; BI.each(this.tasks, function (i, task) { task.apply(self); }); this.tasks = []; this.headerContainer.empty(); this._createHeader(); this._layout(); this._calculateChildrenToRender(); }, setVerticalScroll: function (scrollTop) { if (this.options.scrollTop !== scrollTop) { this.options.scrollTop = scrollTop; try { this.scrollContainer.element.scrollTop(scrollTop); } catch (e) { } } }, getVerticalScroll: function () { return this.options.scrollTop; }, setVPage: function (v) { if (v <= 1) { this.cache = {}; this.start = this.options.startSequence; this._restore(); this.tasks.push(this._nextState); } else if (v === this.vCurr + 1) { this.tasks.push(this._nextState); } else if (v === this.vCurr - 1) { this.tasks.push(this._prevState); } this.vCurr = v; }, setHPage: function (v) { if (v !== this.hCurr) { this.tasks.push(this._prevState); } this.hCurr = v; }, restore: function () { this._restore(); }, populate: function (items, header, crossItems, crossHeader) { var o = this.options; if (items && items !== this.options.items) { o.items = items; this._restore(); this.tasks.push(this._prevState); } if (header && header !== this.options.header) { o.header = header; } if (crossItems && crossItems !== this.options.crossItems) { o.crossItems = crossItems; } if (crossHeader && crossHeader !== this.options.crossHeader) { o.crossHeader = crossHeader; } this._populate(); } }); BI.shortcut("bi.sequence_table_tree_number", BI.SequenceTableTreeNumber);/** * 自适应布局 * * 1、resize * 2、吸附 * 3、当前组件在最上方 * 4、可以撤销 * 5、上下之间插入组件 * * Created by GUY on 2016/2/23. * @class BI.AdaptiveArrangement * @extends BI.Widget */ BI.AdaptiveArrangement = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.AdaptiveArrangement.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-adaptive-arrangement", resizable: true, layoutType: BI.Arrangement.LAYOUT_TYPE.FREE, items: [] }); }, _init: function () { BI.AdaptiveArrangement.superclass._init.apply(this, arguments); var self = this, o = this.options; this.arrangement = BI.createWidget({ type: "bi.arrangement", element: this, layoutType: o.layoutType, items: o.items }); this.arrangement.on(BI.Arrangement.EVENT_SCROLL, function () { self.fireEvent(BI.AdaptiveArrangement.EVENT_SCROLL, arguments); }); this.zIndex = 0; BI.each(o.items, function (i, item) { self._initResizable(item.el); }); $(document).mousedown(function (e) { BI.each(self.getAllRegions(), function (i, region) { if (region.el.element.find(e.target).length === 0) { region.el.element.removeClass("selected"); } }); }); BI.ResizeDetector.addResizeListener(this, function () { self.arrangement.resize(); self.fireEvent(BI.AdaptiveArrangement.EVENT_RESIZE); }); }, _isEqual: function () { return this.arrangement._isEqual.apply(this.arrangement, arguments); }, _setSelect: function (item) { if (!item.element.hasClass("selected")) { item.element.css("zIndex", ++this.zIndex); BI.each(this.getAllRegions(), function (i, region) { region.el.element.removeClass("selected"); }); item.element.addClass("selected"); } }, _initResizable: function (item) { var self = this, o = this.options; item.element.css("zIndex", ++this.zIndex); item.element.mousedown(function () { self._setSelect(item); }); }, _getScrollOffset: function () { return this.arrangement._getScrollOffset(); }, getClientWidth: function () { return this.arrangement.getClientWidth(); }, getClientHeight: function () { return this.arrangement.getClientHeight(); }, addRegion: function (region, position) { this._initResizable(region.el); this._setSelect(region.el); var self = this, flag; var old = this.arrangement.getAllRegions(); if (flag = this.arrangement.addRegion(region, position)) { this._old = old; } return flag; }, deleteRegion: function (name) { var flag; var old = this.getAllRegions(); if (flag = this.arrangement.deleteRegion(name)) { this._old = old; } else { this._old = this.getAllRegions(); this.relayout(); } return flag; }, setRegionSize: function (name, size) { var flag; var old = this.getAllRegions(); if (flag = this.arrangement.setRegionSize(name, size)) { this._old = old; } return flag; }, setPosition: function (position, size) { var self = this; return this.arrangement.setPosition(position, size); }, setRegionPosition: function (name, position) { var region = this.getRegionByName(name); return this.arrangement.setRegionPosition(name, position); }, setDropPosition: function (position, size) { return this.arrangement.setDropPosition(position, size); }, scrollInterval: function (e, isBorderScroll, isOverflowScroll, cb) { // var self = this; // var map = { // top: [-1, 0], // bottom: [1, 0], // left: [0, -1], // right: [0, 1] // }; // var clientWidth = this.arrangement.getClientWidth(); // var clientHeight = this.arrangement.getClientHeight(); // // function scrollTo(direction, callback) { // if (direction === "") { // self.lastActiveRegion = ""; // if (self._scrollInterval) { // clearInterval(self._scrollInterval); // self._scrollInterval = null; // } // return; // } // if (self.lastActiveRegion !== direction) { // self.lastActiveRegion = direction; // if (self._scrollInterval) { // clearInterval(self._scrollInterval); // self._scrollInterval = null; // } // var count = 0; // self._scrollInterval = setInterval(function () { // count++; // if (count <= 3) { // return; // } // var offset = self._getScrollOffset(); // var t = offset.top + map[direction][0] * 40; // var l = offset.left + map[direction][1] * 40; // if (t < 0 || l < 0) { // return; // } // callback({ // offsetX: map[direction][1] * 40, // offsetY: map[direction][0] * 40 // }); // self.scrollTo({ // top: t, // left: l // }); // }, 300); // } // } cb({ offsetX: 0, offsetY: 0 }); // var offset = this.element.offset(); // var p = { // left: e.pageX - offset.left, // top: e.pageY - offset.top // }; // //向上滚 // if (isBorderScroll && p.top >= 0 && p.top <= 30) { // scrollTo("top", cb) // } // //向下滚 // else if (isBorderScroll && p.top >= clientHeight - 30 && p.top <= clientHeight) { // scrollTo("bottom", cb) // } // //向左滚 // else if (isBorderScroll && p.left >= 0 && p.left <= 30) { // scrollTo("left", cb) // } // //向右滚 // else if (isBorderScroll && p.left >= clientWidth - 30 && p.left <= clientWidth) { // scrollTo("right", cb) // } else { // if (isOverflowScroll === true) { // if (p.top < 0) { // scrollTo("top", cb); // } // else if (p.top > clientHeight) { // scrollTo("bottom", cb); // } // else if (p.left < 0) { // scrollTo("left", cb); // } // else if (p.left > clientWidth) { // scrollTo("right", cb); // } else { // scrollTo("", cb); // } // } else { // scrollTo("", cb); // } // } }, scrollEnd: function () { this.lastActiveRegion = ""; if (this._scrollInterval) { clearInterval(this._scrollInterval); this._scrollInterval = null; } }, scrollTo: function (scroll) { this.arrangement.scrollTo(scroll); }, zoom: function (ratio) { this.arrangement.zoom(ratio); }, resize: function () { this.arrangement.resize(); }, relayout: function () { return this.arrangement.relayout(); }, setLayoutType: function (type) { var self = this; this.arrangement.setLayoutType(type); }, getLayoutType: function () { return this.arrangement.getLayoutType(); }, getLayoutRatio: function () { return this.arrangement.getLayoutRatio(); }, getHelper: function () { return this.arrangement.getHelper(); }, getRegionByName: function (name) { return this.arrangement.getRegionByName(name); }, getAllRegions: function () { return this.arrangement.getAllRegions(); }, revoke: function () { if (this._old) { this.populate(BI.toArray(this._old)); } }, populate: function (items) { var self = this; BI.each(items, function (i, item) { self._initResizable(item.el); }); this.arrangement.populate(items); } }); BI.AdaptiveArrangement.EVENT_ELEMENT_START_RESIZE = "AdaptiveArrangement.EVENT_ELEMENT_START_RESIZE"; BI.AdaptiveArrangement.EVENT_ELEMENT_RESIZE = "AdaptiveArrangement.EVENT_ELEMENT_RESIZE"; BI.AdaptiveArrangement.EVENT_ELEMENT_STOP_RESIZE = "AdaptiveArrangement.EVENT_ELEMENT_STOP_RESIZE"; BI.AdaptiveArrangement.EVENT_RESIZE = "AdaptiveArrangement.EVENT_RESIZE"; BI.AdaptiveArrangement.EVENT_SCROLL = "AdaptiveArrangement.EVENT_SCROLL"; BI.shortcut("bi.adaptive_arrangement", BI.AdaptiveArrangement);/** * Arrangement的block面板 * * Created by GUY on 2016/3/1. * @class BI.ArrangementBlock * @extends BI.Widget */ BI.ArrangementBlock = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ArrangementBlock.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-arrangement-block bi-mask" }); } }); BI.shortcut("bi.arrangement_block", BI.ArrangementBlock);/** * Arrangement的drop面板 * * Created by GUY on 2016/3/1. * @class BI.ArrangementDroppable * @extends BI.Widget */ BI.ArrangementDroppable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.ArrangementDroppable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-arrangement-droppable bi-resizer" }); } }); BI.shortcut("bi.arrangement_droppable", BI.ArrangementDroppable);/** * 布局 * * Created by GUY on 2016/2/23. * @class BI.Arrangement * @extends BI.Widget */ BI.Arrangement = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.Arrangement.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-arrangement", layoutType: BI.Arrangement.LAYOUT_TYPE.GRID, items: [] }); }, _init: function () { BI.Arrangement.superclass._init.apply(this, arguments); var self = this, o = this.options; this.arrangement = BI.createWidget({ type: "bi.arrangement_droppable", cls: "arrangement-block", invisible: true }); this.block = BI.createWidget({ type: "bi.arrangement_block", invisible: true }); this.container = BI.createWidget({ type: "bi.absolute", scrollable: true, cls: "arrangement-container", items: o.items.concat([this.block, this.arrangement]) }); this.container.element.scroll(function () { self.fireEvent(BI.Arrangement.EVENT_SCROLL, { scrollLeft: self.container.element.scrollLeft(), scrollTop: self.container.element.scrollTop(), clientWidth: self.container.element[0].clientWidth, clientHeight: self.container.element[0].clientHeight }); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.container, left: 0, right: 0, top: 0, bottom: 0 }] }); this.regions = {}; if (o.items.length > 0) { BI.nextTick(function () { self.populate(o.items); }); } }, // //初始化操作//// _calculateRegions: function (items) { var self = this, o = this.options; this.regions = {}; BI.each(items, function (i, item) { var region = self._createOneRegion(item); self.regions[region.id] = region; }); }, _isEqual: function (num1, num2) { return Math.abs(num1 - num2) < 2; }, _isLessThan: function (num1, num2) { return num1 < num2 && !this._isEqual(num1, num2); }, _isMoreThan: function (num1, num2) { return num1 > num2 && !this._isEqual(num1, num2); }, _isLessThanEqual: function (num1, num2) { return num1 <= num2 || this._isEqual(num1, num2); }, _isMoreThanEqual: function (num1, num2) { return num1 >= num2 || this._isEqual(num1, num2); }, // 获取占有的最大Region _getRegionOccupied: function (regions) { var self = this, o = this.options; if (BI.size(regions || this.regions) <= 0) { return { left: 0, top: 0, width: 0, height: 0 }; } var minLeft = BI.MAX, maxLeft = BI.MIN, minTop = BI.MAX, maxTop = BI.MIN; BI.each(regions || this.regions, function (id, region) { minLeft = Math.min(minLeft, region.left); maxLeft = Math.max(maxLeft, region.left + region.width); minTop = Math.min(minTop, region.top); maxTop = Math.max(maxTop, region.top + region.height); }); return { left: minLeft, top: minTop, width: maxLeft - minLeft, height: maxTop - minTop }; }, // 两个区域的交叉面积 _getCrossArea: function (region1, region2) { if (region1.left <= region2.left) { if (region1.top <= region2.top) { if (region1.top + region1.height > region2.top && region1.left + region1.width > region2.left) { if (this._isEqual(region1.top + region1.height, region2.top) || this._isEqual(region1.left + region1.width, region2.left)) { return 0; } return (region1.top + region1.height - region2.top) * (region1.left + region1.width - region2.left); } } else { if (region2.top + region2.height > region1.top && region1.left + region1.width > region2.left) { if (this._isEqual(region2.top + region2.height, region1.top) || this._isEqual(region1.left + region1.width, region2.left)) { return 0; } return (region2.top + region2.height - region1.top) * (region1.left + region1.width - region2.left); } } } else { if (region1.top <= region2.top) { if (region1.top + region1.height > region2.top && region2.left + region2.width > region1.left) { if (this._isEqual(region1.top + region1.height, region2.top) || this._isEqual(region2.left + region2.width, region1.left)) { return 0; } return (region1.top + region1.height - region2.top) * (region2.left + region2.width - region1.left); } } else { if (region2.top + region2.height > region1.top && region2.left + region2.width > region1.left) { if (this._isEqual(region2.top + region2.height, region1.top) || this._isEqual(region2.left + region2.width, region1.left)) { return 0; } return (region2.top + region2.height - region1.top) * (region2.left + region2.width - region1.left); } } } return 0; }, // 是否有覆盖的组件 _isRegionOverlay: function (regions) { var reg = []; BI.each(regions || this.regions, function (id, region) { reg.push(new BI.Region(region.left, region.top, region.width, region.height)); }); for (var i = 0, len = reg.length; i < len; i++) { for (var j = i + 1; j < len; j++) { var area1 = { left: reg[i].x, top: reg[i].y, width: reg[i].w, height: reg[i].h }; var area2 = { left: reg[j].x, top: reg[j].y, width: reg[j].w, height: reg[j].h }; if (reg[i].isIntersects(reg[j]) && this._getCrossArea(area1, area2) > 1) { return true; } } } return false; }, // 布局是否是优良的 _isArrangeFine: function (regions) { switch (this.options.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: return true; case BI.Arrangement.LAYOUT_TYPE.GRID: // if (this._isRegionOverlay()) { // return false; // } } return true; }, _getRegionNames: function (regions) { var names = []; BI.each(regions || this.regions, function (i, region) { names.push(region.id || region.attr("id")); }); return names; }, _getRegionsByNames: function (names, regions) { names = BI.isArray(names) ? names : [names]; regions = regions || this.regions; if (BI.isArray(regions)) { var result = []; BI.each(regions, function (i, region) { if (names.contains(region.id || region.attr("id"))) { result.push(region); } }); } else { var result = {}; BI.each(names, function (i, name) { result[name] = regions[name]; }); } return result; }, _cloneRegion: function (regions) { var clone = {}; BI.each(regions || this.regions, function (id, region) { clone[id] = {}; clone[id].el = region.el; clone[id].id = region.id; clone[id].left = region.left; clone[id].top = region.top; clone[id].width = region.width; clone[id].height = region.height; }); return clone; }, // 测试合法性 _test: function (regions) { var self = this; return !BI.any(regions || this.regions, function (i, region) { if (BI.isNaN(region.width) || BI.isNaN(region.height) || region.width <= 21 || region.height <= 21) { return true; } }); }, _getScrollOffset: function () { return { left: this.container.element[0].scrollLeft, top: this.container.element[0].scrollTop }; }, // //操作//// _createOneRegion: function (item) { var el = BI.createWidget(item.el); el.setVisible(true); return { id: el.attr("id"), left: item.left, top: item.top, width: item.width, height: item.height, el: el }; }, _applyRegion: function (regions) { var self = this, o = this.options; BI.each(regions || this.regions, function (i, region) { region.el.element.css({ left: region.left, top: region.top, width: region.width, height: region.height }); }); this._applyContainer(); this.ratio = this.getLayoutRatio(); }, _renderRegion: function () { var items = BI.toArray(this.regions); BI.each(items, function (i, item) { if (BI.isNotNull(item.el)) { item.el.options.key = item.id; } else { item.key = item.id; } }); if (BI.isNull(this.wrapper)) { this.wrapper = BI.createWidget({ type: "bi.absolute", element: this.container }); } this.wrapper.addItems(items); }, getClientWidth: function () { return this.container.element[0].clientWidth; }, getClientHeight: function () { return this.container.element[0].clientHeight; }, _applyContainer: function () { var occupied = this._getRegionOccupied(); return occupied; }, _modifyRegion: function (regions) { BI.each(this.regions, function (id, region) { if (regions[id]) { region.left = regions[id].left; region.top = regions[id].top; region.width = regions[id].width; region.height = regions[id].height; } }); }, _addRegion: function (item) { var region = this._createOneRegion(item); this.regions[region.id] = region; BI.createWidget({ type: "bi.absolute", element: this.container, items: [region] }); }, _deleteRegionByName: function (name) { this.regions[name].el.setVisible(false); delete this.regions[name]; }, _setArrangeSize: function (size) { this.arrangement.element.css({ left: size.left, top: size.top, width: size.width, height: size.height }); }, // Grid _getOneWidthPortion: function () { return this.getClientWidth() / BI.Arrangement.PORTION; }, _getOneHeightPortion: function () { return this.getClientHeight() / BI.Arrangement.H_PORTION; }, _getGridPositionAndSize: function (position) { var perWidth = this._getOneWidthPortion(); var perHeight = this._getOneHeightPortion(); var widthPortion = Math.round(position.width / perWidth); var leftPortion = Math.round(position.left / perWidth); var topPortion = Math.round(position.top / perHeight); var heightPortion = Math.round(position.height / perHeight); // if (leftPortion > BI.Arrangement.PORTION) { // leftPortion = BI.Arrangement.PORTION; // } // if (widthPortion > BI.Arrangement.PORTION) { // widthPortion = BI.Arrangement.PORTION; // } // if (leftPortion + widthPortion > BI.Arrangement.PORTION) { // leftPortion = BI.Arrangement.PORTION - widthPortion; // } if (widthPortion === 0) { widthPortion = 1; } if (heightPortion === 0) { heightPortion = 1; } return { x: leftPortion, y: topPortion, w: widthPortion, h: heightPortion }; }, _getBlockPositionAndSize: function (position) { var perWidth = this._getOneWidthPortion(); var perHeight = this._getOneHeightPortion(); return { left: position.x * perWidth, top: position.y * perHeight, width: position.w * perWidth, height: position.h * perHeight }; }, _getLayoutsByRegions: function (regions) { var self = this; var result = []; BI.each(regions || this.regions, function (id, region) { result.push(BI.extend(self._getGridPositionAndSize(region), { i: region.id })); }); return result; }, _getLayoutIndexByName: function (layout, name) { return BI.findIndex(layout, function (i, l) { return l.i === name; }); }, _setBlockPositionAndSize: function (size) { this.block.element.css({ left: size.left, top: size.top, width: size.width, height: size.height }); }, _getRegionsByLayout: function (layout) { var self = this; var regions = {}; BI.each(layout, function (i, ly) { regions[ly.i] = BI.extend(self._getBlockPositionAndSize(ly), { id: ly.i }); }); return regions; }, _setRegionsByLayout: function (regions, layout) { var self = this; regions || (regions = this.regions); BI.each(layout, function (i, ly) { if (regions[ly.i]) { BI.extend(regions[ly.i], self._getBlockPositionAndSize(ly)); } }); return regions; }, _moveElement: function (layout, l, x, y, isUserAction) { var self = this; if (l._static) { return layout; } if (l.y === y && l.x === x) { return layout; } var movingUp = y && l.y > y; if (typeof x === "number") { l.x = x; } if (typeof y === "number") { l.y = y; } l.moved = true; var sorted = this._sortLayoutItemsByRowCol(layout); if (movingUp) { sorted = sorted.reverse(); } var collisions = getAllCollisions(sorted, l); for (var i = 0, len = collisions.length; i < len; i++) { var collision = collisions[i]; if (collision.moved) { continue; } if (l.y > collision.y && l.y - collision.y > collision.h / 4) { continue; } if (collision._static) { layout = this._moveElementAwayFromCollision(layout, collision, l, isUserAction); } else { layout = this._moveElementAwayFromCollision(layout, l, collision, isUserAction); } } return layout; function getAllCollisions (layout, layoutItem) { return BI.filter(layout, function (i, l) { return self._collides(l, layoutItem); }); } }, _sortLayoutItemsByRowCol: function (layout) { return [].concat(layout).sort(function (a, b) { if (a.y > b.y || (a.y === b.y && a.x > b.x)) { return 1; } return -1; }); }, _collides: function (l1, l2) { if (l1 === l2) { return false; } // same element if (l1.x + l1.w <= l2.x) { return false; } // l1 is left of l2 if (l1.x >= l2.x + l2.w) { return false; } // l1 is right of l2 if (l1.y + l1.h <= l2.y) { return false; } // l1 is above l2 if (l1.y >= l2.y + l2.h) { return false; } // l1 is below l2 return true; // boxes overlap }, _getFirstCollision: function (layout, layoutItem) { for (var i = 0, len = layout.length; i < len; i++) { if (this._collides(layout[i], layoutItem)) { return layout[i]; } } }, _moveElementAwayFromCollision: function (layout, collidesWith, itemToMove, isUserAction) { if (isUserAction) { var fakeItem = { x: itemToMove.x, y: itemToMove.y, w: itemToMove.w, h: itemToMove.h, i: "-1" }; fakeItem.y = Math.max(collidesWith.y - itemToMove.h, 0); if (!this._getFirstCollision(layout, fakeItem)) { return this._moveElement(layout, itemToMove, undefined, fakeItem.y); } } return this._moveElement(layout, itemToMove, undefined, itemToMove.y + 1); }, _compactItem: function (compareWith, l, verticalCompact) { if (verticalCompact) { while (l.y > 0 && !this._getFirstCollision(compareWith, l)) { l.y--; } } var collides; while ((collides = this._getFirstCollision(compareWith, l))) { l.y = collides.y + collides.h; } return l; }, compact: function (layout, verticalCompact) { var compareWith = getStatics(layout); var sorted = this._sortLayoutItemsByRowCol(layout); var out = []; for (var i = 0, len = sorted.length; i < len; i++) { var l = sorted[i]; if (!l._static) { l = this._compactItem(compareWith, l, verticalCompact); compareWith.push(l); } out[layout.indexOf(l)] = l; l.moved = false; } return out; function getStatics (layout) { return BI.filter(layout, function (i, l) { return l._static; }); } }, // //公有方法//// getRegionByName: function (name) { var obj = {}; obj[name] = this.regions[name]; return this._cloneRegion(obj)[name]; }, getAllRegions: function () { return BI.toArray(this._cloneRegion()); }, getHelper: function () { var helper = BI.createWidget({ type: "bi.layout", width: 18, height: 18, cls: "arrangement-helper bi-border" }); BI.createWidget({ type: "bi.absolute", element: this, items: [helper] }); return helper; }, _start: function () { if (this.options.layoutType === BI.Arrangement.LAYOUT_TYPE.GRID) { this.block.setVisible(true); } else { this.arrangement.setVisible(true); } }, _stop: function () { this.arrangement.setVisible(false); this.block.setVisible(false); }, // //公有操作//// setLayoutType: function (type) { var self = this, o = this.options; if (type !== o.layoutType) { o.layoutType = type; switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: break; case BI.Arrangement.LAYOUT_TYPE.GRID: this.relayout(); break; } } }, getLayoutType: function () { return this.options.layoutType; }, getLayoutRatio: function () { var occupied = this._getRegionOccupied(); var width = this.getClientWidth(), height = this.getClientHeight(); return { x: BI.parseFloat(BI.contentFormat((occupied.left + occupied.width) / width, "#.##;-#.##")), y: BI.parseFloat(BI.contentFormat((occupied.top + occupied.height) / height, "#.##;-#.##")) }; }, addRegion: function (region, position) { if (position) { this.setPosition(position, region); } var self = this, o = this.options; if (!this.position) { return false; } var test = this._cloneRegion(); BI.each(this.position.regions, function (i, region) { test[region.id].left = region.left; test[region.id].top = region.top; test[region.id].width = region.width; test[region.id].height = region.height; }); var item = BI.extend({}, region, { left: this.position.insert.left, top: this.position.insert.top, width: this.position.insert.width, height: this.position.insert.height }); var added = this._createOneRegion(item); test[added.id] = added; if (this._test(test)) { delete test[added.id]; this._modifyRegion(test); this._addRegion(item); this._populate(this.getAllRegions()); return true; } return false; }, deleteRegion: function (name) { if (!this.regions[name]) { return false; } var self = this, o = this.options; switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: this._deleteRegionByName(name); this._populate(this.getAllRegions()); return true; case BI.Arrangement.LAYOUT_TYPE.GRID: this._deleteRegionByName(name); this._populate(this.getAllRegions()); this.resize(); return true; } return false; }, setRegionSize: function (name, size) { var self = this, o = this.options; var flag = false; switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: var clone = this._cloneRegion(); BI.extend(clone[name], { width: size.width, height: size.height }); if (this._test(clone)) { this._modifyRegion(clone); flag = true; } break; case BI.Arrangement.LAYOUT_TYPE.GRID: var clone = this._cloneRegion(); BI.extend(clone[name], { width: size.width, height: size.height }); if (this._test(clone)) { var layout = this._getLayoutsByRegions(clone); layout = this.compact(layout, true); var regions = this._getRegionsByLayout(layout); this._modifyRegion(regions); flag = true; } break; } this._applyRegion(); return flag; }, setPosition: function (position, size) { var self = this, o = this.options; var insert, regions = [], cur; if (position.left < 0 || position.top < 0) { switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: break; case BI.Arrangement.LAYOUT_TYPE.GRID: this.resize(); break; } this._stop(); this.position = null; return null; } var offset = this._getScrollOffset(); position = { left: position.left + offset.left, top: position.top + offset.top }; switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: var insert = { top: position.top < 0 ? 0 : position.top, left: position.left < 0 ? 0 : position.left, width: size.width, height: size.height }; this.position = { insert: insert }; this._setArrangeSize(insert); this._start(); break; case BI.Arrangement.LAYOUT_TYPE.GRID: var p = { top: position.top < 0 ? 0 : position.top, left: position.left < 0 ? 0 : position.left, width: size.width, height: size.height }; this._setArrangeSize(p); var cur = this._getGridPositionAndSize(p); var layout = [{ x: 0, y: BI.MAX, w: cur.w, h: cur.h, i: cur.i }].concat(this._getLayoutsByRegions()); layout = this._moveElement(layout, layout[0], cur.x, cur.y, true); layout = this.compact(layout, true); var regions = this._setRegionsByLayout(this._cloneRegion(), layout); var insert = this._getBlockPositionAndSize(layout[0]); this.position = { insert: insert, regions: regions }; this._applyRegion(regions); this._setBlockPositionAndSize(insert); this._start(); break; } return this.position; }, setRegionPosition: function (name, position) { var self = this, o = this.options; var offset = this._getScrollOffset(); position = BI.extend(position, { left: position.left + offset.left, top: position.top + offset.top }); switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: BI.extend(this.regions[name], { left: position.left < 0 ? 0 : position.left, top: position.top < 0 ? 0 : position.top }); this._applyRegion(); break; case BI.Arrangement.LAYOUT_TYPE.GRID: if (!position.stop) { BI.extend(this.regions[name], { left: position.left < 0 ? 0 : position.left, top: position.top < 0 ? 0 : position.top }); var cloned = this._cloneRegion(); var cur = this._getGridPositionAndSize(BI.extend(cloned[name], { left: position.left < 0 ? 0 : position.left, top: position.top < 0 ? 0 : position.top })); var x = cur.x, y = cur.y; cur = BI.extend(cur, { x: 0, y: BI.MAX, i: -1 }); delete cloned[name]; var layout = this._getLayoutsByRegions(cloned); layout = this._moveElement([cur].concat(layout), cur, x, y, true); layout = this.compact(layout, true); var regions = this._getRegionsByLayout(layout); this._modifyRegion(regions); this._applyRegion(); this._setBlockPositionAndSize(this._getBlockPositionAndSize(cur)); this.block.setVisible(true); } else { BI.extend(this.regions[name], { left: position.left < 0 ? 0 : position.left, top: position.top < 0 ? 0 : position.top }); var cloned = this._cloneRegion(); var layout = this._getLayoutsByRegions(cloned); layout = this.compact(layout, true); var regions = this._getRegionsByLayout(layout); this._modifyRegion(regions); this._applyRegion(); this.block.setVisible(false); } break; } }, setDropPosition: function (position, size) { var self = this; this.arrangement.setVisible(true); var offset = this._getScrollOffset(); this._setArrangeSize(BI.extend({}, size, { left: position.left + offset.left, top: position.top + offset.top })); return function () { self.arrangement.setVisible(false); }; }, scrollTo: function (scroll) { this.container.element.scrollTop(scroll.top); this.container.element.scrollLeft(scroll.left); }, zoom: function (ratio) { var self = this, o = this.options; if (!ratio) { return; } var occupied = this._applyContainer(); switch (this.getLayoutType()) { case BI.Arrangement.LAYOUT_TYPE.FREE: if (this._isArrangeFine()) { var width = this.getClientWidth(); var xRatio = (ratio.x || 1) * width / (occupied.left + occupied.width); // var yRatio = ratio.y * height / (occupied.top + occupied.height); var regions = this._cloneRegion(); BI.each(regions, function (i, region) { region.left = region.left * xRatio; // region.top = region.top * yRatio; region.width = region.width * xRatio; // region.height = region.height * yRatio; }); if (this._test(regions)) { this._modifyRegion(regions); this._applyRegion(); } this.resize(); // } else { this.relayout(); } break; case BI.Arrangement.LAYOUT_TYPE.GRID: if (this._isArrangeFine()) { var width = this.getClientWidth(), height = this.getClientHeight(); var xRatio = (ratio.x || 1) * width / (occupied.left + occupied.width); var yRatio = (ratio.y || 1) * height / (occupied.top + occupied.height); var regions = this._cloneRegion(); BI.each(regions, function (i, region) { region.left = region.left * xRatio; region.width = region.width * xRatio; region.top = region.top * yRatio; region.height = region.height * yRatio; // 做一下自适应布局到网格布局的兼容 var perWidth = self._getOneWidthPortion(); var widthPortion = Math.round(region.width / perWidth); var leftPortion = Math.round(region.left / perWidth); var comparePortion = Math.round((region.width + region.left) / perWidth); if (leftPortion + widthPortion !== comparePortion) { region.left = leftPortion * perWidth; region.width = comparePortion * perWidth - region.left; } }); if (this._test(regions)) { var layout = this._getLayoutsByRegions(regions); layout = this.compact(layout, true); regions = this._getRegionsByLayout(layout); this._modifyRegion(regions); this._applyRegion(); } } else { this.relayout(); } break; } }, resize: function () { var self = this, o = this.options; switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: break; case BI.Arrangement.LAYOUT_TYPE.GRID: this.zoom(this.ratio); var regions = this._cloneRegion(); var layout = this._getLayoutsByRegions(regions); layout = this.compact(layout, true); regions = this._getRegionsByLayout(layout); this._modifyRegion(regions); this._applyRegion(); break; } }, relayout: function () { var self = this, o = this.options; switch (o.layoutType) { case BI.Arrangement.LAYOUT_TYPE.FREE: break; case BI.Arrangement.LAYOUT_TYPE.GRID: if (!this._isArrangeFine()) { var perHeight = this._getOneHeightPortion(); var width = this.getClientWidth(), height = this.getClientHeight(); var regions = this._cloneRegion(); var clone = BI.toArray(regions); clone.sort(function (r1, r2) { if (self._isEqual(r1.top, r2.top)) { return r1.left - r2.left; } return r1.top - r2.top; }); var count = clone.length; var cols = 4, rows = Math.floor((count - 1) / 4 + 1); var w = width / cols, h = height / rows; var store = {}; BI.each(clone, function (i, region) { var row = Math.floor(i / 4), col = i % 4; BI.extend(region, { top: row * perHeight * 6, left: col * w, width: w, height: perHeight * 6 }); if (!store[row]) { store[row] = {}; } store[row][col] = region; }); // 非4的倍数 // if (count % 4 !== 0) { // var lasts = store[rows - 1]; // var perWidth = width / (count % 4); // BI.each(lasts, function (i, region) { // BI.extend(region, { // left: BI.parseInt(i) * perWidth, // width: perWidth // }); // }); // } if (this._test(clone)) { var layout = this._getLayoutsByRegions(regions); layout = this.compact(layout, true); regions = this._getRegionsByLayout(layout); this._modifyRegion(regions); this._populate(clone); } } else { this.resize(); } break; } }, _populate: function (items) { this._stop(); this._calculateRegions(items); this._applyRegion(); }, populate: function (items) { // this.regions = {}; var self = this; BI.each(this.regions, function (name, region) { var exist = BI.some(items, function (i, item) { return item.el.attr("id") === name; }); if (!exist) { self.regions[name].el.setVisible(false); } delete self.regions[name]; }); this._populate(items); this._renderRegion(); } }); BI.Arrangement.EVENT_SCROLL = "EVENT_SCROLL"; BI.extend(BI.Arrangement, { PORTION: 36, H_PORTION: 18, LAYOUT_TYPE: { GRID: 0, FREE: 1 } }); BI.shortcut("bi.arrangement", BI.Arrangement);/** * 日期控件中的月份下拉框 * * Created by GUY on 2015/9/7. * @class BI.MonthDateCombo * @extends BI.Trigger */ BI.MonthDateCombo = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend( BI.MonthDateCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-month-combo", height: 25 }); }, _init: function () { BI.MonthDateCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.date_triangle_trigger" }); this.popup = BI.createWidget({ type: "bi.month_popup" }); this.popup.on(BI.YearPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); }); this.combo = BI.createWidget({ type: "bi.combo", offsetStyle: "center", element: this, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, popup: { minWidth: 85, stopPropagation: false, el: this.popup } }); this.combo.on(BI.Combo.EVENT_CHANGE, function () { self.combo.hideView(); self.fireEvent(BI.MonthDateCombo.EVENT_CHANGE); }); }, setValue: function (v) { this.trigger.setValue(v + 1); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); } }); BI.MonthDateCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.month_date_combo", BI.MonthDateCombo);/** * 年份下拉框 * * Created by GUY on 2015/9/7. * @class BI.YearDateCombo * @extends BI.Trigger */ BI.YearDateCombo = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend( BI.YearDateCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-year-combo", min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 height: 25 }); }, _init: function () { BI.YearDateCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.date_triangle_trigger" }); this.popup = BI.createWidget({ type: "bi.year_popup", min: o.min, max: o.max }); this.popup.on(BI.YearPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.YearDateCombo.EVENT_CHANGE); }); this.combo = BI.createWidget({ type: "bi.combo", offsetStyle: "center", element: this, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, popup: { minWidth: 85, stopPropagation: false, el: this.popup } }); this.combo.on(BI.Combo.EVENT_CHANGE, function () { self.fireEvent(BI.YearDateCombo.EVENT_CHANGE); }); }, setValue: function (v) { this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); } }); BI.YearDateCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.year_date_combo", BI.YearDateCombo);/** * Created by GUY on 2015/9/7. * @class BI.DatePicker * @extends BI.Widget */ BI.DatePicker = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.DatePicker.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-date-picker bi-background", height: 25, min: "1900-01-01", // 最小日期 max: "2099-12-31" // 最大日期 }); }, _init: function () { BI.DatePicker.superclass._init.apply(this, arguments); var self = this, o = this.options; this._year = Date.getDate().getFullYear(); this._month = Date.getDate().getMonth(); this.left = BI.createWidget({ type: "bi.icon_button", cls: "pre-page-h-font", width: 25, height: 25 }); this.left.on(BI.IconButton.EVENT_CHANGE, function () { if (self._month === 0) { self.setValue({ year: self.year.getValue() - 1, month: 11 }); } else { self.setValue({ year: self.year.getValue(), month: self.month.getValue() - 1 }); } self.fireEvent(BI.DatePicker.EVENT_CHANGE); self._checkLeftValid(); self._checkRightValid(); }); this.right = BI.createWidget({ type: "bi.icon_button", cls: "next-page-h-font", width: 25, height: 25 }); this.right.on(BI.IconButton.EVENT_CHANGE, function () { if (self._month === 11) { self.setValue({ year: self.year.getValue() + 1, month: 0 }); } else { self.setValue({ year: self.year.getValue(), month: self.month.getValue() + 1 }); } self.fireEvent(BI.DatePicker.EVENT_CHANGE); self._checkLeftValid(); self._checkRightValid(); }); this.year = BI.createWidget({ type: "bi.year_date_combo", min: o.min, max: o.max }); this.year.on(BI.YearDateCombo.EVENT_CHANGE, function () { self.setValue({ year: self.year.getValue(), month: self.month.getValue() }); self.fireEvent(BI.DatePicker.EVENT_CHANGE); }); this.month = BI.createWidget({ type: "bi.month_date_combo" }); this.month.on(BI.MonthDateCombo.EVENT_CHANGE, function () { self.setValue({ year: self.year.getValue(), month: self.month.getValue() }); self.fireEvent(BI.DatePicker.EVENT_CHANGE); }); BI.createWidget({ type: "bi.htape", element: this, items: [{ el: this.left, width: 25 }, { type: "bi.center_adapt", items: [{ type: "bi.horizontal", width: 100, items: [this.year, this.month] }] }, { el: this.right, width: 25 }] }); this.setValue({ year: this._year, month: this._month }); }, _checkLeftValid: function () { var o = this.options; var valid = !(this._month === 0 && this._year === Date.parseDateTime(o.min, "%Y-%X-%d").getFullYear()); this.left.setEnable(valid); return valid; }, _checkRightValid: function () { var o = this.options; var valid = !(this._month === 11 && this._year === Date.parseDateTime(o.max, "%Y-%X-%d").getFullYear()); this.right.setEnable(valid); return valid; }, setValue: function (ob) { this._year = ob.year; this._month = ob.month; this.year.setValue(ob.year); this.month.setValue(ob.month); this._checkLeftValid(); this._checkRightValid(); }, getValue: function () { return { year: this.year.getValue(), month: this.month.getValue() }; } }); BI.DatePicker.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.date_picker", BI.DatePicker);/** * Created by GUY on 2015/9/7. * @class BI.DateCalendarPopup * @extends BI.Widget */ BI.DateCalendarPopup = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.DateCalendarPopup.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-date-calendar-popup", min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 selectedTime: null }); }, _createNav: function (v) { var date = BI.Calendar.getDateJSONByPage(v); var calendar = BI.createWidget({ type: "bi.calendar", logic: { dynamic: true }, min: this.options.min, max: this.options.max, year: date.year, month: date.month, day: this.selectedTime.day }); return calendar; }, _init: function () { BI.DateCalendarPopup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.today = Date.getDate(); this._year = this.today.getFullYear(); this._month = this.today.getMonth(); this._day = this.today.getDate(); this.selectedTime = o.selectedTime || { year: this._year, month: this._month, day: this._day }; this.datePicker = BI.createWidget({ type: "bi.date_picker", min: o.min, max: o.max }); this.calendar = BI.createWidget({ direction: "top", element: this, logic: { dynamic: true }, type: "bi.navigation", tab: this.datePicker, cardCreator: BI.bind(this._createNav, this), afterCardCreated: function () { }, afterCardShow: function () { this.setValue(self.selectedTime); } }); this.datePicker.on(BI.DatePicker.EVENT_CHANGE, function () { self.selectedTime = self.datePicker.getValue(); self.selectedTime.day = 1; self.calendar.setSelect(BI.Calendar.getPageByDateJSON(self.selectedTime)); }); this.calendar.on(BI.Navigation.EVENT_CHANGE, function () { self.selectedTime = self.calendar.getValue(); self.setValue(self.selectedTime); self.fireEvent(BI.DateCalendarPopup.EVENT_CHANGE); }); }, setValue: function (timeOb) { this.datePicker.setValue(timeOb); this.calendar.setSelect(BI.Calendar.getPageByDateJSON(timeOb)); this.calendar.setValue(timeOb); this.selectedTime = timeOb; }, getValue: function () { return this.selectedTime; } }); BI.DateCalendarPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.date_calendar_popup", BI.DateCalendarPopup);/** * 日期控件中的年份或月份trigger * * Created by GUY on 2015/9/7. * @class BI.DateTriangleTrigger * @extends BI.Trigger */ BI.DateTriangleTrigger = BI.inherit(BI.Trigger, { _const: { height: 25, iconWidth: 16, iconHeight: 13 }, _defaultConfig: function () { return BI.extend( BI.DateTriangleTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-date-triangle-trigger pull-down-ha-font cursor-pointer", height: 25 }); }, _init: function () { BI.DateTriangleTrigger.superclass._init.apply(this, arguments); var o = this.options, c = this._const; this.text = BI.createWidget({ type: "bi.label", cls: "list-item-text", textAlign: "right", text: o.text, value: o.value, height: c.height }); this.icon = BI.createWidget({ type: "bi.icon", width: c.iconWidth, height: c.iconHeight }); BI.createWidget({ type: "bi.center_adapt", element: this, items: [{ type: "bi.center_adapt", width: 50, height: c.height, items: [this.text, this.icon] }] }); }, setValue: function (v) { this.text.setValue(v); }, getValue: function () { return this.text.getValue(); }, setText: function (v) { this.text.setText(v); }, getText: function () { return this.item.getText(); }, getKey: function () { } }); BI.shortcut("bi.date_triangle_trigger", BI.DateTriangleTrigger);/** * 日期下拉框 * * Created by GUY on 2015/9/7. * @class BI.DateCombo * @extends BI.Widget */ BI.DateCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DateCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-date-combo bi-border", height: 25 }); }, _init: function () { BI.DateCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.date_trigger" }); this.trigger.on(BI.DateTrigger.EVENT_TRIGGER_CLICK, function () { self.combo.toggle(); }); this.popup = BI.createWidget({ type: "bi.date_calendar_popup" }); this.popup.on(BI.DateCalendarPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, element: this, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, popup: { width: 270, el: this.popup, stopPropagation: false } }); }, setValue: function (v) { this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); } }); BI.shortcut("bi.date_combo", BI.DateCombo);BI.DateTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4, vgap: 2, yearLength: 4, yearMonthLength: 7 }, _defaultConfig: function () { return BI.extend(BI.DateTrigger.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-date-trigger", min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 height: 24 }); }, _init: function () { BI.DateTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.editor = BI.createWidget({ type: "bi.sign_editor", height: o.height, validationChecker: function (v) { var date = v.match(/\d+/g); self._autoAppend(v, date); return self._dateCheck(v) && Date.checkLegal(v) && self._checkVoid({ year: date[0], month: date[1], day: date[2] }); }, quitChecker: function () { return false; }, hgap: c.hgap, vgap: c.vgap, allowBlank: true, watermark: BI.i18nText("BI-Basic_Unrestricted"), errorText: function () { if (self.editor.isEditing()) { return BI.i18nText("BI-Date_Trigger_Error_Text"); } return BI.i18nText("BI-Year_Trigger_Invalid_Text"); } }); this.editor.on(BI.SignEditor.EVENT_KEY_DOWN, function () { self.fireEvent(BI.DateTrigger.EVENT_KEY_DOWN); }); this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { self.fireEvent(BI.DateTrigger.EVENT_FOCUS); }); this.editor.on(BI.SignEditor.EVENT_STOP, function () { self.fireEvent(BI.DateTrigger.EVENT_STOP); }); this.editor.on(BI.SignEditor.EVENT_VALID, function () { self.fireEvent(BI.DateTrigger.EVENT_VALID); }); this.editor.on(BI.SignEditor.EVENT_ERROR, function () { self.fireEvent(BI.DateTrigger.EVENT_ERROR); }); this.editor.on(BI.SignEditor.EVENT_CONFIRM, function () { var value = self.editor.getValue(); if (BI.isNotNull(value)) { self.editor.setState(value); } if (BI.isNotEmptyString(value)) { var date = value.split("-"); self.store_value = { type: BI.DateTrigger.MULTI_DATE_CALENDAR, value: { year: date[0] | 0, month: date[1] - 1, day: date[2] | 0 } }; } self.fireEvent(BI.DateTrigger.EVENT_CONFIRM); }); this.editor.on(BI.SignEditor.EVENT_SPACE, function () { if (self.editor.isValid()) { self.editor.blur(); } }); this.editor.on(BI.SignEditor.EVENT_START, function () { self.fireEvent(BI.DateTrigger.EVENT_START); }); this.editor.on(BI.SignEditor.EVENT_CHANGE, function () { self.fireEvent(BI.DateTrigger.EVENT_CHANGE); }); BI.createWidget({ type: "bi.htape", element: this, items: [{ el: BI.createWidget(), width: 30 }, { el: this.editor }] }); }, _dateCheck: function (date) { return Date.parseDateTime(date, "%Y-%x-%d").print("%Y-%x-%d") == date || Date.parseDateTime(date, "%Y-%X-%d").print("%Y-%X-%d") == date || Date.parseDateTime(date, "%Y-%x-%e").print("%Y-%x-%e") == date || Date.parseDateTime(date, "%Y-%X-%e").print("%Y-%X-%e") == date; }, _checkVoid: function (obj) { return !Date.checkVoid(obj.year, obj.month, obj.day, this.options.min, this.options.max)[0]; }, _autoAppend: function (v, dateObj) { var self = this; var date = Date.parseDateTime(v, "%Y-%X-%d").print("%Y-%X-%d"); var yearCheck = function (v) { return Date.parseDateTime(v, "%Y").print("%Y") == v && date >= self.options.min && date <= self.options.max; }; var monthCheck = function (v) { return Date.parseDateTime(v, "%Y-%X").print("%Y-%X") == v && date >= self.options.min && date <= self.options.max; }; if (BI.isNotNull(dateObj) && Date.checkLegal(v)) { switch (v.length) { case this._const.yearLength: if (yearCheck(v)) { this.editor.setValue(v + "-"); } break; case this._const.yearMonthLength: if (monthCheck(v)) { this.editor.setValue(v + "-"); } break; } } }, setValue: function (v) { var type, value, self = this; var date = Date.getDate(); this.store_value = v; if (BI.isNotNull(v)) { type = v.type || BI.DateTrigger.MULTI_DATE_CALENDAR; value = v.value; if(BI.isNull(value)) { value = v; } } var _setInnerValue = function (date, text) { var dateStr = date.print("%Y-%x-%e"); self.editor.setState(dateStr); self.editor.setValue(dateStr); self.setTitle(text + ":" + dateStr); }; switch (type) { case BI.DateTrigger.MULTI_DATE_YEAR_PREV: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_PREV]; date = Date.getDate((date.getFullYear() - 1 * value), date.getMonth(), date.getDate()); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_YEAR_AFTER: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_AFTER]; date = Date.getDate((date.getFullYear() + 1 * value), date.getMonth(), date.getDate()); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_YEAR_BEGIN: var text = BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_BEGIN]; date = Date.getDate(date.getFullYear(), 0, 1); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_YEAR_END: var text = BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_END]; date = Date.getDate(date.getFullYear(), 11, 31); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_QUARTER_PREV: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_PREV]; date = Date.getDate().getBeforeMulQuarter(value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_QUARTER_AFTER: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_AFTER]; date = Date.getDate().getAfterMulQuarter(value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_QUARTER_BEGIN: var text = BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_BEGIN]; date = Date.getDate().getQuarterStartDate(); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_QUARTER_END: var text = BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_END]; date = Date.getDate().getQuarterEndDate(); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_MONTH_PREV: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_PREV]; date = Date.getDate().getBeforeMultiMonth(value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_MONTH_AFTER: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_AFTER]; date = Date.getDate().getAfterMultiMonth(value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_MONTH_BEGIN: var text = BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_BEGIN]; date = Date.getDate(date.getFullYear(), date.getMonth(), 1); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_MONTH_END: var text = BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_END]; date = Date.getDate(date.getFullYear(), date.getMonth(), (date.getLastDateOfMonth()).getDate()); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_WEEK_PREV: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_WEEK_PREV]; date = date.getOffsetDate(-7 * value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_WEEK_AFTER: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_WEEK_AFTER]; date = date.getOffsetDate(7 * value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_DAY_PREV: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_DAY_PREV]; date = date.getOffsetDate(-1 * value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_DAY_AFTER: var text = value + BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_DAY_AFTER]; date = date.getOffsetDate(1 * value); _setInnerValue(date, text); break; case BI.DateTrigger.MULTI_DATE_DAY_TODAY: var text = BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_DAY_TODAY]; date = Date.getDate(); _setInnerValue(date, text); break; default: if (BI.isNull(value) || BI.isNull(value.day)) { this.editor.setState(""); this.editor.setValue(""); this.setTitle(""); } else { var dateStr = value.year + "-" + (value.month + 1) + "-" + value.day; this.editor.setState(dateStr); this.editor.setValue(dateStr); this.setTitle(dateStr); } break; } }, getKey: function () { return this.editor.getValue(); }, getValue: function () { return this.store_value; } }); BI.DateTrigger.MULTI_DATE_YEAR_PREV = 1; BI.DateTrigger.MULTI_DATE_YEAR_AFTER = 2; BI.DateTrigger.MULTI_DATE_YEAR_BEGIN = 3; BI.DateTrigger.MULTI_DATE_YEAR_END = 4; BI.DateTrigger.MULTI_DATE_MONTH_PREV = 5; BI.DateTrigger.MULTI_DATE_MONTH_AFTER = 6; BI.DateTrigger.MULTI_DATE_MONTH_BEGIN = 7; BI.DateTrigger.MULTI_DATE_MONTH_END = 8; BI.DateTrigger.MULTI_DATE_QUARTER_PREV = 9; BI.DateTrigger.MULTI_DATE_QUARTER_AFTER = 10; BI.DateTrigger.MULTI_DATE_QUARTER_BEGIN = 11; BI.DateTrigger.MULTI_DATE_QUARTER_END = 12; BI.DateTrigger.MULTI_DATE_WEEK_PREV = 13; BI.DateTrigger.MULTI_DATE_WEEK_AFTER = 14; BI.DateTrigger.MULTI_DATE_DAY_PREV = 15; BI.DateTrigger.MULTI_DATE_DAY_AFTER = 16; BI.DateTrigger.MULTI_DATE_DAY_TODAY = 17; BI.DateTrigger.MULTI_DATE_PARAM = 18; BI.DateTrigger.MULTI_DATE_CALENDAR = 19; BI.DateTrigger.MULTI_DATE_SEGMENT_NUM = {}; BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_PREV] = BI.i18nText("BI-Multi_Date_Year_Prev"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_AFTER] = BI.i18nText("BI-Multi_Date_Year_Next"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_BEGIN] = BI.i18nText("BI-Multi_Date_Year_Begin"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_YEAR_END] = BI.i18nText("BI-Multi_Date_Year_End"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_PREV] = BI.i18nText("BI-Multi_Date_Quarter_Prev"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_AFTER] = BI.i18nText("BI-Multi_Date_Quarter_Next"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_BEGIN] = BI.i18nText("BI-Multi_Date_Quarter_Begin"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_QUARTER_END] = BI.i18nText("BI-Multi_Date_Quarter_End"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_PREV] = BI.i18nText("BI-Multi_Date_Month_Prev"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_AFTER] = BI.i18nText("BI-Multi_Date_Month_Next"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_BEGIN] = BI.i18nText("BI-Multi_Date_Month_Begin"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_MONTH_END] = BI.i18nText("BI-Multi_Date_Month_End"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_WEEK_PREV] = BI.i18nText("BI-Multi_Date_Week_Prev"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_WEEK_AFTER] = BI.i18nText("BI-Multi_Date_Week_Next"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_DAY_PREV] = BI.i18nText("BI-Multi_Date_Day_Prev"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_DAY_AFTER] = BI.i18nText("BI-Multi_Date_Day_Next"); BI.DateTrigger.MULTI_DATE_SEGMENT_NUM[BI.DateTrigger.MULTI_DATE_DAY_TODAY] = BI.i18nText("BI-Multi_Date_Today"); BI.DateTrigger.EVENT_FOCUS = "EVENT_FOCUS"; BI.DateTrigger.EVENT_START = "EVENT_START"; BI.DateTrigger.EVENT_STOP = "EVENT_STOP"; BI.DateTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.DateTrigger.EVENT_CHANGE = "EVENT_CHANGE"; BI.DateTrigger.EVENT_VALID = "EVENT_VALID"; BI.DateTrigger.EVENT_ERROR = "EVENT_ERROR"; BI.DateTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; BI.DateTrigger.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.shortcut("bi.date_trigger", BI.DateTrigger);/** * Created by zcf on 2017/2/20. */ BI.DatePaneWidget = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.DatePaneWidget.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-date-pane", min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 selectedTime: null }); }, _init: function () { BI.DatePaneWidget.superclass._init.apply(this, arguments); var self = this, o = this.options; this.today = Date.getDate(); this._year = this.today.getFullYear(); this._month = this.today.getMonth(); this.selectedTime = o.selectedTime || { year: this._year, month: this._month }; this.datePicker = BI.createWidget({ type: "bi.date_picker", min: o.min, max: o.max }); this.datePicker.on(BI.DatePicker.EVENT_CHANGE, function () { self.selectedTime = self.datePicker.getValue(); // self.selectedTime.day = 1; self.calendar.setSelect(BI.Calendar.getPageByDateJSON(self.selectedTime)); }); this.calendar = BI.createWidget({ direction: "top", element: this, logic: { dynamic: false }, type: "bi.navigation", tab: this.datePicker, cardCreator: BI.bind(this._createNav, this) // afterCardCreated: function () { // // }, // // afterCardShow: function () { // // this.setValue(self.selectedTime); // } }); this.calendar.on(BI.Navigation.EVENT_CHANGE, function () { self.selectedTime = self.calendar.getValue(); self.calendar.empty(); self.setValue(self.selectedTime); self.fireEvent(BI.DateCalendarPopup.EVENT_CHANGE); }); }, _createNav: function (v) { var date = BI.Calendar.getDateJSONByPage(v); var calendar = BI.createWidget({ type: "bi.calendar", logic: { dynamic: false }, min: this.options.min, max: this.options.max, year: date.year, month: date.month, day: this.selectedTime.day }); return calendar; }, _getNewCurrentDate: function () { var today = Date.getDate(); return { year: today.getFullYear(), month: today.getMonth() }; }, _setCalenderValue: function (date) { this.calendar.setSelect(BI.Calendar.getPageByDateJSON(date)); this.calendar.setValue(date); this.selectedTime = date; }, _setDatePicker: function (timeOb) { if (BI.isNull(timeOb) || BI.isNull(timeOb.year) || BI.isNull(timeOb.month)) { this.datePicker.setValue(this._getNewCurrentDate()); } else { this.datePicker.setValue(timeOb); } }, _setCalendar: function (timeOb) { if (BI.isNull(timeOb) || BI.isNull(timeOb.day)) { this.calendar.empty(); this._setCalenderValue(this._getNewCurrentDate()); } else { this._setCalenderValue(timeOb); } }, setValue: function (timeOb) { this._setDatePicker(timeOb); this._setCalendar(timeOb); }, getValue: function () { return this.selectedTime; } }); BI.shortcut("bi.date_pane", BI.DatePaneWidget);/** * Created by Urthur on 2017/7/14. */ BI.DateTimeCombo = BI.inherit(BI.Single, { constants: { popupHeight: 290, popupWidth: 270, comboAdjustHeight: 1, border: 1, DATE_MIN_VALUE: "1900-01-01", DATE_MAX_VALUE: "2099-12-31" }, _defaultConfig: function () { return BI.extend(BI.DateTimeCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-date-time-combo bi-border", width: 200, height: 24 }); }, _init: function () { BI.DateTimeCombo.superclass._init.apply(this, arguments); var self = this, opts = this.options; var date = Date.getDate(); this.storeValue = { year: date.getFullYear(), month: date.getMonth(), day: date.getDate(), hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds() }; this.trigger = BI.createWidget({ type: "bi.date_time_trigger", min: this.constants.DATE_MIN_VALUE, max: this.constants.DATE_MAX_VALUE }); this.popup = BI.createWidget({ type: "bi.date_time_popup", min: this.constants.DATE_MIN_VALUE, max: this.constants.DATE_MAX_VALUE }); self.setValue(this.storeValue); this.popup.on(BI.DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE, function () { self.setValue(self.storeValue); self.hidePopupView(); self.fireEvent(BI.DateTimeCombo.EVENT_CANCEL); }); this.popup.on(BI.DateTimePopup.BUTTON_OK_EVENT_CHANGE, function () { self.storeValue = self.popup.getValue(); self.setValue(self.storeValue); self.hidePopupView(); self.fireEvent(BI.DateTimeCombo.EVENT_CONFIRM); }); this.popup.on(BI.DateTimePopup.CALENDAR_EVENT_CHANGE, function () { self.trigger.setValue(self.popup.getValue()); self.fireEvent(BI.DateTimeCombo.EVENT_CHANGE); }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, adjustLength: this.constants.comboAdjustHeight, popup: { el: this.popup, maxHeight: this.constants.popupHeight, width: this.constants.popupWidth, stopPropagation: false } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.popup.setValue(self.storeValue); self.fireEvent(BI.DateTimeCombo.EVENT_BEFORE_POPUPVIEW); }); var triggerBtn = BI.createWidget({ type: "bi.icon_button", cls: "bi-trigger-icon-button date-font bi-border-right", width: 24, height: 24 }); triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { if (self.combo.isViewVisible()) { self.combo.hideView(); } else { self.combo.showView(); } }); BI.createWidget({ type: "bi.htape", element: this, items: [{ type: "bi.absolute", items: [{ el: this.combo, top: 0, left: 0, right: 0, bottom: 0 }, { el: triggerBtn, top: 0, left: 0 }] }] }); }, setValue: function (v) { this.storeValue = v; this.popup.setValue(v); this.trigger.setValue(v); }, getValue: function () { return this.storeValue; }, hidePopupView: function () { this.combo.hideView(); } }); BI.DateTimeCombo.EVENT_CANCEL = "EVENT_CANCEL"; BI.DateTimeCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.DateTimeCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.DateTimeCombo.EVENT_BEFORE_POPUPVIEW = "BI.DateTimeCombo.EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.date_time_combo", BI.DateTimeCombo); /** * Created by Urthur on 2017/7/14. */ BI.DateTimePopup = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DateTimePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-date-time-popup", width: 268, height: 290 }); }, _init: function () { BI.DateTimePopup.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.cancelButton = BI.createWidget({ type: "bi.text_button", forceCenter: true, cls: "multidate-popup-button bi-border-top bi-border-right", shadow: true, text: BI.i18nText("BI-Basic_Cancel") }); this.cancelButton.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE); }); this.okButton = BI.createWidget({ type: "bi.text_button", forceCenter: true, cls: "multidate-popup-button bi-border-top", shadow: true, text: BI.i18nText("BI-Basic_OK") }); this.okButton.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.DateTimePopup.BUTTON_OK_EVENT_CHANGE); }); this.dateCombo = BI.createWidget({ type: "bi.date_calendar_popup", min: self.options.min, max: self.options.max }); self.dateCombo.on(BI.DateCalendarPopup.EVENT_CHANGE, function () { self.fireEvent(BI.DateTimePopup.CALENDAR_EVENT_CHANGE); }); this.dateSelect = BI.createWidget({ type: "bi.vertical_adapt", cls: "bi-border-top", items: [{ type: "bi.label", text: BI.i18nText("BI-Basic_Time"), width: 45 }, { type: "bi.date_time_select", max: 23, min: 0, width: 60, height: 30, listeners: [{ eventName: BI.DateTimeSelect.EVENT_CONFIRM, action: function () { self.fireEvent(BI.DateTimePopup.CALENDAR_EVENT_CHANGE); } }], ref: function (_ref) { self.hour = _ref; } }, { type: "bi.label", text: ":", width: 15 }, { type: "bi.date_time_select", max: 59, min: 0, width: 60, height: 30, listeners: [{ eventName: BI.DateTimeSelect.EVENT_CONFIRM, action: function () { self.fireEvent(BI.DateTimePopup.CALENDAR_EVENT_CHANGE); } }], ref: function (_ref) { self.minute = _ref; } }, { type: "bi.label", text: ":", width: 15 }, { type: "bi.date_time_select", max: 59, min: 0, width: 60, height: 30, listeners: [{ eventName: BI.DateTimeSelect.EVENT_CONFIRM, action: function () { self.fireEvent(BI.DateTimePopup.CALENDAR_EVENT_CHANGE); } }], ref: function (_ref) { self.second = _ref; } }] }); var date = Date.getDate(); this.dateCombo.setValue({ year: date.getFullYear(), month: date.getMonth(), day: date.getDate() }); this.hour.setValue(date.getHours()); this.minute.setValue(date.getMinutes()); this.second.setValue(date.getSeconds()); this.dateButton = BI.createWidget({ type: "bi.grid", items: [[this.cancelButton, this.okButton]] }); BI.createWidget({ element: this, type: "bi.vtape", items: [{ el: this.dateCombo }, { el: this.dateSelect, height: 50 }, { el: this.dateButton, height: 30 }] }); }, setValue: function (v) { var value = v, date; if (BI.isNull(value)) { date = Date.getDate(); this.dateCombo.setValue({ year: date.getFullYear(), month: date.getMonth(), day: date.getDate() }); this.hour.setValue(date.getHours()); this.minute.setValue(date.getMinutes()); this.second.setValue(date.getSeconds()); } else { this.dateCombo.setValue({ year: value.year, month: value.month, day: value.day }); this.hour.setValue(value.hour); this.minute.setValue(value.minute); this.second.setValue(value.second); } }, getValue: function () { return { year: this.dateCombo.getValue().year, month: this.dateCombo.getValue().month, day: this.dateCombo.getValue().day, hour: this.hour.getValue(), minute: this.minute.getValue(), second: this.second.getValue() }; } }); BI.DateTimePopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; BI.DateTimePopup.BUTTON_CANCEL_EVENT_CHANGE = "BUTTON_CANCEL_EVENT_CHANGE"; BI.DateTimePopup.CALENDAR_EVENT_CHANGE = "CALENDAR_EVENT_CHANGE"; BI.shortcut("bi.date_time_popup", BI.DateTimePopup); /** * Created by Urthur on 2017/7/14. */ BI.DateTimeSelect = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DateTimeSelect.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-date-time-select bi-border", max: 23, min: 0 }); }, _init: function () { BI.DateTimeSelect.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.sign_editor", value: this._alertInEditorValue(o.min), allowBlank: false, errorText: BI.i18nText("BI-Please_Input_Natural_Number"), validationChecker: function (v) { return BI.isNaturalNumber(v); } }); this.editor.on(BI.TextEditor.EVENT_CONFIRM, function () { self._finetuning(0); self.fireEvent(BI.DateTimeSelect.EVENT_CONFIRM); }); this.topBtn = BI.createWidget({ type: "bi.icon_button", cls: "column-pre-page-h-font top-button bi-border-left bi-border-bottom" }); this.topBtn.on(BI.IconButton.EVENT_CHANGE, function () { self._finetuning(1); self.fireEvent(BI.DateTimeSelect.EVENT_CONFIRM); }); this.bottomBtn = BI.createWidget({ type: "bi.icon_button", cls: "column-next-page-h-font bottom-button bi-border-left" }); this.bottomBtn.on(BI.IconButton.EVENT_CHANGE, function () { self._finetuning(-1); self.fireEvent(BI.DateTimeSelect.EVENT_CONFIRM); }); this._finetuning(0); BI.createWidget({ type: "bi.htape", element: this, items: [this.editor, { el: { type: "bi.grid", columns: 1, rows: 2, items: [{ column: 0, row: 0, el: this.topBtn }, { column: 0, row: 1, el: this.bottomBtn }] }, width: 30 }] }); }, _alertOutEditorValue: function (v) { if (v > this.options.max) { v = this.options.min; } if (v < this.options.min) { v = this.options.max; } return BI.parseInt(v); }, _alertInEditorValue: function (v) { if (v > this.options.max) { v = this.options.min; } if (v < this.options.min) { v = this.options.max; } v = v < 10 ? "0" + v : v; return v; }, _finetuning: function (add) { var v = BI.parseInt(this._alertOutEditorValue(this.editor.getValue())); this.editor.setValue(this._alertInEditorValue(v + add)); }, getValue: function () { var v = this.editor.getValue(); return this._alertOutEditorValue(v); }, setValue: function (v) { this.editor.setValue(this._alertInEditorValue(v)); this._finetuning(0); } }); BI.DateTimeSelect.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.shortcut("bi.date_time_select", BI.DateTimeSelect);/** * Created by Urthur on 2017/7/14. */ BI.DateTimeTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4 }, _defaultConfig: function () { return BI.extend(BI.DateTimeTrigger.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-date-time-trigger", min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 height: 24, width: 200 }); }, _init: function () { BI.DateTimeTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.text = BI.createWidget({ type: "bi.label", textAlign: "left", height: o.height, width: o.width, hgap: c.hgap }); BI.createWidget({ type: "bi.htape", element: this, items: [{ el: BI.createWidget(), width: o.height }, { el: this.text }] }); }, _printTime: function (v) { return v < 10 ? "0" + v : v; }, setValue: function (v) { var self = this; var value = v, dateStr; if(BI.isNull(value)) { value = Date.getDate(); dateStr = value.print("%Y-%X-%d %H:%M:%S"); } else { var date = Date.getDate(value.year, value.month, value.day, value.hour, value.minute, value.second); dateStr = date.print("%Y-%X-%d %H:%M:%S"); } this.text.setText(dateStr); this.text.setTitle(dateStr); } }); BI.shortcut("bi.date_time_trigger", BI.DateTimeTrigger);/** * 带有方向的pathchooser * * Created by GUY on 2016/4/21. * @class BI.DirectionPathChooser * @extends BI.Widget */ BI.DirectionPathChooser = BI.inherit(BI.Widget, { _const: { lineColor: "#808080", selectLineColor: "#009de3" }, _defaultConfig: function () { return BI.extend(BI.DirectionPathChooser.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-excel-table", items: [] }); }, _init: function () { BI.DirectionPathChooser.superclass._init.apply(this, arguments); var self = this, o = this.options; this.pathChooser = BI.createWidget({ type: "bi.path_chooser", element: this, items: o.items }); this.pathChooser.on(BI.PathChooser.EVENT_CHANGE, function (start, index) { // self._unselectAllArrows(); self._setValue(start, index); self.fireEvent(BI.DirectionPathChooser.EVENT_CHANGE); }); this._drawArrows(); }, _unselectAllArrows: function () { var self = this, lineColor = this._const.lineColor; BI.each(this.arrows, function (region, rs) { BI.each(rs, function (idx, arrows) { BI.each(arrows, function (i, arrow) { arrow.attr({fill: lineColor, stroke: lineColor}); }); }); }); }, _drawOneArrow: function (dot, direction) { // 0,1,2,3 上右下左 var lineColor = this._const.lineColor; var selectLineColor = this._const.selectLineColor; var svg = this.pathChooser.svg; var path = ""; switch (direction) { case 0: path = "M" + dot.x + "," + dot.y + "L" + (dot.x - 3) + "," + (dot.y + 5) + "L" + (dot.x + 3) + "," + (dot.y + 5) + "L" + dot.x + "," + dot.y; break; case 1: path = "M" + dot.x + "," + dot.y + "L" + (dot.x - 5) + "," + (dot.y - 3) + "L" + (dot.x - 5) + "," + (dot.y + 3) + "L" + dot.x + "," + dot.y; break; case 2: path = "M" + dot.x + "," + dot.y + "L" + (dot.x - 3) + "," + (dot.y - 5) + "L" + (dot.x + 3) + "," + (dot.y - 5) + "L" + dot.x + "," + dot.y; break; case 3: path = "M" + dot.x + "," + dot.y + "L" + (dot.x + 5) + "," + (dot.y - 3) + "L" + (dot.x + 5) + "," + (dot.y + 3) + "L" + dot.x + "," + dot.y; break; } return svg.path(path).attr({fill: lineColor, stroke: lineColor}); }, _drawArrows: function () { var self = this, o = this.options; var routes = this.pathChooser.routes; var pathes = this.pathChooser.pathes; var cache = this.pathChooser.cache; this.arrows = {}; BI.each(routes, function (region, ps) { self.arrows[region] = []; BI.each(ps, function (idx, path) { self.arrows[region][idx] = []; var dots = pathes[region][idx]; BI.each(dots, function (i, dot) { if (i > 0 && i < dots.length - 1) { var arrow; if (dot.y === dots[i - 1].y) { if (dots[i + 1].y != dot.y) { if (cache[path[path.length - 2]].direction === -1) { if (i - 1 > 0) { arrow = self._drawOneArrow(dots[i - 1], 3); } } else { arrow = self._drawOneArrow(dots[i], 1); } } } else if (dot.x === dots[i - 1].x) { if (dot.y > dots[i - 1].y) { if (cache[BI.first(path)].direction === -1) { arrow = self._drawOneArrow(dots[i - 1], 0); } else { arrow = self._drawOneArrow(dot, 2); } } else { if (cache[path[path.length - 2]].direction === -1) { arrow = self._drawOneArrow(dots[i - 1], 2); } else { arrow = self._drawOneArrow(dot, 0); } } } if (arrow) { self.arrows[region][idx].push(arrow); } } }); BI.each(path, function (i, node) { if (i !== 0) { var arrow; var from = path[i - 1]; if (cache[from].direction === -1) { var regionIndex = self.pathChooser.getRegionIndexById(from); var x = getXoffsetByRegionIndex(regionIndex, -1); var y = getYByXoffset(dots, x); arrow = self._drawOneArrow({x: x, y: y}, 3); } else { var regionIndex = self.pathChooser.getRegionIndexById(node); var x = getXoffsetByRegionIndex(regionIndex); var y = getYByXoffset(dots, x); arrow = self._drawOneArrow({x: x, y: y}, 1); } if (arrow) { self.arrows[region][idx].push(arrow); } } }); }); }); function getXoffsetByRegionIndex (regionIndex, diregion) { if (diregion === -1) { return 100 * (regionIndex + 1) - 20; } return 100 * regionIndex + 20; } function getYByXoffset (dots, xoffset) { var finded = BI.find(dots, function (i, dot) { if (i > 0) { if (dots[i - 1].x < xoffset && dots[i].x > xoffset) { return true; } } }); return finded.y; } }, _setValue: function (start, index) { var self = this; var lineColor = this._const.lineColor; var selectLineColor = this._const.selectLineColor; var routes = this.pathChooser.routes; var starts = this.pathChooser.start; var each = [start]; if (starts.contains(start)) { each = starts; } BI.each(each, function (i, s) { BI.each(self.arrows[s], function (j, arrows) { BI.each(arrows, function (k, arrow) { arrow.attr({fill: lineColor, stroke: lineColor}).toFront(); }); }); }); BI.each(this.arrows[start][index], function (i, arrow) { arrow.attr({fill: selectLineColor, stroke: selectLineColor}).toFront(); }); var current = BI.last(routes[start][index]); while (current && routes[current] && routes[current].length === 1) { BI.each(self.arrows[current][0], function (i, arrow) { arrow.attr({fill: selectLineColor, stroke: selectLineColor}).toFront(); }); current = BI.last(routes[current][0]); } }, setValue: function (v) { this.pathChooser.setValue(v); this._unselectAllArrows(); var routes = this.pathChooser.routes; var nodes = BI.keys(routes), self = this; var result = [], array = []; BI.each(v, function (i, val) { if (BI.contains(nodes, val)) { if (array.length > 0) { array.push(val); result.push(array); array = []; } } array.push(val); }); if (array.length > 0) { result.push(array); } // 画这n条路径 BI.each(result, function (idx, path) { var start = path[0]; var index = BI.findIndex(routes[start], function (idx, p) { if (BI.isEqual(path, p)) { return true; } }); if (index >= 0) { self._setValue(start, index); } }); }, getValue: function () { return this.pathChooser.getValue(); }, populate: function (items) { this.pathChooser.populate(items); this._drawArrows(); } }); BI.DirectionPathChooser.EVENT_CHANGE = "DirectionPathChooser.EVENT_CHANGE"; BI.shortcut("bi.direction_path_chooser", BI.DirectionPathChooser);/** * Created by roy on 15/8/14. */ BI.DownListCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.DownListCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-down-list-combo", invalid: false, height: 25, items: [], adjustLength: 0, direction: "bottom", trigger: "click", container: null, stopPropagation: false, el: {} }); }, _init: function () { BI.DownListCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.popupview = BI.createWidget({ type: "bi.down_list_popup", items: o.items, chooseType: o.chooseType }); this.popupview.on(BI.DownListPopup.EVENT_CHANGE, function (value) { self.fireEvent(BI.DownListCombo.EVENT_CHANGE, value); self.downlistcombo.hideView(); }); this.popupview.on(BI.DownListPopup.EVENT_SON_VALUE_CHANGE, function (value, fatherValue) { self.fireEvent(BI.DownListCombo.EVENT_SON_VALUE_CHANGE, value, fatherValue); self.downlistcombo.hideView(); }); this.downlistcombo = BI.createWidget({ element: this, type: "bi.combo", trigger: o.trigger, isNeedAdjustWidth: false, container: o.container, adjustLength: o.adjustLength, direction: o.direction, stopPropagation: o.stopPropagation, el: BI.createWidget(o.el, { type: "bi.icon_trigger", extraCls: o.iconCls ? o.iconCls : "pull-down-font", width: o.width, height: o.height }), popup: { el: this.popupview, stopPropagation: true, maxHeight: 1000 } }); this.downlistcombo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.DownListCombo.EVENT_BEFORE_POPUPVIEW); }); }, hideView: function () { this.downlistcombo.hideView(); }, showView: function () { this.downlistcombo.showView(); }, populate: function (items) { this.popupview.populate(items); }, setValue: function (v) { this.popupview.setValue(v); }, getValue: function () { return this.popupview.getValue(); } }); BI.DownListCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.DownListCombo.EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; BI.DownListCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.down_list_combo", BI.DownListCombo);/** * Created by roy on 15/9/6. */ BI.DownListGroup = BI.inherit(BI.Widget, { constants: { iconCls: "check-mark-ha-font" }, _defaultConfig: function () { return BI.extend(BI.DownListGroup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-down-list-group", items: [ { el: {} } ] }); }, _init: function () { BI.DownListGroup.superclass._init.apply(this, arguments); var o = this.options, self = this; this.downlistgroup = BI.createWidget({ element: this, type: "bi.button_tree", items: o.items, chooseType: 0, // 0单选,1多选 layouts: [{ type: "bi.vertical", hgap: 0, vgap: 0 }] }); this.downlistgroup.on(BI.Controller.EVENT_CHANGE, function (type) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if(type === BI.Events.CLICK) { self.fireEvent(BI.DownListGroup.EVENT_CHANGE, arguments); } }); }, getValue: function () { return this.downlistgroup.getValue(); }, setValue: function (v) { this.downlistgroup.setValue(v); } }); BI.DownListGroup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.down_list_group", BI.DownListGroup);BI.DownListItem = BI.inherit(BI.Single, { _defaultConfig: function () { var conf = BI.DownListItem.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-down-list-item bi-list-item-active", cls: "", height: 25, logic: { dynamic: true }, selected: false, iconHeight: null, iconWidth: null, textHgap: 0, textVgap: 0, textLgap: 0, textRgap: 0 }); }, _init: function () { BI.DownListItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.text = BI.createWidget({ type: "bi.icon_text_item", element: this, height: o.height, text: o.text, value: o.value, logic: o.logic, selected: o.selected, disabled: o.disabled, iconHeight: o.iconHeight, iconWidth: o.iconWidth, textHgap: o.textHgap, textVgap: o.textVgap, textLgap: o.textLgap, textRgap: o.textRgap, father: o.father }); this.text.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.text.on(BI.IconTextItem.EVENT_CHANGE, function () { self.fireEvent(BI.DownListItem.EVENT_CHANGE); }); // this.setSelected(o.selected); }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, isSelected: function () { return this.text.isSelected(); }, setSelected: function (b) { this.text.setSelected(b); // if (b === true) { // this.element.addClass("dot-e-font"); // } else { // this.element.removeClass("dot-e-font"); // } }, setValue: function (v) { this.text.setValue(v); }, getValue: function () { return this.text.getValue(); } }); BI.DownListItem.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.down_list_item", BI.DownListItem);BI.DownListGroupItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { var conf = BI.DownListGroupItem.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-down-list-group-item", logic: { dynamic: false }, // invalid: true, iconCls1: "dot-e-font", iconCls2: "pull-right-e-font" }); }, _init: function () { BI.DownListGroupItem.superclass._init.apply(this, arguments); var o = this.options; var self = this; this.text = BI.createWidget({ type: "bi.label", cls: "list-group-item-text", textAlign: "left", text: o.text, value: o.value, height: o.height }); this.icon1 = BI.createWidget({ type: "bi.icon_button", cls: o.iconCls1, width: 25, forceNotSelected: true }); this.icon2 = BI.createWidget({ type: "bi.icon_button", cls: o.iconCls2, width: 25, forceNotSelected: true }); var blank = BI.createWidget({ type: "bi.layout", width: 25 }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.icon2, top: 0, bottom: 0, right: 0 }] }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic("horizontal", BI.extend(o.logic, { items: BI.LogicFactory.createLogicItemsByDirection("left", this.icon1, this.text, blank) })))); this.element.hover(function () { if (self.isEnabled()) { self.hover(); } }, function () { if (self.isEnabled()) { self.dishover(); } }); }, hover: function () { BI.DownListGroupItem.superclass.hover.apply(this, arguments); this.icon1.element.addClass("hover"); this.icon2.element.addClass("hover"); }, dishover: function () { BI.DownListGroupItem.superclass.dishover.apply(this, arguments); this.icon1.element.removeClass("hover"); this.icon2.element.removeClass("hover"); }, doClick: function () { BI.DownListGroupItem.superclass.doClick.apply(this, arguments); if (this.isValid()) { this.fireEvent(BI.DownListGroupItem.EVENT_CHANGE, this.getValue()); } }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, setValue: function (v) { var self = this, o = this.options; v = BI.isArray(v) ? v : [v]; BI.find(v, function (idx, value) { if (BI.contains(o.childValues, value)) { self.icon1.setSelected(true); return true; } self.icon1.setSelected(false); }); } }); BI.DownListGroupItem.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.down_list_group_item", BI.DownListGroupItem);/** * Created by roy on 15/9/8. * 处理popup中的item分组样式 * 一个item分组中的成员大于一时,该分组设置为单选,并且默认状态第一个成员设置为已选择项 */ BI.DownListPopup = BI.inherit(BI.Pane, { constants: { nextIcon: "pull-right-e-font", height: 25, iconHeight: 12, iconWidth: 12, hgap: 0, vgap: 0, border: 1 }, _defaultConfig: function () { var conf = BI.DownListPopup.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-down-list-popup", items: [], chooseType: BI.Selection.Multi }); }, _init: function () { BI.DownListPopup.superclass._init.apply(this, arguments); this.singleValues = []; this.childValueMap = {}; this.fatherValueMap = {}; var self = this, o = this.options, children = this._createChildren(o.items); this.popup = BI.createWidget({ type: "bi.button_tree", items: BI.createItems(children, {}, { adjustLength: -2 } ), layouts: [{ type: "bi.vertical", hgap: this.constants.hgap, vgap: this.constants.vgap }], chooseType: o.chooseType }); this.popup.on(BI.ButtonTree.EVENT_CHANGE, function (value, object) { var changedValue = value; if (BI.isNotNull(self.childValueMap[value])) { changedValue = self.childValueMap[value]; self.fireEvent(BI.DownListPopup.EVENT_SON_VALUE_CHANGE, changedValue, self.fatherValueMap[value]); } else { self.fireEvent(BI.DownListPopup.EVENT_CHANGE, changedValue, object); } if (!self.singleValues.contains(changedValue)) { var item = self.getValue(); var result = []; BI.each(item, function (i, valueObject) { if (valueObject.value != changedValue) { result.push(valueObject); } }); self.setValue(result); } }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.popup] }); }, _createChildren: function (items) { var self = this, result = []; BI.each(items, function (i, it) { var item_done = { type: "bi.down_list_group", items: [] }; BI.each(it, function (i, item) { if (BI.isNotEmptyArray(item.children) && !BI.isEmpty(item.el)) { item.type = "bi.combo_group"; item.cls = "down-list-group"; item.trigger = "hover"; item.isNeedAdjustWidth = false; item.el.title = item.el.title || item.el.text; item.el.type = "bi.down_list_group_item"; item.el.logic = { dynamic: true }; item.el.height = self.constants.height; item.el.iconCls2 = self.constants.nextIcon; item.popup = { lgap: 4, el: { type: "bi.button_tree", chooseType: 0, layouts: [{ type: "bi.vertical" }] } }; item.el.childValues = []; BI.each(item.children, function (i, child) { var fatherValue = BI.deepClone(item.el.value); var childValue = BI.deepClone(child.value); self.singleValues.push(child.value); child.type = "bi.down_list_item"; child.extraCls = " child-down-list-item"; child.title = child.title || child.text; child.textRgap = 10; child.isNeedAdjustWidth = false; child.logic = { dynamic: true }; child.father = fatherValue; self.fatherValueMap[self._createChildValue(fatherValue, childValue)] = fatherValue; self.childValueMap[self._createChildValue(fatherValue, childValue)] = childValue; child.value = self._createChildValue(fatherValue, childValue); item.el.childValues.push(child.value); }); } else { item.type = "bi.down_list_item"; item.title = item.title || item.text; item.textRgap = 10; item.isNeedAdjustWidth = false; item.logic = { dynamic: true }; } var el_done = {}; el_done.el = item; item_done.items.push(el_done); }); if (self._isGroup(item_done.items)) { BI.each(item_done.items, function (i, item) { self.singleValues.push(item.el.value); }); } result.push(item_done); if (self._needSpliter(i, items.length)) { var spliter_container = BI.createWidget({ type: "bi.vertical", items: [{ el: { type: "bi.layout", cls: "bi-down-list-spliter bi-border-top cursor-pointer", height: 0 } }], cls: "bi-down-list-spliter-container cursor-pointer", lgap: 10, rgap: 10 }); result.push(spliter_container); } }); return result; }, _isGroup: function (i) { return i.length > 1; }, _needSpliter: function (i, itemLength) { return i < itemLength - 1; }, _createChildValue: function (fatherValue, childValue) { return fatherValue + "_" + childValue; }, populate: function (items) { BI.DownListPopup.superclass.populate.apply(this, arguments); var self = this; self.childValueMap = {}; self.fatherValueMap = {}; self.singleValues = []; var children = self._createChildren(items); var popupItem = BI.createItems(children, {}, { adjustLength: -2 } ); self.popup.populate(popupItem); }, setValue: function (valueItem) { var self = this; var valueArray = []; BI.each(valueItem, function (i, item) { var value; if (BI.isNotNull(item.childValue)) { value = self._createChildValue(item.value, item.childValue); } else { value = item.value; } valueArray.push(value); } ); this.popup.setValue(valueArray); }, getValue: function () { var self = this, result = []; var values = this.popup.getValue(); BI.each(values, function (i, value) { var valueItem = {}; if (BI.isNotNull(self.childValueMap[value])) { var fartherValue = self.fatherValueMap[value]; valueItem.childValue = self.childValueMap[value]; valueItem.value = fartherValue; } else { valueItem.value = value; } result.push(valueItem); }); return result; } }); BI.DownListPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.DownListPopup.EVENT_SON_VALUE_CHANGE = "EVENT_SON_VALUE_CHANGE"; BI.shortcut("bi.down_list_popup", BI.DownListPopup);/** * Created by roy on 15/9/14. */ BI.SearchEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.SearchEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: "bi-search-editor bi-border", height: 24, errorText: "", watermark: BI.i18nText("BI-Basic_Search"), validationChecker: BI.emptyFn, quitChecker: BI.emptyFn }); }, _init: function () { this.options.height -= 2; BI.SearchEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, watermark: o.watermark, allowBlank: true, errorText: o.errorText, validationChecker: o.validationChecker, quitChecker: o.quitChecker }); this.clear = BI.createWidget({ type: "bi.icon_button", stopEvent: true, cls: "search-close-h-font" }); this.clear.on(BI.IconButton.EVENT_CHANGE, function () { self.setValue(""); self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.STOPEDIT); self.fireEvent(BI.SearchEditor.EVENT_CLEAR); }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: { type: "bi.center_adapt", cls: "search-font", items: [{ el: { type: "bi.icon" } }] }, width: 25 }, { el: self.editor }, { el: this.clear, width: 25 } ] }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.SearchEditor.EVENT_FOCUS); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.SearchEditor.EVENT_BLUR); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.SearchEditor.EVENT_CLICK); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self._checkClear(); self.fireEvent(BI.SearchEditor.EVENT_CHANGE); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.SearchEditor.EVENT_KEY_DOWN, v); }); this.editor.on(BI.Editor.EVENT_SPACE, function () { self.fireEvent(BI.SearchEditor.EVENT_SPACE); }); this.editor.on(BI.Editor.EVENT_BACKSPACE, function () { self.fireEvent(BI.SearchEditor.EVENT_BACKSPACE); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.SearchEditor.EVENT_VALID); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self.fireEvent(BI.SearchEditor.EVENT_ERROR); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.SearchEditor.EVENT_ENTER); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.SearchEditor.EVENT_RESTRICT); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self._checkClear(); self.fireEvent(BI.SearchEditor.EVENT_EMPTY); }); this.editor.on(BI.Editor.EVENT_REMOVE, function () { self.fireEvent(BI.SearchEditor.EVENT_REMOVE); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self.fireEvent(BI.SearchEditor.EVENT_CONFIRM); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.SearchEditor.EVENT_START); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.SearchEditor.EVENT_PAUSE); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.SearchEditor.EVENT_STOP); }); this.clear.invisible(); }, _checkClear: function () { if (!this.getValue()) { this.clear.invisible(); } else { this.clear.visible(); } }, focus: function () { this.editor.focus(); }, blur: function () { this.editor.blur(); }, getValue: function () { if (this.isValid()) { var res = this.editor.getValue().match(/[\S]+/g); return BI.isNull(res) ? "" : res[res.length - 1]; } }, getLastValidValue: function () { return this.editor.getLastValidValue(); }, setValue: function (v) { this.editor.setValue(v); if (BI.isKey(v)) { this.clear.visible(); } }, isEditing: function () { return this.editor.isEditing(); }, isValid: function () { return this.editor.isValid(); } }); BI.SearchEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.SearchEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.SearchEditor.EVENT_BLUR = "EVENT_BLUR"; BI.SearchEditor.EVENT_CLICK = "EVENT_CLICK"; BI.SearchEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.SearchEditor.EVENT_SPACE = "EVENT_SPACE"; BI.SearchEditor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; BI.SearchEditor.EVENT_CLEAR = "EVENT_CLEAR"; BI.SearchEditor.EVENT_START = "EVENT_START"; BI.SearchEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.SearchEditor.EVENT_STOP = "EVENT_STOP"; BI.SearchEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.SearchEditor.EVENT_VALID = "EVENT_VALID"; BI.SearchEditor.EVENT_ERROR = "EVENT_ERROR"; BI.SearchEditor.EVENT_ENTER = "EVENT_ENTER"; BI.SearchEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.SearchEditor.EVENT_REMOVE = "EVENT_REMOVE"; BI.SearchEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.search_editor", BI.SearchEditor);/** * 小号搜索框 * Created by GUY on 2015/9/29. * @class BI.SmallSearchEditor * @extends BI.SearchEditor */ BI.SmallSearchEditor = BI.inherit(BI.SearchEditor, { _defaultConfig: function () { var conf = BI.SmallSearchEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-small-search-editor", height: 24 }); }, _init: function () { BI.SmallSearchEditor.superclass._init.apply(this, arguments); } }); BI.shortcut("bi.small_search_editor", BI.SmallSearchEditor);/** * guy * @class BI.TextEditor * @extends BI.Single */ BI.TextEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.TextEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-text-editor bi-border", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: false, watermark: "", errorText: "", height: 24 }); }, _init: function () { BI.TextEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; if (BI.isNumber(o.height)) { this.element.css({height: o.height - 2}); } if (BI.isNumber(o.width)) { this.element.css({width: o.width - 2}); } this.editor = BI.createWidget({ type: "bi.editor", height: o.height - 2, hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, value: o.value, title: o.title, tipType: o.tipType, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_FOCUS, function () { self.fireEvent(BI.TextEditor.EVENT_FOCUS); }); this.editor.on(BI.Editor.EVENT_BLUR, function () { self.fireEvent(BI.TextEditor.EVENT_BLUR); }); this.editor.on(BI.Editor.EVENT_CLICK, function () { self.fireEvent(BI.TextEditor.EVENT_CLICK); }); this.editor.on(BI.Editor.EVENT_CHANGE, function () { self.fireEvent(BI.TextEditor.EVENT_CHANGE); }); this.editor.on(BI.Editor.EVENT_KEY_DOWN, function (v) { self.fireEvent(BI.TextEditor.EVENT_KEY_DOWN); }); this.editor.on(BI.Editor.EVENT_SPACE, function (v) { self.fireEvent(BI.TextEditor.EVENT_SPACE); }); this.editor.on(BI.Editor.EVENT_BACKSPACE, function (v) { self.fireEvent(BI.TextEditor.EVENT_BACKSPACE); }); this.editor.on(BI.Editor.EVENT_VALID, function () { self.fireEvent(BI.TextEditor.EVENT_VALID); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self.fireEvent(BI.TextEditor.EVENT_CONFIRM); }); this.editor.on(BI.Editor.EVENT_REMOVE, function (v) { self.fireEvent(BI.TextEditor.EVENT_REMOVE); }); this.editor.on(BI.Editor.EVENT_START, function () { self.fireEvent(BI.TextEditor.EVENT_START); }); this.editor.on(BI.Editor.EVENT_PAUSE, function () { self.fireEvent(BI.TextEditor.EVENT_PAUSE); }); this.editor.on(BI.Editor.EVENT_STOP, function () { self.fireEvent(BI.TextEditor.EVENT_STOP); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self.fireEvent(BI.TextEditor.EVENT_ERROR, arguments); }); this.editor.on(BI.Editor.EVENT_ENTER, function () { self.fireEvent(BI.TextEditor.EVENT_ENTER); }); this.editor.on(BI.Editor.EVENT_RESTRICT, function () { self.fireEvent(BI.TextEditor.EVENT_RESTRICT); }); this.editor.on(BI.Editor.EVENT_EMPTY, function () { self.fireEvent(BI.TextEditor.EVENT_EMPTY); }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [this.editor] }); }, focus: function () { this.editor.focus(); }, blur: function () { this.editor.blur(); }, setErrorText: function (text) { this.editor.setErrorText(text); }, getErrorText: function () { return this.editor.getErrorText(); }, isValid: function () { return this.editor.isValid(); }, setValue: function (v) { this.editor.setValue(v); }, getValue: function () { return this.editor.getValue(); } }); BI.TextEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.TextEditor.EVENT_FOCUS = "EVENT_FOCUS"; BI.TextEditor.EVENT_BLUR = "EVENT_BLUR"; BI.TextEditor.EVENT_CLICK = "EVENT_CLICK"; BI.TextEditor.EVENT_KEY_DOWN = "EVENT_KEY_DOWN"; BI.TextEditor.EVENT_SPACE = "EVENT_SPACE"; BI.TextEditor.EVENT_BACKSPACE = "EVENT_BACKSPACE"; BI.TextEditor.EVENT_START = "EVENT_START"; BI.TextEditor.EVENT_PAUSE = "EVENT_PAUSE"; BI.TextEditor.EVENT_STOP = "EVENT_STOP"; BI.TextEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.TextEditor.EVENT_VALID = "EVENT_VALID"; BI.TextEditor.EVENT_ERROR = "EVENT_ERROR"; BI.TextEditor.EVENT_ENTER = "EVENT_ENTER"; BI.TextEditor.EVENT_RESTRICT = "EVENT_RESTRICT"; BI.TextEditor.EVENT_REMOVE = "EVENT_REMOVE"; BI.TextEditor.EVENT_EMPTY = "EVENT_EMPTY"; BI.shortcut("bi.text_editor", BI.TextEditor);/** * 小号搜索框 * Created by GUY on 2015/9/29. * @class BI.SmallTextEditor * @extends BI.SearchEditor */ BI.SmallTextEditor = BI.inherit(BI.TextEditor, { _defaultConfig: function () { var conf = BI.SmallTextEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-small-text-editor", height: 25 }); }, _init: function () { BI.SmallTextEditor.superclass._init.apply(this, arguments); } }); BI.shortcut("bi.small_text_editor", BI.SmallTextEditor);/** * 文件管理控件组 * * Created by GUY on 2015/12/11. * @class BI.FileManagerButtonGroup * @extends BI.Widget */ BI.FileManagerButtonGroup = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.FileManagerButtonGroup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-file-manager-button_group", items: [] }); }, _init: function () { BI.FileManagerButtonGroup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.button_group = BI.createWidget({ type: "bi.button_tree", element: this, chooseType: BI.Selection.Multi, items: this._formatItems(o.items), layouts: [{ type: "bi.vertical" }] }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, _formatItems: function (items) { var self = this, o = this.options; BI.each(items, function (i, item) { if (item.children && item.children.length > 0) { item.type = "bi.file_manager_folder_item"; } else { item.type = "bi.file_manager_file_item"; } }); return items; }, setValue: function (v) { this.button_group.setValue(v); }, getValue: function () { return this.button_group.getValue(); }, getNotSelectedValue: function () { return this.button_group.getNotSelectedValue(); }, getAllLeaves: function () { return this.button_group.getAllLeaves(); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, getSelectedButtons: function () { return this.button_group.getSelectedButtons(); }, getNotSelectedButtons: function () { return this.button_group.getNotSelectedButtons(); }, populate: function (items) { this.button_group.populate(this._formatItems(items)); } }); BI.FileManagerButtonGroup.EVENT_CHANGE = "FileManagerButtonGroup.EVENT_CHANGE"; BI.shortcut("bi.file_manager_button_group", BI.FileManagerButtonGroup);/** * 文件管理控件 * * Created by GUY on 2015/12/11. * @class BI.FileManager * @extends BI.Widget */ BI.FileManager = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.FileManager.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-file-manager", el: {}, items: [] }); }, _init: function () { BI.FileManager.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tree = new BI.Tree(); var items = BI.Tree.transformToTreeFormat(o.items); this.tree.initTree(items); this.selectedValues = []; this.nav = BI.createWidget({ type: "bi.file_manager_nav", items: BI.deepClone(items) }); this.nav.on(BI.FileManagerNav.EVENT_CHANGE, function (value, obj) { if (value == "-1") {// 根节点 self.populate({children: self.tree.toJSON()}); } else { var node = self.tree.search(obj.attr("id")); self.populate(BI.extend({id: node.id}, node.get("data"), {children: self.tree.toJSON(node)})); } self.setValue(self.selectedValues); }); this.list = BI.createWidget(o.el, { type: "bi.file_manager_list", items: items }); this.list.on(BI.Controller.EVENT_CHANGE, function (type, selected, obj) { if (type === BI.Events.CHANGE) { var node = self.tree.search(obj.attr("id")); self.populate(BI.extend({id: node.id}, node.get("data"), {children: self.tree.toJSON(node)})); } else if (type === BI.Events.CLICK) { var values = []; if (obj instanceof BI.MultiSelectBar) { var t = self.list.getValue(); selected = t.type === BI.Selection.All; values = BI.concat(t.assist, t.value); } else { values = obj.getAllLeaves(); } BI.each(values, function (i, v) { if (selected === true) { self.selectedValues.pushDistinct(v); } else { self.selectedValues.remove(v); } }); } self.setValue(self.selectedValues); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.list, left: 0, right: 0, top: 0, bottom: 10 }, { el: this.nav, left: 40, right: 100, top: 0 }] }); }, setValue: function (value) { this.selectedValues = value || []; this.list.setValue(this.selectedValues); }, getValue: function () { var obj = this.list.getValue(); var res = obj.type === BI.Selection.All ? obj.assist : obj.value; res.pushDistinctArray(this.selectedValues); return res; }, _populate: function (items) { this.list.populate(items); }, getSelectedValue: function () { return this.nav.getValue()[0]; }, getSelectedId: function () { return this.nav.getId()[0]; }, populate: function (node) { var clone = BI.deepClone(node); this._populate(node.children); this.nav.populate(clone); } }); BI.FileManager.EVENT_CHANGE = "FileManager.EVENT_CHANGE"; BI.shortcut("bi.file_manager", BI.FileManager);/** * 文件管理控件 * * Created by GUY on 2015/12/11. * @class BI.FileManagerFileItem * @extends BI.Single */ BI.FileManagerFileItem = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.FileManagerFileItem.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-file-manager-file-item bi-list-item bi-border-bottom", height: 30 }); }, _init: function () { BI.FileManagerFileItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checked = BI.createWidget({ type: "bi.multi_select_bar", text: "", width: 36, height: o.height }); this.checked.on(BI.Controller.EVENT_CHANGE, function () { arguments[2] = self; self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); BI.createWidget({ type: "bi.htape", element: this, items: [{ el: this.checked, width: 36 }, { el: { type: "bi.icon_button", cls: "create-by-me-file-font" }, width: 20 }, { el: { type: "bi.label", textAlign: "left", height: o.height, text: o.text, value: o.value } }] }); }, getAllLeaves: function () { return [this.options.value]; }, isSelected: function () { return this.checked.isSelected(); }, setSelected: function (v) { this.checked.setSelected(v); } }); BI.FileManagerFileItem.EVENT_CHANGE = "FileManagerFileItem.EVENT_CHANGE"; BI.shortcut("bi.file_manager_file_item", BI.FileManagerFileItem);/** * 文件管理控件 * * Created by GUY on 2015/12/11. * @class BI.FileManagerFolderItem * @extends BI.Single */ BI.FileManagerFolderItem = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.FileManagerFolderItem.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-file-manager-folder-item bi-list-item bi-border-bottom", height: 30 }); }, _init: function () { BI.FileManagerFolderItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checked = BI.createWidget({ type: "bi.multi_select_bar", text: "", width: 36, height: o.height }); this.checked.on(BI.Controller.EVENT_CHANGE, function () { arguments[2] = self; self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button = BI.createWidget({ type: "bi.text_button", textAlign: "left", height: o.height, text: o.text, value: o.value }); this.button.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CHANGE, o.value, self); }); this.tree = new BI.Tree(); this.tree.initTree([{ id: o.id, children: o.children }]); this.selectValue = []; BI.createWidget({ type: "bi.htape", element: this, items: [{ el: this.checked, width: 36 }, { el: { type: "bi.icon_button", cls: "create-by-me-folder-font" }, width: 20 }, { el: this.button }] }); }, setAllSelected: function (v) { this.checked.setSelected(v); this.selectValue = []; }, setHalfSelected: function (v) { this.checked.setHalfSelected(v); if(!v) { this.selectValue = []; } }, setValue: function (v) { var self = this, o = this.options; var isHalf = false; var selectValue = []; this.tree.traverse(function (node) { if (node.isLeaf()) { if (BI.contains(v, node.get("data").value)) { selectValue.push(node.get("data").value); } else { isHalf = true; } } }); this.setAllSelected(selectValue.length > 0 && !isHalf); this.setHalfSelected(selectValue.length > 0 && isHalf); if (this.checked.isHalfSelected()) { this.selectValue = selectValue; } }, getAllButtons: function () { return [this]; }, getAllLeaves: function () { var o = this.options; var res = []; this.tree.traverse(function (node) { if (node.isLeaf()) { res.push(node.get("data").value); } }); return res; }, getNotSelectedValue: function () { var self = this, o = this.options; var res = []; var isAllSelected = this.checked.isSelected(); if (isAllSelected === true) { return res; } var isHalfSelected = this.checked.isHalfSelected(); this.tree.traverse(function (node) { if (node.isLeaf()) { var v = node.get("data").value; if (isHalfSelected === true) { if (!BI.contains(self.selectValue, node.get("data").value)) { res.push(v); } } else { res.push(v); } } }); return res; }, getValue: function () { var res = []; if (this.checked.isSelected()) { this.tree.traverse(function (node) { if (node.isLeaf()) { res.push(node.get("data").value); } }); return res; } if (this.checked.isHalfSelected()) { return this.selectValue; } return []; } }); BI.FileManagerFolderItem.EVENT_CHANGE = "FileManagerFolderItem.EVENT_CHANGE"; BI.shortcut("bi.file_manager_folder_item", BI.FileManagerFolderItem);/** * 文件管理控件列表 * * Created by GUY on 2015/12/11. * @class BI.FileManagerList * @extends BI.Widget */ BI.FileManagerList = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.FileManagerList.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-file-manager-list", el: {}, items: [] }); }, _init: function () { BI.FileManagerList.superclass._init.apply(this, arguments); var self = this, o = this.options; this.list = BI.createWidget({ type: "bi.select_list", element: this, items: o.items, toolbar: { type: "bi.multi_select_bar", height: 40, text: "" }, el: { type: "bi.list_pane", el: BI.isWidget(o.el) ? o.el : BI.extend({ type: "bi.file_manager_button_group" }, o.el) } }); this.list.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, setValue: function (v) { this.list.setValue({ value: v }); }, getValue: function () { return this.list.getValue(); }, populate: function (items) { this.list.populate(items); this.list.setToolBarVisible(true); } }); BI.FileManagerList.EVENT_CHANGE = "FileManagerList.EVENT_CHANGE"; BI.shortcut("bi.file_manager_list", BI.FileManagerList);/** * 文件管理导航按钮 * * Created by GUY on 2015/12/11. * @class BI.FileManagerNavButton * @extends BI.Widget */ BI.FileManagerNavButton = BI.inherit(BI.Widget, { _const: { normal_color: "#ffffff", select_color: "#eff1f4" }, _defaultConfig: function () { return BI.extend(BI.FileManagerNavButton.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-file-manager-nav-button", selected: false, height: 40 }); }, _init: function () { BI.FileManagerNavButton.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.button = BI.createWidget({ type: "bi.text_button", cls: "file-manager-nav-button-text bi-card", once: true, selected: o.selected, text: o.text, title: o.text, value: o.value, height: o.height, lgap: 20, rgap: 10 }); this.button.on(BI.Controller.EVENT_CHANGE, function () { arguments[2] = self; self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var svg = BI.createWidget({ type: "bi.svg", cls: "file-manager-nav-button-triangle", width: 15, height: o.height }); var path = svg.path("M0,0L15,20L0,40").attr({ stroke: c.select_color, fill: o.selected ? c.select_color : c.normal_color }); this.button.on(BI.TextButton.EVENT_CHANGE, function () { if (this.isSelected()) { path.attr("fill", c.select_color); } else { path.attr("fill", c.normal_color); } }); BI.createWidget({ type: "bi.default", element: this, items: [this.button] }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: svg, right: -15, top: 0, bottom: 0 }] }); }, isSelected: function () { return this.button.isSelected(); }, setValue: function (v) { this.button.setValue(v); }, getValue: function () { return this.button.getValue(); }, populate: function (items) { } }); BI.FileManagerNavButton.EVENT_CHANGE = "FileManagerNavButton.EVENT_CHANGE"; BI.shortcut("bi.file_manager_nav_button", BI.FileManagerNavButton);/** * 文件管理导航 * * Created by GUY on 2015/12/11. * @class BI.FileManagerNav * @extends BI.Widget */ BI.FileManagerNav = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.FileManagerNav.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-file-manager-nav bi-border-left", height: 40, items: [] }); }, _init: function () { BI.FileManagerNav.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tree = new BI.Tree(); this.refreshTreeData(o.items); this.tree.getRoot().set("data", { text: BI.i18nText("BI-Created_By_Me"), value: BI.FileManagerNav.ROOT_CREATE_BY_ME, id: BI.FileManagerNav.ROOT_CREATE_BY_ME }); this.button_group = BI.createWidget({ type: "bi.button_group", element: this, items: [{ type: "bi.file_manager_nav_button", text: BI.i18nText("BI-Created_By_Me"), selected: true, id: BI.FileManagerNav.ROOT_CREATE_BY_ME, value: BI.FileManagerNav.ROOT_CREATE_BY_ME }], layouts: [{ type: "bi.horizontal" }] }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button_group.on(BI.ButtonGroup.EVENT_CHANGE, function (value, obj) { self.fireEvent(BI.FileManagerNav.EVENT_CHANGE, arguments); }); }, _getAllParents: function (id) { var node, res = []; if (!id) { node = this.tree.getRoot(); } else { node = this.tree.search(id); } while (node.parent) { res.push(node); node = node.parent; } res.push(node); return res.reverse(); }, _formatNodes: function (nodes) { var res = []; BI.each(nodes, function (i, node) { res.push(BI.extend({ type: "bi.file_manager_nav_button", id: node.id }, node.get("data"))); }); BI.last(res).selected = true; return res; }, getValue: function () { return this.button_group.getValue(); }, getId: function () { var ids = []; BI.each(this.button_group.getSelectedButtons(), function (i, btn) { ids.push(btn.attr("id")); }); return ids; }, refreshTreeData: function (items) { this.tree.initTree(BI.Tree.transformToTreeFormat(items)); this.tree.getRoot().set("data", { text: BI.i18nText("BI-Created_By_Me"), value: BI.FileManagerNav.ROOT_CREATE_BY_ME, id: BI.FileManagerNav.ROOT_CREATE_BY_ME }); }, populate: function (node) { var parents = BI.isNull(node) ? [this.tree.getRoot()] : this._getAllParents(node.id); this.button_group.populate(this._formatNodes(parents)); } }); BI.extend(BI.FileManagerNav, { ROOT_CREATE_BY_ME: "-1" }); BI.FileManagerNav.EVENT_CHANGE = "FileManagerNav.EVENT_CHANGE"; BI.shortcut("bi.file_manager_nav", BI.FileManagerNav);/** * 交互行为布局 * * * Created by GUY on 2016/7/23. * @class BI.InteractiveArrangement * @extends BI.Widget */ BI.InteractiveArrangement = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.InteractiveArrangement.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-interactive-arrangement", resizable: true, layoutType: BI.Arrangement.LAYOUT_TYPE.GRID, items: [] }); }, _init: function () { BI.InteractiveArrangement.superclass._init.apply(this, arguments); var self = this, o = this.options; this.arrangement = BI.createWidget({ type: "bi.adaptive_arrangement", element: this, resizable: o.resizable, layoutType: o.layoutType, items: o.items }); this.arrangement.on(BI.AdaptiveArrangement.EVENT_SCROLL, function () { self.fireEvent(BI.InteractiveArrangement.EVENT_SCROLL, arguments); }); this.arrangement.on(BI.AdaptiveArrangement.EVENT_RESIZE, function () { self.fireEvent(BI.InteractiveArrangement.EVENT_RESIZE, arguments); }); this.arrangement.on(BI.AdaptiveArrangement.EVENT_ELEMENT_RESIZE, function (id, size) { var p = self._getRegionClientPosition(id); self.draw({ left: p.left, top: p.top }, size, id); }); this.arrangement.on(BI.AdaptiveArrangement.EVENT_ELEMENT_STOP_RESIZE, function (id, size) { self.stopDraw(); self.setRegionSize(id, size); }); this.tags = []; }, _isEqual: function (num1, num2) { return this.arrangement._isEqual(num1, num2); }, _getScrollOffset: function () { return this.arrangement._getScrollOffset(); }, _positionAt: function (position, regions) { var self = this; regions = regions || this.getAllRegions(); var left = [], center = [], right = [], top = [], middle = [], bottom = []; BI.each(regions, function (i, region) { var client = self._getRegionClientPosition(region.id); if (Math.abs(client.left - position.left) <= 3) { left.push(region); } if (Math.abs(client.left + client.width / 2 - position.left) <= 3) { center.push(region); } if (Math.abs(client.left + client.width - position.left) <= 3) { right.push(region); } if (Math.abs(client.top - position.top) <= 3) { top.push(region); } if (Math.abs(client.top + client.height / 2 - position.top) <= 3) { middle.push(region); } if (Math.abs(client.top + client.height - position.top) <= 3) { bottom.push(region); } }); return { left: left, center: center, right: right, top: top, middle: middle, bottom: bottom }; }, _getRegionClientPosition: function (name) { var region = this.getRegionByName(name); var offset = this.arrangement._getScrollOffset(); return { top: region.top - offset.top, left: region.left - offset.left, width: region.width, height: region.height, id: region.id }; }, _vAlign: function (position, regions) { var self = this; var vs = this._positionAt(position, regions); var positions = []; var l; if (vs.left.length > 0) { l = this._getRegionClientPosition(vs.left[0].id).left; } else if (vs.right.length > 0) { var temp = this._getRegionClientPosition(vs.right[0].id); l = temp.left + temp.width; } else if (vs.center.length > 0) { var temp = this._getRegionClientPosition(vs.center[0].id); l = temp.left + temp.width / 2; } var rs = vs.left.concat(vs.right).concat(vs.center); BI.each(rs, function (i, region) { var p = self._getRegionClientPosition(region.id); if (self._isEqual(p.left, l) || self._isEqual(p.left + p.width, l) || self._isEqual(p.left + p.width / 2, l)) { var topPoint = { top: p.top + p.height / 2, left: l }; positions.push({ id: region.id, start: topPoint, end: { left: l, top: position.top } }); } }); return positions; }, _leftAlign: function (position, size, regions) { var self = this; return this._vAlign({ left: position.left, top: position.top + size.height / 2 }, regions); }, _rightAlign: function (position, size, regions) { var self = this; return this._vAlign({ left: position.left + size.width, top: position.top + size.height / 2 }, regions); }, _hAlign: function (position, regions) { var self = this; var hs = this._positionAt(position, regions); var positions = []; var t; if (hs.top.length > 0) { var temp = this._getRegionClientPosition(hs.top[0].id); t = temp.top; } else if (hs.bottom.length > 0) { var temp = this._getRegionClientPosition(hs.bottom[0].id); t = temp.top + temp.height; } else if (hs.middle.length > 0) { var temp = this._getRegionClientPosition(hs.middle[0].id); t = temp.top + temp.height / 2; } var rs = hs.top.concat(hs.bottom).concat(hs.middle); BI.each(rs, function (i, region) { var p = self._getRegionClientPosition(region.id); if (self._isEqual(p.top, t) || self._isEqual(p.top + p.height, t) || self._isEqual(p.top + p.height / 2, t)) { var leftPoint = { top: t, left: p.left + p.width / 2 }; positions.push({ id: p.id, start: leftPoint, end: { left: position.left, top: t } }); } }); return positions; }, _topAlign: function (position, size, regions) { var self = this; return this._hAlign({ left: position.left + size.width / 2, top: position.top }, regions); }, _bottomAlign: function (position, size, regions) { var self = this; return this._hAlign({ left: position.left + size.width / 2, top: position.top + size.height }, regions); }, _centerAlign: function (position, size, regions) { var self = this; return this._vAlign({ left: position.left + size.width / 2, top: position.top + size.height / 2 }, regions); }, _middleAlign: function (position, size, regions) { var self = this; return this._hAlign({ left: position.left + size.width / 2, top: position.top + size.height / 2 }, regions); }, _drawOneTag: function (start, end) { var s = BI.createWidget({ type: "bi.icon_button", // invisible: true, width: 13, height: 13, cls: "drag-tag-font interactive-arrangement-dragtag-icon" }); var e = BI.createWidget({ type: "bi.icon_button", // invisible: true, width: 13, height: 13, cls: "drag-tag-font interactive-arrangement-dragtag-icon" }); if (this._isEqual(start.left, end.left)) { var line = BI.createWidget({ type: "bi.layout", // invisible: true, cls: "interactive-arrangement-dragtag-line", width: 1, height: Math.abs(start.top - end.top) }); } else { var line = BI.createWidget({ type: "bi.layout", // invisible: true, cls: "interactive-arrangement-dragtag-line", height: 1, width: Math.abs(start.left - end.left) }); } BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: s, left: start.left - 6, top: start.top - 7 }, { el: e, left: end.left - 6, top: end.top - 7 }, { el: line, left: Math.min(start.left, end.left), top: Math.min(start.top, end.top) }] }); this.tags.push(s); this.tags.push(e); this.tags.push(line); }, stopDraw: function () { BI.each(this.tags, function (i, w) { w.destroy(); }); this.tags = []; }, _getRegionExcept: function (name, regions) { var other = []; BI.each(regions || this.getAllRegions(), function (i, region) { if (!(name && region.id === name)) { other.push(region); } }); return other; }, getClientWidth: function () { return this.arrangement.getClientWidth(); }, getClientHeight: function () { return this.arrangement.getClientHeight(); }, getPosition: function (name, position, size) { var regions = this.getAllRegions(); var me; if (name) { me = this._getRegionClientPosition(name); } var other = this._getRegionExcept(name, regions); position = position || { left: me.left, top: me.top }; size = size || { width: me.width, height: me.height }; var left = this._leftAlign(position, size, other); var right = this._rightAlign(position, size, other); var top = this._topAlign(position, size, other, other); var bottom = this._bottomAlign(position, size, other); var center = this._centerAlign(position, size, other); var middle = this._middleAlign(position, size, other); BI.each(center, function (i, pos) { position.left = pos.end.left - size.width / 2; }); BI.each(right, function (i, pos) { position.left = pos.end.left - size.width; }); BI.each(left, function (i, pos) { position.left = pos.end.left; }); BI.each(middle, function (i, pos) { position.top = pos.end.top - size.height / 2; }); BI.each(bottom, function (i, pos) { position.top = pos.end.top - size.height; }); BI.each(top, function (i, pos) { position.top = pos.end.top; }); return position; }, // position不动 变size getSize: function (name, position, size) { var regions = this.getAllRegions(); var me; if (name) { me = this._getRegionClientPosition(name); } var other = this._getRegionExcept(name, regions); position = position || { left: me.left, top: me.top }; size = size || { width: me.width, height: me.height }; var left = this._leftAlign(position, size, other); var right = this._rightAlign(position, size, other); var top = this._topAlign(position, size, other, other); var bottom = this._bottomAlign(position, size, other); var center = this._centerAlign(position, size, other); var middle = this._middleAlign(position, size, other); BI.each(center, function (i, pos) { size.width = (pos.end.left - position.left) * 2; }); BI.each(right, function (i, pos) { size.width = pos.end.left - position.left; }); BI.each(left, function (i, pos) { }); BI.each(middle, function (i, pos) { size.height = (pos.end.top - position.top) * 2; }); BI.each(bottom, function (i, pos) { size.height = pos.end.top - position.top; }); BI.each(top, function (i, pos) { }); return size; }, draw: function (position, size, name) { var self = this; this.stopDraw(); switch (this.getLayoutType()) { case BI.Arrangement.LAYOUT_TYPE.FREE: var other = this._getRegionExcept(name); var left = this._leftAlign(position, size, other); var right = this._rightAlign(position, size, other); var top = this._topAlign(position, size, other); var bottom = this._bottomAlign(position, size, other); var center = this._centerAlign(position, size, other); var middle = this._middleAlign(position, size, other); BI.each(center, function (i, pos) { self._drawOneTag(pos.start, pos.end); }); BI.each(right, function (i, pos) { self._drawOneTag(pos.start, pos.end); }); BI.each(left, function (i, pos) { self._drawOneTag(pos.start, pos.end); }); BI.each(middle, function (i, pos) { self._drawOneTag(pos.start, pos.end); }); BI.each(bottom, function (i, pos) { self._drawOneTag(pos.start, pos.end); }); BI.each(top, function (i, pos) { self._drawOneTag(pos.start, pos.end); }); break; case BI.Arrangement.LAYOUT_TYPE.GRID: break; } }, addRegion: function (region, position) { this.stopDraw(); return this.arrangement.addRegion(region, position); }, deleteRegion: function (name) { return this.arrangement.deleteRegion(name); }, setRegionSize: function (name, size) { size = this.getSize(name, null, size); return this.arrangement.setRegionSize(name, size); }, setPosition: function (position, size) { var self = this; this.stopDraw(); if (position.left > 0 && position.top > 0) { switch (this.getLayoutType()) { case BI.Arrangement.LAYOUT_TYPE.FREE: position = this.getPosition(null, position, size); this.draw(position, size); break; case BI.Arrangement.LAYOUT_TYPE.GRID: break; } } var at = this.arrangement.setPosition(position, size); return at; }, setRegionPosition: function (name, position) { if (position.left > 0 && position.top > 0) { switch (this.getLayoutType()) { case BI.Arrangement.LAYOUT_TYPE.FREE: position = this.getPosition(name, position); break; case BI.Arrangement.LAYOUT_TYPE.GRID: break; } } return this.arrangement.setRegionPosition(name, position); }, setDropPosition: function (position, size) { var self = this; this.stopDraw(); if (position.left > 0 && position.top > 0) { switch (this.getLayoutType()) { case BI.Arrangement.LAYOUT_TYPE.FREE: position = this.getPosition(null, position, size); this.draw(position, size); break; case BI.Arrangement.LAYOUT_TYPE.GRID: break; } } var callback = self.arrangement.setDropPosition(position, size); return function () { callback(); self.stopDraw(); }; }, scrollInterval: function () { this.arrangement.scrollInterval.apply(this.arrangement, arguments); }, scrollEnd: function () { this.arrangement.scrollEnd.apply(this.arrangement, arguments); }, scrollTo: function (scroll) { this.arrangement.scrollTo(scroll); }, zoom: function (ratio) { this.arrangement.zoom(ratio); }, resize: function () { return this.arrangement.resize(); }, relayout: function () { return this.arrangement.relayout(); }, setLayoutType: function (type) { this.arrangement.setLayoutType(type); }, getLayoutType: function () { return this.arrangement.getLayoutType(); }, getLayoutRatio: function () { return this.arrangement.getLayoutRatio(); }, getHelper: function () { return this.arrangement.getHelper(); }, getRegionByName: function (name) { return this.arrangement.getRegionByName(name); }, getAllRegions: function () { return this.arrangement.getAllRegions(); }, revoke: function () { return this.arrangement.revoke(); }, populate: function (items) { var self = this; this.arrangement.populate(items); } }); BI.InteractiveArrangement.EVENT_RESIZE = "InteractiveArrangement.EVENT_RESIZE"; BI.InteractiveArrangement.EVENT_SCROLL = "InteractiveArrangement.EVENT_SCROLL"; BI.shortcut("bi.interactive_arrangement", BI.InteractiveArrangement);/** * Created by zcf on 2016/9/26. */ BI.IntervalSlider = BI.inherit(BI.Widget, { _constant: { EDITOR_WIDTH: 58, EDITOR_R_GAP: 60, EDITOR_HEIGHT: 30, SLIDER_WIDTH_HALF: 15, SLIDER_WIDTH: 30, SLIDER_HEIGHT: 30, TRACK_HEIGHT: 24 }, _defaultConfig: function () { return BI.extend(BI.IntervalSlider.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-interval-slider bi-slider-track", digit: false, unit: "" }); }, _init: function () { BI.IntervalSlider.superclass._init.apply(this, arguments); var self = this; var c = this._constant; this.enable = false; this.valueOne = ""; this.valueTwo = ""; this.calculation = new BI.AccurateCalculationModel(); // this.backgroundTrack = BI.createWidget({ // type: "bi.layout", // cls: "background-track", // height: c.TRACK_HEIGHT // }); this.grayTrack = BI.createWidget({ type: "bi.layout", cls: "gray-track", height: 6 }); this.blueTrack = BI.createWidget({ type: "bi.layout", cls: "blue-track bi-high-light-background", height: 6 }); this.track = this._createTrackWrapper(); this.labelOne = BI.createWidget({ type: "bi.sign_text_editor", cls: "slider-editor-button", text: this.options.unit, errorText: "", allowBlank: false, width: c.EDITOR_WIDTH, validationChecker: function (v) { return self._checkValidation(v); } }); this.labelOne.element.hover(function () { self.labelOne.element.removeClass("bi-border").addClass("bi-border"); }, function () { self.labelOne.element.removeClass("bi-border"); }); this.labelOne.on(BI.Editor.EVENT_CONFIRM, function () { var v = BI.parseFloat(this.getValue()); self.valueOne = v; var percent = self._getPercentByValue(v); var significantPercent = BI.parseFloat(percent.toFixed(1));// 分成1000份 self._setLabelOnePosition(significantPercent); self._setSliderOnePosition(significantPercent); self._setBlueTrack(); self.fireEvent(BI.IntervalSlider.EVENT_CHANGE); }); this.labelTwo = BI.createWidget({ type: "bi.sign_text_editor", cls: "slider-editor-button", errorText: "", text: this.options.unit, allowBlank: false, width: c.EDITOR_WIDTH, validationChecker: function (v) { return self._checkValidation(v); } }); this.labelTwo.element.hover(function () { self.labelTwo.element.removeClass("bi-border").addClass("bi-border"); }, function () { self.labelTwo.element.removeClass("bi-border"); }); this.labelTwo.on(BI.Editor.EVENT_CONFIRM, function () { var v = BI.parseFloat(this.getValue()); self.valueTwo = v; var percent = self._getPercentByValue(v); var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setLabelTwoPosition(significantPercent); self._setSliderTwoPosition(significantPercent); self._setBlueTrack(); self.fireEvent(BI.IntervalSlider.EVENT_CHANGE); }); this.sliderOne = BI.createWidget({ type: "bi.single_slider_button" }); this.sliderTwo = BI.createWidget({ type: "bi.single_slider_button" }); this._draggable(this.sliderOne, true); this._draggable(this.sliderTwo, false); this._setVisible(false); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.track, width: "100%", height: c.TRACK_HEIGHT }] }], hgap: 7, height: c.TRACK_HEIGHT }, top: 23, left: 0, width: "100%" }, this._createLabelWrapper(), this._createSliderWrapper() ] }); }, _rePosBySizeAfterMove: function (size, isLeft) { var o = this.options; var percent = size * 100 / (this._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1)); var v = this._getValueByPercent(significantPercent); v = this._assertValue(v); v = o.digit === false ? v : v.toFixed(o.digit); if(isLeft) { this._setLabelOnePosition(significantPercent); this._setSliderOnePosition(significantPercent); this.labelOne.setValue(v); this.valueOne = v; }else{ this._setLabelTwoPosition(significantPercent); this._setSliderTwoPosition(significantPercent); this.labelTwo.setValue(v); this.valueTwo = v; } this._setBlueTrack(); }, _rePosBySizeAfterStop: function (size, isLeft) { var percent = size * 100 / (this._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1)); isLeft ? this._setSliderOnePosition(significantPercent) : this._setSliderTwoPosition(significantPercent); }, _draggable: function (widget, isLeft) { var self = this, o = this.options; var startDrag = false; var size = 0, offset = 0, defaultSize = 0; var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { if (mouseMoveTracker.isDragging()) { startDrag = true; offset += deltaX; size = optimizeSize(defaultSize + offset); widget.element.addClass("dragging"); self._rePosBySizeAfterMove(size, isLeft); } }, function () { if (startDrag === true) { size = optimizeSize(size); self._rePosBySizeAfterStop(size, isLeft); size = 0; offset = 0; defaultSize = size; startDrag = false; } widget.element.removeClass("dragging"); mouseMoveTracker.releaseMouseMoves(); self.fireEvent(BI.IntervalSlider.EVENT_CHANGE); }, document); widget.element.on("mousedown", function (event) { if(!widget.isEnabled()) { return; } defaultSize = this.offsetLeft; optimizeSize(defaultSize); mouseMoveTracker.captureMouseMoves(event); }); function optimizeSize (s) { return BI.clamp(s, 0, self._getGrayTrackLength()); } }, _createLabelWrapper: function () { var c = this._constant; return { el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.labelOne, top: 0, left: "0%" }] }, { type: "bi.absolute", items: [{ el: this.labelTwo, top: 0, left: "100%" }] }], rgap: c.EDITOR_R_GAP, height: 70 }, top: 0, left: 0, width: "100%" }; }, _createSliderWrapper: function () { var c = this._constant; return { el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.sliderOne, top: 0, left: "0%" }] }, { type: "bi.absolute", items: [{ el: this.sliderTwo, top: 0, left: "100%" }] }], hgap: c.SLIDER_WIDTH_HALF, height: c.SLIDER_HEIGHT }, top: 20, left: 0, width: "100%" }; }, _createTrackWrapper: function () { return BI.createWidget({ type: "bi.absolute", items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.grayTrack, top: 0, left: 0, width: "100%" }, { el: this.blueTrack, top: 0, left: 0, width: "0%" }] }], hgap: 8, height: 8 }, top: 8, left: 0, width: "100%" }] }); }, _checkValidation: function (v) { var o = this.options; var valid = false; // 像90.这样的既不属于整数又不属于小数,是不合法的值 var dotText = (v + "").split(".")[1]; if (BI.isEmptyString(dotText)) { }else{ if (BI.isNumeric(v) && !(BI.isNull(v) || v < this.min || v > this.max)) { if(o.digit === false) { valid = true; }else{ dotText = dotText || ""; valid = (dotText.length === o.digit); } } } return valid; }, _checkOverlap: function () { var labelOneLeft = this.labelOne.element[0].offsetLeft; var labelTwoLeft = this.labelTwo.element[0].offsetLeft; if (labelOneLeft <= labelTwoLeft) { if ((labelTwoLeft - labelOneLeft) < 90) { this.labelTwo.element.css({top: 40}); } else { this.labelTwo.element.css({top: 0}); } } else { if ((labelOneLeft - labelTwoLeft) < 90) { this.labelTwo.element.css({top: 40}); } else { this.labelTwo.element.css({top: 0}); } } }, _setLabelOnePosition: function (percent) { this.labelOne.element.css({left: percent + "%"}); this._checkOverlap(); }, _setLabelTwoPosition: function (percent) { this.labelTwo.element.css({left: percent + "%"}); this._checkOverlap(); }, _setSliderOnePosition: function (percent) { this.sliderOne.element.css({left: percent + "%"}); }, _setSliderTwoPosition: function (percent) { this.sliderTwo.element.css({left: percent + "%"}); }, _setBlueTrackLeft: function (percent) { this.blueTrack.element.css({left: percent + "%"}); }, _setBlueTrackWidth: function (percent) { this.blueTrack.element.css({width: percent + "%"}); }, _setBlueTrack: function () { var percentOne = this._getPercentByValue(this.labelOne.getValue()); var percentTwo = this._getPercentByValue(this.labelTwo.getValue()); if (percentOne <= percentTwo) { this._setBlueTrackLeft(percentOne); this._setBlueTrackWidth(percentTwo - percentOne); } else { this._setBlueTrackLeft(percentTwo); this._setBlueTrackWidth(percentOne - percentTwo); } }, _setAllPosition: function (one, two) { this._setSliderOnePosition(one); this._setLabelOnePosition(one); this._setSliderTwoPosition(two); this._setLabelTwoPosition(two); this._setBlueTrack(); }, _setVisible: function (visible) { this.sliderOne.setVisible(visible); this.sliderTwo.setVisible(visible); this.labelOne.setVisible(visible); this.labelTwo.setVisible(visible); }, _setErrorText: function () { var errorText = BI.i18nText("BI-Please_Enter") + this.min + "-" + this.max + BI.i18nText("BI-Basic_De") + BI.i18nText("BI-Basic_Number"); this.labelOne.setErrorText(errorText); this.labelTwo.setErrorText(errorText); }, _getGrayTrackLength: function () { return this.grayTrack.element[0].scrollWidth; }, // 其中取max-min后保留4为有效数字后的值的小数位数为最终value的精度 _getValueByPercent: function (percent) {// return (((max-min)*percent)/100+min) var sub = this.calculation.accurateSubtraction(this.max, this.min); var mul = this.calculation.accurateMultiplication(sub, percent); var div = this.calculation.accurateDivisionTenExponent(mul, 2); if(this.precision < 0) { var value = BI.parseFloat(this.calculation.accurateAddition(div, this.min)); var reduceValue = Math.round(this.calculation.accurateDivisionTenExponent(value, -this.precision)); return this.calculation.accurateMultiplication(reduceValue, Math.pow(10, -this.precision)); } return BI.parseFloat(this.calculation.accurateAddition(div, this.min).toFixed(this.precision)); }, _getPercentByValue: function (v) { return (v - this.min) * 100 / (this.max - this.min); }, _setDraggableEnable: function (enable) { this.sliderOne.setEnable(enable); this.sliderTwo.setEnable(enable); }, _getPrecision: function () { // 计算每一份值的精度(最大值和最小值的差值保留4为有效数字后的精度) // 如果差值的整数位数大于4,toPrecision(4)得到的是科学计数法123456 => 1.235e+5 // 返回非负值: 保留的小数位数 // 返回负值: 保留的10^n精度中的n var sub = this.calculation.accurateSubtraction(this.max, this.min); var pre = sub.toPrecision(4); // 科学计数法 var eIndex = pre.indexOf("e"); var arr = []; if(eIndex > -1) { arr = pre.split("e"); var decimalPartLength = BI.size(arr[0].split(".")[1]); var sciencePartLength = BI.parseInt(arr[1].substring(1)); return decimalPartLength - sciencePartLength; } arr = pre.split("."); return arr.length > 1 ? arr[1].length : 0; }, _assertValue: function (value) { if(value <= this.min) { return this.min; } if(value >= this.max) { return this.max; } return value; }, getValue: function () { if (this.valueOne <= this.valueTwo) { return {min: this.valueOne, max: this.valueTwo}; } return {min: this.valueTwo, max: this.valueOne}; }, setMinAndMax: function (v) { var minNumber = BI.parseFloat(v.min); var maxNumber = BI.parseFloat(v.max); if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber >= minNumber )) { this.min = minNumber; this.max = maxNumber; this.valueOne = minNumber; this.valueTwo = maxNumber; this.precision = this._getPrecision(); this._setDraggableEnable(true); } if (maxNumber === minNumber) { this._setDraggableEnable(false); } }, setValue: function (v) { var o = this.options; var valueOne = BI.parseFloat(v.min); var valueTwo = BI.parseFloat(v.max); valueOne = o.digit === false ? valueOne : valueOne.toFixed(o.digit); valueTwo = o.digit === false ? valueTwo : valueTwo.toFixed(o.digit); if (!isNaN(valueOne) && !isNaN(valueTwo)) { if (this._checkValidation(valueOne)) { this.valueOne = valueOne; } if (this._checkValidation(valueTwo)) { this.valueTwo = valueTwo; } if (valueOne < this.min) { this.valueOne = this.min; } if (valueTwo > this.max) { this.valueTwo = this.max; } } }, reset: function () { this._setVisible(false); this.enable = false; this.valueOne = ""; this.valueTwo = ""; this.min = NaN; this.max = NaN; this._setBlueTrackWidth(0); }, populate: function () { if (!isNaN(this.min) && !isNaN(this.max)) { this.enable = true; this._setVisible(true); this._setErrorText(); if ((BI.isNumeric(this.valueOne) || BI.isNotEmptyString(this.valueOne)) && (BI.isNumeric(this.valueTwo) || BI.isNotEmptyString(this.valueTwo))) { this.labelOne.setValue(this.valueOne); this.labelTwo.setValue(this.valueTwo); this._setAllPosition(this._getPercentByValue(this.valueOne), this._getPercentByValue(this.valueTwo)); } else { this.labelOne.setValue(this.min); this.labelTwo.setValue(this.max); this._setAllPosition(0, 100); } } } }); BI.IntervalSlider.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.interval_slider", BI.IntervalSlider);/** * Created by zcf on 2017/3/1. * 万恶的IEEE-754 * 使用字符串精确计算含小数加法、减法、乘法和10的指数倍除法,支持负数 */ BI.AccurateCalculationModel = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.AccurateCalculationModel.superclass._defaultConfig.apply(this, arguments), { baseCls: "" }); }, _init: function () { BI.AccurateCalculationModel.superclass._init.apply(this, arguments); }, _getMagnitude: function (n) { var magnitude = "1"; for (var i = 0; i < n; i++) { magnitude += "0"; } return BI.parseInt(magnitude); }, _formatDecimal: function (stringNumber1, stringNumber2) { if (stringNumber1.numDecimalLength === stringNumber2.numDecimalLength) { return; } var magnitudeDiff = stringNumber1.numDecimalLength - stringNumber2.numDecimalLength; if (magnitudeDiff > 0) { var needAddZero = stringNumber2; } else { var needAddZero = stringNumber1; magnitudeDiff = (0 - magnitudeDiff); } for (var i = 0; i < magnitudeDiff; i++) { if (needAddZero.numDecimal === "0" && i === 0) { continue; } needAddZero.numDecimal += "0"; } }, _stringNumberFactory: function (num) { var strNum = num.toString(); var numStrArray = strNum.split("."); var numInteger = numStrArray[0]; if (numStrArray.length === 1) { var numDecimal = "0"; var numDecimalLength = 0; } else { var numDecimal = numStrArray[1]; var numDecimalLength = numStrArray[1].length; } return { numInteger: numInteger, numDecimal: numDecimal, numDecimalLength: numDecimalLength }; }, _accurateSubtraction: function (num1, num2) {// num1-num2 && num1>num2 var stringNumber1 = this._stringNumberFactory(num1); var stringNumber2 = this._stringNumberFactory(num2); // 整数部分计算 var integerResult = BI.parseInt(stringNumber1.numInteger) - BI.parseInt(stringNumber2.numInteger); // 小数部分 this._formatDecimal(stringNumber1, stringNumber2); var decimalMaxLength = getDecimalMaxLength(stringNumber1, stringNumber2); if (BI.parseInt(stringNumber1.numDecimal) >= BI.parseInt(stringNumber2.numDecimal)) { var decimalResultTemp = (BI.parseInt(stringNumber1.numDecimal) - BI.parseInt(stringNumber2.numDecimal)).toString(); var decimalResult = addZero(decimalResultTemp, decimalMaxLength); } else {// 否则借位 integerResult--; var borrow = this._getMagnitude(decimalMaxLength); var decimalResultTemp = (borrow + BI.parseInt(stringNumber1.numDecimal) - BI.parseInt(stringNumber2.numDecimal)).toString(); var decimalResult = addZero(decimalResultTemp, decimalMaxLength); } var result = integerResult + "." + decimalResult; return BI.parseFloat(result); function getDecimalMaxLength (num1, num2) { if (num1.numDecimal.length >= num2.numDecimal.length) { return num1.numDecimal.length; } return num2.numDecimal.length; } function addZero (resultTemp, length) { var diff = length - resultTemp.length; for (var i = 0; i < diff; i++) { resultTemp = "0" + resultTemp; } return resultTemp; } }, _accurateAddition: function (num1, num2) {// 加法结合律 var stringNumber1 = this._stringNumberFactory(num1); var stringNumber2 = this._stringNumberFactory(num2); // 整数部分计算 var integerResult = BI.parseInt(stringNumber1.numInteger) + BI.parseInt(stringNumber2.numInteger); // 小数部分 this._formatDecimal(stringNumber1, stringNumber2); var decimalResult = (BI.parseInt(stringNumber1.numDecimal) + BI.parseInt(stringNumber2.numDecimal)).toString(); if (decimalResult !== "0") { if (decimalResult.length <= stringNumber1.numDecimal.length) { decimalResult = addZero(decimalResult, stringNumber1.numDecimal.length); } else { integerResult++;// 进一 decimalResult = decimalResult.slice(1); } } var result = integerResult + "." + decimalResult; return BI.parseFloat(result); function addZero (resultTemp, length) { var diff = length - resultTemp.length; for (var i = 0; i < diff; i++) { resultTemp = "0" + resultTemp; } return resultTemp; } }, _accurateMultiplication: function (num1, num2) {// 乘法分配律 var stringNumber1 = this._stringNumberFactory(num1); var stringNumber2 = this._stringNumberFactory(num2); // 整数部分计算 var integerResult = BI.parseInt(stringNumber1.numInteger) * BI.parseInt(stringNumber2.numInteger); // num1的小数和num2的整数 var dec1Int2 = this._accurateDivisionTenExponent(BI.parseInt(stringNumber1.numDecimal) * BI.parseInt(stringNumber2.numInteger), stringNumber1.numDecimalLength); // num1的整数和num2的小数 var int1dec2 = this._accurateDivisionTenExponent(BI.parseInt(stringNumber1.numInteger) * BI.parseInt(stringNumber2.numDecimal), stringNumber2.numDecimalLength); // 小数*小数 var dec1dec2 = this._accurateDivisionTenExponent(BI.parseInt(stringNumber1.numDecimal) * BI.parseInt(stringNumber2.numDecimal), (stringNumber1.numDecimalLength + stringNumber2.numDecimalLength)); return this._accurateAddition(this._accurateAddition(this._accurateAddition(integerResult, dec1Int2), int1dec2), dec1dec2); }, _accurateDivisionTenExponent: function (num, n) {// num/10^n && n>0 var stringNumber = this._stringNumberFactory(num); if (stringNumber.numInteger.length > n) { var integerResult = stringNumber.numInteger.slice(0, (stringNumber.numInteger.length - n)); var partDecimalResult = stringNumber.numInteger.slice(-n); } else { var integerResult = "0"; var partDecimalResult = addZero(stringNumber.numInteger, n); } var result = integerResult + "." + partDecimalResult + stringNumber.numDecimal; return BI.parseFloat(result); function addZero (resultTemp, length) { var diff = length - resultTemp.length; for (var i = 0; i < diff; i++) { resultTemp = "0" + resultTemp; } return resultTemp; } }, accurateSubtraction: function (num1, num2) { if (num1 >= 0 && num2 >= 0) { if (num1 >= num2) { return this._accurateSubtraction(num1, num2); } return -this._accurateSubtraction(num2, num1); } if (num1 >= 0 && num2 < 0) { return this._accurateAddition(num1, -num2); } if (num1 < 0 && num2 >= 0) { return -this._accurateAddition(-num1, num2); } if (num1 < 0 && num2 < 0) { if (num1 >= num2) { return this._accurateSubtraction(-num2, -num1); } return this._accurateSubtraction(-num1, -num2); } }, accurateAddition: function (num1, num2) { if (num1 >= 0 && num2 >= 0) { return this._accurateAddition(num1, num2); } if (num1 >= 0 && num2 < 0) { return this.accurateSubtraction(num1, -num2); } if (num1 < 0 && num2 >= 0) { return this.accurateSubtraction(num2, -num1); } if (num1 < 0 && num2 < 0) { return -this._accurateAddition(-num1, -num2); } }, accurateMultiplication: function (num1, num2) { if (num1 >= 0 && num2 >= 0) { return this._accurateMultiplication(num1, num2); } if (num1 >= 0 && num2 < 0) { return -this._accurateMultiplication(num1, -num2); } if (num1 < 0 && num2 >= 0) { return -this._accurateMultiplication(-num1, num2); } if (num1 < 0 && num2 < 0) { return this._accurateMultiplication(-num1, -num2); } }, accurateDivisionTenExponent: function (num1, n) { if (num1 >= 0) { return this._accurateDivisionTenExponent(num1, n); } return -this._accurateDivisionTenExponent(-num1, n); } });/** * 月份下拉框 * * Created by GUY on 2015/8/28. * @class BI.MonthCombo * @extends BI.Trigger */ BI.MonthCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MonthCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-month-combo", behaviors: {}, height: 25 }); }, _init: function () { BI.MonthCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.month_trigger" }); this.trigger.on(BI.MonthTrigger.EVENT_CONFIRM, function (v) { if (self.combo.isViewVisible()) { return; } if (this.getKey() && this.getKey() !== self.storeValue) { self.setValue(this.getValue()); } else if (!this.getKey()) { self.setValue(); } self.fireEvent(BI.MonthCombo.EVENT_CONFIRM); }); this.trigger.on(BI.MonthTrigger.EVENT_FOCUS, function () { self.storeValue = this.getKey(); }); this.trigger.on(BI.MonthTrigger.EVENT_START, function () { self.combo.hideView(); }); this.trigger.on(BI.MonthTrigger.EVENT_STOP, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.popup = BI.createWidget({ type: "bi.month_popup", behaviors: o.behaviors }); this.popup.on(BI.MonthPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.MonthCombo.EVENT_CONFIRM); }); this.combo = BI.createWidget({ type: "bi.combo", element: this, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, popup: { minWidth: 85, el: this.popup } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.MonthCombo.EVENT_BEFORE_POPUPVIEW); }); }, setValue: function (v) { this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); } }); BI.MonthCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.MonthCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.month_combo", BI.MonthCombo);/** * 月份展示面板 * * Created by GUY on 2015/9/2. * @class BI.MonthPopup * @extends BI.Trigger */ BI.MonthPopup = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MonthPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-month-popup", behaviors: {} }); }, _init: function () { BI.MonthPopup.superclass._init.apply(this, arguments); var self = this, o = this.options; // 纵向排列月 var month = [0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11]; var items = []; items.push(month.slice(0, 2)); items.push(month.slice(2, 4)); items.push(month.slice(4, 6)); items.push(month.slice(6, 8)); items.push(month.slice(8, 10)); items.push(month.slice(10, 12)); items = BI.map(items, function (i, item) { return BI.map(item, function (j, td) { return { type: "bi.text_item", cls: "bi-list-item-active", textAlign: "center", whiteSpace: "nowrap", once: false, forceSelected: true, height: 23, width: 38, value: td, text: td + 1 }; }); }); this.month = BI.createWidget({ type: "bi.button_group", element: this, behaviors: o.behaviors, items: BI.createItems(items, {}), layouts: [BI.LogicFactory.createLogic("table", BI.extend({ dynamic: true }, { columns: 2, rows: 6, columnSize: [1 / 2, 1 / 2], rowSize: 25 })), { type: "bi.center_adapt", vgap: 1, hgap: 2 }] }); this.month.on(BI.Controller.EVENT_CHANGE, function (type) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.MonthPopup.EVENT_CHANGE); } }); }, getValue: function () { return this.month.getValue()[0]; }, setValue: function (v) { this.month.setValue([v]); } }); BI.MonthPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.month_popup", BI.MonthPopup);/** * 月份trigger * * Created by GUY on 2015/8/21. * @class BI.MonthTrigger * @extends BI.Trigger */ BI.MonthTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4, vgap: 2, errorText: BI.i18nText("BI-Month_Trigger_Error_Text") }, _defaultConfig: function () { return BI.extend(BI.MonthTrigger.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-month-trigger bi-border", height: 24 }); }, _init: function () { BI.MonthTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.editor = BI.createWidget({ type: "bi.sign_editor", height: o.height, validationChecker: function (v) { return v === "" || (BI.isPositiveInteger(v) && v >= 1 && v <= 12); }, quitChecker: function (v) { return false; }, hgap: c.hgap, vgap: c.vgap, allowBlank: true, errorText: c.errorText }); this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { self.fireEvent(BI.MonthTrigger.EVENT_FOCUS); }); this.editor.on(BI.SignEditor.EVENT_CHANGE, function () { self.fireEvent(BI.MonthTrigger.EVENT_CHANGE); }); this.editor.on(BI.SignEditor.EVENT_CONFIRM, function () { var value = self.editor.getValue(); if (BI.isNotNull(value)) { self.editor.setValue(value); self.editor.setTitle(value); } self.fireEvent(BI.MonthTrigger.EVENT_CONFIRM); }); this.editor.on(BI.SignEditor.EVENT_SPACE, function () { if (self.editor.isValid()) { self.editor.blur(); } }); this.editor.on(BI.SignEditor.EVENT_START, function () { self.fireEvent(BI.MonthTrigger.EVENT_START); }); this.editor.on(BI.SignEditor.EVENT_STOP, function () { self.fireEvent(BI.MonthTrigger.EVENT_STOP); }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: this.editor }, { el: { type: "bi.text_button", text: BI.i18nText("BI-Multi_Date_Month"), baseCls: "bi-trigger-month-text", width: o.height }, width: o.height }, { el: { type: "bi.trigger_icon_button", width: o.height }, width: o.height } ] }); }, setValue: function (v) { if(BI.isNotNull(v)) { this.editor.setState(v + 1); this.editor.setValue(v + 1); this.editor.setTitle(v + 1); return; } this.editor.setState(""); this.editor.setValue(""); this.editor.setTitle(""); }, getKey: function () { return this.editor.getValue() | 0; }, getValue: function () { return this.editor.getValue() - 1; } }); BI.MonthTrigger.EVENT_FOCUS = "EVENT_FOCUS"; BI.MonthTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.MonthTrigger.EVENT_START = "EVENT_START"; BI.MonthTrigger.EVENT_STOP = "EVENT_STOP"; BI.MonthTrigger.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.month_trigger", BI.MonthTrigger);/** * 普通控件 * * @class BI.MultiDateCard * @extends BI.Widget * @abstract */ BI.MultiDateCard = BI.inherit(BI.Widget, { constants: { lgap: 80, itemHeight: 35, defaultEditorValue: "1" }, _defaultConfig: function () { return $.extend(BI.MultiDateCard.superclass._defaultConfig.apply(this, arguments), {}); }, dateConfig: function () { }, defaultSelectedItem: function () { }, _init: function () { BI.MultiDateCard.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.label = BI.createWidget({ type: "bi.label", height: this.constants.itemHeight, textAlign: "left", text: BI.i18nText("BI-Multi_Date_Relative_Current_Time"), cls: "bi-multidate-inner-label bi-tips" }); this.radioGroup = BI.createWidget({ type: "bi.button_group", chooseType: 0, items: BI.createItems(this.dateConfig(), { type: "bi.multidate_segment", height: this.constants.itemHeight }), layouts: [{ type: "bi.vertical" }] }); this.radioGroup.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CONFIRM) { self.fireEvent(BI.MultiDateCard.EVENT_CHANGE); } }); this.radioGroup.on(BI.ButtonGroup.EVENT_CHANGE, function () { self.setValue(self.getValue()); self.fireEvent(BI.MultiDateCard.EVENT_CHANGE); }); BI.createWidget({ element: this, type: "bi.center_adapt", lgap: this.constants.lgap, items: [{ type: "bi.vertical", items: [this.label, this.radioGroup] }] }); }, getValue: function () { var button = this.radioGroup.getSelectedButtons()[0]; var type = button.getValue(), value = button.getInputValue(); return { type: type, value: value }; }, _isTypeAvaliable: function (type) { var res = false; BI.find(this.dateConfig(), function (i, item) { if (item.value === type) { res = true; return true; } }); return res; }, setValue: function (v) { var self = this; if (BI.isNotNull(v) && this._isTypeAvaliable(v.type)) { this.radioGroup.setValue(v.type); BI.each(this.radioGroup.getAllButtons(), function (i, button) { if (button.isEditorExist() === true && button.isSelected()) { button.setInputValue(v.value); } else { button.setInputValue(self.constants.defaultEditorValue); } }); } else { this.radioGroup.setValue(this.defaultSelectedItem()); BI.each(this.radioGroup.getAllButtons(), function (i, button) { button.setInputValue(self.constants.defaultEditorValue); }); } }, getCalculationValue: function () { var valueObject = this.getValue(); var type = valueObject.type, value = valueObject.value; switch (type) { case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_PREV: return Date.getDate().getOffsetDate(-1 * value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_AFTER: return Date.getDate().getOffsetDate(value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_TODAY: return Date.getDate(); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_PREV: return Date.getDate().getBeforeMultiMonth(value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_AFTER: return Date.getDate().getAfterMultiMonth(value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_BEGIN: return Date.getDate(Date.getDate().getFullYear(), Date.getDate().getMonth(), 1); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_END: return Date.getDate(Date.getDate().getFullYear(), Date.getDate().getMonth(), (Date.getDate().getLastDateOfMonth()).getDate()); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_PREV: return Date.getDate().getBeforeMulQuarter(value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_AFTER: return Date.getDate().getAfterMulQuarter(value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_BEGIN: return Date.getDate().getQuarterStartDate(); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_END: return Date.getDate().getQuarterEndDate(); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_PREV: return Date.getDate().getOffsetDate(-7 * value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_AFTER: return Date.getDate().getOffsetDate(7 * value); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_PREV: return Date.getDate((Date.getDate().getFullYear() - 1 * value), Date.getDate().getMonth(), Date.getDate().getDate()); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_AFTER: return Date.getDate((Date.getDate().getFullYear() + 1 * value), Date.getDate().getMonth(), Date.getDate().getDate()); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_BEGIN: return Date.getDate(Date.getDate().getFullYear(), 0, 1); case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_END: return Date.getDate(Date.getDate().getFullYear(), 11, 31); } } }); BI.MultiDateCard.EVENT_CHANGE = "EVENT_CHANGE"; /** * 日期控件 * @class BI.MultiDateCombo * @extends BI.Widget */ BI.MultiDateCombo = BI.inherit(BI.Single, { constants: { popupHeight: 259, popupWidth: 270, comboAdjustHeight: 1, border: 1, DATE_MIN_VALUE: "1900-01-01", DATE_MAX_VALUE: "2099-12-31" }, _defaultConfig: function () { return BI.extend(BI.MultiDateCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-combo bi-border", height: 24 }); }, _init: function () { BI.MultiDateCombo.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.storeTriggerValue = ""; var date = Date.getDate(); this.storeValue = null; this.trigger = BI.createWidget({ type: "bi.date_trigger", min: this.constants.DATE_MIN_VALUE, max: this.constants.DATE_MAX_VALUE }); this.trigger.on(BI.DateTrigger.EVENT_KEY_DOWN, function () { if (self.combo.isViewVisible()) { self.combo.hideView(); } }); this.trigger.on(BI.DateTrigger.EVENT_STOP, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.trigger.on(BI.DateTrigger.EVENT_TRIGGER_CLICK, function () { self.combo.toggle(); }); this.trigger.on(BI.DateTrigger.EVENT_FOCUS, function () { self.storeTriggerValue = self.trigger.getKey(); if (!self.combo.isViewVisible()) { self.combo.showView(); } self.fireEvent(BI.MultiDateCombo.EVENT_FOCUS); }); this.trigger.on(BI.DateTrigger.EVENT_ERROR, function () { self.storeValue = { year: date.getFullYear(), month: date.getMonth() }; self.popup.setValue(); self.fireEvent(BI.MultiDateCombo.EVENT_ERROR); }); this.trigger.on(BI.DateTrigger.EVENT_VALID, function () { self.fireEvent(BI.MultiDateCombo.EVENT_VALID); }); this.trigger.on(BI.DateTrigger.EVENT_CHANGE, function () { self.fireEvent(BI.MultiDateCombo.EVENT_CHANGE); }); this.trigger.on(BI.DateTrigger.EVENT_CONFIRM, function () { if (self.combo.isViewVisible()) { return; } var dateStore = self.storeTriggerValue; var dateObj = self.trigger.getKey(); if (BI.isNotEmptyString(dateObj) && !BI.isEqual(dateObj, dateStore)) { self.storeValue = self.trigger.getValue(); self.setValue(self.trigger.getValue()); } else if (BI.isEmptyString(dateObj)) { self.storeValue = null; self.trigger.setValue(); } self.fireEvent(BI.MultiDateCombo.EVENT_CONFIRM); }); this.popup = BI.createWidget({ type: "bi.multidate_popup", min: this.constants.DATE_MIN_VALUE, max: this.constants.DATE_MAX_VALUE }); this.popup.on(BI.MultiDatePopup.BUTTON_CLEAR_EVENT_CHANGE, function () { self.setValue(); self.combo.hideView(); self.fireEvent(BI.MultiDateCombo.EVENT_CONFIRM); }); this.popup.on(BI.MultiDatePopup.BUTTON_lABEL_EVENT_CHANGE, function () { var date = Date.getDate(); self.setValue({ year: date.getFullYear(), month: date.getMonth(), day: date.getDate() }); self.combo.hideView(); self.fireEvent(BI.MultiDateCombo.EVENT_CONFIRM); }); this.popup.on(BI.MultiDatePopup.BUTTON_OK_EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.MultiDateCombo.EVENT_CONFIRM); }); this.popup.on(BI.MultiDatePopup.CALENDAR_EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); // self.fireEvent(BI.MultiDateCombo.EVENT_CHANGE); self.fireEvent(BI.MultiDateCombo.EVENT_CONFIRM); }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, adjustLength: this.constants.comboAdjustHeight, popup: { el: this.popup, maxHeight: this.constants.popupHeight, width: this.constants.popupWidth, stopPropagation: false } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.popup.setValue(self.storeValue); self.fireEvent(BI.MultiDateCombo.EVENT_BEFORE_POPUPVIEW); }); var triggerBtn = BI.createWidget({ type: "bi.icon_button", cls: "bi-trigger-icon-button date-font", width: 24, height: 24 }); triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { if (self.combo.isViewVisible()) { self.combo.hideView(); } else { self.combo.showView(); } }); this.changeIcon = BI.createWidget({ type: "bi.icon_button", cls: "bi-trigger-icon-button date-change-h-font", width: 24, height: 24 }); var leftPart = BI.createWidget({ type: "bi.absolute", items: [{ el: this.combo, top: 0, left: 0, right: 0, bottom: 0 }, { el: triggerBtn, top: 0, left: 0 }] }); BI.createWidget({ type: "bi.htape", element: this, items: [leftPart, { el: this.changeIcon, width: 30 }], ref: function (_ref) { self.comboWrapper = _ref; } }); }, _checkDynamicValue: function (v) { var type = null; if (BI.isNotNull(v)) { type = v.type; } switch (type) { case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_BEGIN: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_END: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_BEGIN: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_END: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_BEGIN: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_END: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_TODAY: this.changeIcon.setVisible(true); this.comboWrapper.attr("items")[1].width = 30; this.comboWrapper.resize(); break; default: this.comboWrapper.attr("items")[1].width = 0; this.comboWrapper.resize(); this.changeIcon.setVisible(false); break; } }, setValue: function (v) { this.storeValue = v; this.popup.setValue(v); this.trigger.setValue(v); this._checkDynamicValue(v); }, getValue: function () { return this.storeValue; }, getKey: function () { return this.trigger.getKey(); }, hidePopupView: function () { this.combo.hideView(); } }); BI.shortcut("bi.multidate_combo", BI.MultiDateCombo); BI.MultiDateCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.MultiDateCombo.EVENT_FOCUS = "EVENT_FOCUS"; BI.MultiDateCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiDateCombo.EVENT_VALID = "EVENT_VALID"; BI.MultiDateCombo.EVENT_ERROR = "EVENT_ERROR"; BI.MultiDateCombo.EVENT_BEFORE_POPUPVIEW = "BI.MultiDateCombo.EVENT_BEFORE_POPUPVIEW"; BI.extend(BI.MultiDateCombo, { MULTI_DATE_YMD_CARD: 1, MULTI_DATE_YEAR_CARD: 2, MULTI_DATE_QUARTER_CARD: 3, MULTI_DATE_MONTH_CARD: 4, MULTI_DATE_WEEK_CARD: 5, MULTI_DATE_DAY_CARD: 6 }); BI.extend(BI.MultiDateCombo, { DATE_TYPE: { MULTI_DATE_YEAR_PREV: 1, MULTI_DATE_YEAR_AFTER: 2, MULTI_DATE_YEAR_BEGIN: 3, MULTI_DATE_YEAR_END: 4, MULTI_DATE_MONTH_PREV: 5, MULTI_DATE_MONTH_AFTER: 6, MULTI_DATE_MONTH_BEGIN: 7, MULTI_DATE_MONTH_END: 8, MULTI_DATE_QUARTER_PREV: 9, MULTI_DATE_QUARTER_AFTER: 10, MULTI_DATE_QUARTER_BEGIN: 11, MULTI_DATE_QUARTER_END: 12, MULTI_DATE_WEEK_PREV: 13, MULTI_DATE_WEEK_AFTER: 14, MULTI_DATE_DAY_PREV: 15, MULTI_DATE_DAY_AFTER: 16, MULTI_DATE_DAY_TODAY: 17, MULTI_DATE_PARAM: 18, MULTI_DATE_CALENDAR: 19, YEAR_QUARTER: 20, YEAR_MONTH: 21, YEAR_WEEK: 22, YEAR_DAY: 23, MONTH_WEEK: 24, MONTH_DAY: 25, YEAR: 26, SAME_PERIOD: 27, LAST_SAME_PERIOD: 28 } }); /** * 普通控件 * * @class BI.DayCard * @extends BI.MultiDateCard */ BI.DayCard = BI.inherit(BI.MultiDateCard, { _defaultConfig: function () { return $.extend(BI.DayCard.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-daycard" }); }, _init: function () { BI.DayCard.superclass._init.apply(this, arguments); }, dateConfig: function () { return [{ isEditorExist: true, selected: true, text: BI.i18nText("BI-Multi_Date_Day_Prev"), value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_PREV }, { isEditorExist: true, text: BI.i18nText("BI-Multi_Date_Day_Next"), value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_AFTER }, { isEditorExist: false, value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_TODAY, text: BI.i18nText("BI-Multi_Date_Today") }]; }, defaultSelectedItem: function () { return BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_PREV; } }); BI.DayCard.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.daycard", BI.DayCard); /** * 普通控件 * * @class BI.MonthCard * @extends BI.MultiDateCard */ BI.MonthCard = BI.inherit(BI.MultiDateCard, { _defaultConfig: function () { return $.extend(BI.MonthCard.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-monthcard" }); }, _init: function () { BI.MonthCard.superclass._init.apply(this, arguments); }, dateConfig: function () { return [{ selected: true, isEditorExist: true, value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_PREV, text: BI.i18nText("BI-Multi_Date_Month_Prev") }, { isEditorExist: true, value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_AFTER, text: BI.i18nText("BI-Multi_Date_Month_Next") }, { value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_BEGIN, isEditorExist: false, text: BI.i18nText("BI-Multi_Date_Month_Begin") }, { value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_END, isEditorExist: false, text: BI.i18nText("BI-Multi_Date_Month_End") }]; }, defaultSelectedItem: function () { return BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_PREV; } }); BI.MonthCard.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.monthcard", BI.MonthCard); /** * 日期控件 * @class BI.MultiDatePopup * @extends BI.Widget */ BI.MultiDatePopup = BI.inherit(BI.Widget, { constants: { tabHeight: 30, tabWidth: 42, titleHeight: 27, itemHeight: 30, triggerHeight: 24, buttonWidth: 90, buttonHeight: 25, cardHeight: 229, cardWidth: 270, popupHeight: 259, popupWidth: 270, comboAdjustHeight: 1, ymdWidth: 58, lgap: 2, border: 1 }, _defaultConfig: function () { return BI.extend(BI.MultiDatePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-popup", width: 268, height: 260 }); }, _init: function () { BI.MultiDatePopup.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.storeValue = ""; this.textButton = BI.createWidget({ type: "bi.text_button", forceCenter: true, cls: "bi-multidate-popup-label bi-border-left bi-border-right bi-border-top", shadow: true, text: BI.i18nText("BI-Multi_Date_Today") }); this.textButton.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.MultiDatePopup.BUTTON_lABEL_EVENT_CHANGE); }); this.clearButton = BI.createWidget({ type: "bi.text_button", forceCenter: true, cls: "bi-multidate-popup-button bi-border-top", shadow: true, text: BI.i18nText("BI-Basic_Clear") }); this.clearButton.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.MultiDatePopup.BUTTON_CLEAR_EVENT_CHANGE); }); this.okButton = BI.createWidget({ type: "bi.text_button", forceCenter: true, cls: "bi-multidate-popup-button bi-border-top", shadow: true, text: BI.i18nText("BI-Basic_OK") }); this.okButton.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.MultiDatePopup.BUTTON_OK_EVENT_CHANGE); }); this.dateTab = BI.createWidget({ type: "bi.tab", tab: { cls: "bi-multidate-popup-tab bi-border-bottom", height: this.constants.tabHeight, items: BI.createItems([{ text: BI.i18nText("BI-Multi_Date_YMD"), value: BI.MultiDateCombo.MULTI_DATE_YMD_CARD, width: this.constants.ymdWidth }, { text: BI.i18nText("BI-Multi_Date_Year"), value: BI.MultiDateCombo.MULTI_DATE_YEAR_CARD }, { text: BI.i18nText("BI-Multi_Date_Quarter"), value: BI.MultiDateCombo.MULTI_DATE_QUARTER_CARD }, { text: BI.i18nText("BI-Multi_Date_Month"), value: BI.MultiDateCombo.MULTI_DATE_MONTH_CARD }, { text: BI.i18nText("BI-Multi_Date_Week"), value: BI.MultiDateCombo.MULTI_DATE_WEEK_CARD }, { text: BI.i18nText("BI-Multi_Date_Day"), value: BI.MultiDateCombo.MULTI_DATE_DAY_CARD }], { width: this.constants.tabWidth, textAlign: "center", height: this.constants.itemHeight, cls: "bi-multidate-popup-item bi-list-item-active" }), layouts: [{ type: "bi.left" }] }, cardCreator: function (v) { switch (v) { case BI.MultiDateCombo.MULTI_DATE_YMD_CARD: self.ymd = BI.createWidget({ type: "bi.date_calendar_popup", min: self.options.min, max: self.options.max }); self.ymd.on(BI.DateCalendarPopup.EVENT_CHANGE, function () { self.fireEvent(BI.MultiDatePopup.CALENDAR_EVENT_CHANGE); }); return self.ymd; case BI.MultiDateCombo.MULTI_DATE_YEAR_CARD: self.year = BI.createWidget({ type: "bi.yearcard" }); self.year.on(BI.MultiDateCard.EVENT_CHANGE, function (v) { self._setInnerValue(self.year, v); }); return self.year; case BI.MultiDateCombo.MULTI_DATE_QUARTER_CARD: self.quarter = BI.createWidget({ type: "bi.quartercard" }); self.quarter.on(BI.MultiDateCard.EVENT_CHANGE, function (v) { self._setInnerValue(self.quarter, v); }); return self.quarter; case BI.MultiDateCombo.MULTI_DATE_MONTH_CARD: self.month = BI.createWidget({ type: "bi.monthcard" }); self.month.on(BI.MultiDateCard.EVENT_CHANGE, function (v) { self._setInnerValue(self.month, v); }); return self.month; case BI.MultiDateCombo.MULTI_DATE_WEEK_CARD: self.week = BI.createWidget({ type: "bi.weekcard" }); self.week.on(BI.MultiDateCard.EVENT_CHANGE, function (v) { self._setInnerValue(self.week, v); }); return self.week; case BI.MultiDateCombo.MULTI_DATE_DAY_CARD: self.day = BI.createWidget({ type: "bi.daycard" }); self.day.on(BI.MultiDateCard.EVENT_CHANGE, function (v) { self._setInnerValue(self.day, v); }); return self.day; } } }); this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_YMD_CARD); this.cur = BI.MultiDateCombo.MULTI_DATE_YMD_CARD; this.dateTab.on(BI.Tab.EVENT_CHANGE, function () { var v = self.dateTab.getSelect(); switch (v) { case BI.MultiDateCombo.MULTI_DATE_YMD_CARD: var date = this.getTab(self.cur).getCalculationValue(); self.ymd.setValue({ year: date.getFullYear(), month: date.getMonth(), day: date.getDate() }); self._setInnerValue(self.ymd); break; case BI.MultiDateCombo.MULTI_DATE_YEAR_CARD: self.year.setValue(self.storeValue); self._setInnerValue(self.year); break; case BI.MultiDateCombo.MULTI_DATE_QUARTER_CARD: self.quarter.setValue(self.storeValue); self._setInnerValue(self.quarter); break; case BI.MultiDateCombo.MULTI_DATE_MONTH_CARD: self.month.setValue(self.storeValue); self._setInnerValue(self.month); break; case BI.MultiDateCombo.MULTI_DATE_WEEK_CARD: self.week.setValue(self.storeValue); self._setInnerValue(self.week); break; case BI.MultiDateCombo.MULTI_DATE_DAY_CARD: self.day.setValue(self.storeValue); self._setInnerValue(self.day); break; } self.cur = v; }); this.dateButton = BI.createWidget({ type: "bi.grid", items: [[this.clearButton, this.textButton, this.okButton]] }); BI.createWidget({ element: this, type: "bi.vtape", items: [{ el: this.dateTab }, { el: this.dateButton, height: 30 }] }); }, _setInnerValue: function (obj) { if (this.dateTab.getSelect() === BI.MultiDateCombo.MULTI_DATE_YMD_CARD) { this.textButton.setValue(BI.i18nText("BI-Multi_Date_Today")); this.textButton.setEnable(true); } else { var date = obj.getCalculationValue(); date = date.print("%Y-%x-%e"); this.textButton.setValue(date); this.textButton.setEnable(false); } }, _checkValueValid: function (value) { return BI.isNull(value) || BI.isEmptyObject(value) || BI.isEmptyString(value); }, setValue: function (v) { this.storeValue = v; var self = this, date; var type, value; if (BI.isNotNull(v)) { type = v.type || BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_CALENDAR; value = v.value; if (BI.isNull(value)) { value = v; } } switch (type) { case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_BEGIN: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_END: this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_YEAR_CARD); this.year.setValue({type: type, value: value}); this.cur = BI.MultiDateCombo.MULTI_DATE_YEAR_CARD; self._setInnerValue(this.year); break; case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_BEGIN: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_END: this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_QUARTER_CARD); this.cur = BI.MultiDateCombo.MULTI_DATE_QUARTER_CARD; this.quarter.setValue({type: type, value: value}); self._setInnerValue(this.quarter); break; case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_BEGIN: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_MONTH_END: this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_MONTH_CARD); this.cur = BI.MultiDateCombo.MULTI_DATE_MONTH_CARD; this.month.setValue({type: type, value: value}); self._setInnerValue(this.month); break; case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_AFTER: this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_WEEK_CARD); this.cur = BI.MultiDateCombo.MULTI_DATE_WEEK_CARD; this.week.setValue({type: type, value: value}); self._setInnerValue(this.week); break; case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_PREV: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_AFTER: case BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_DAY_TODAY: this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_DAY_CARD); this.cur = BI.MultiDateCombo.MULTI_DATE_DAY_CARD; this.day.setValue({type: type, value: value}); self._setInnerValue(this.day); break; default: if (this._checkValueValid(value)) { var date = Date.getDate(); this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_YMD_CARD); this.ymd.setValue({ year: date.getFullYear(), month: date.getMonth(), day: date.getDate() }); this.textButton.setValue(BI.i18nText("BI-Multi_Date_Today")); } else { this.dateTab.setSelect(BI.MultiDateCombo.MULTI_DATE_YMD_CARD); this.ymd.setValue(value); this.textButton.setValue(BI.i18nText("BI-Multi_Date_Today")); } this.textButton.setEnable(true); break; } }, getValue: function () { var tab = this.dateTab.getSelect(); switch (tab) { case BI.MultiDateCombo.MULTI_DATE_YMD_CARD: return this.ymd.getValue(); case BI.MultiDateCombo.MULTI_DATE_YEAR_CARD: return this.year.getValue(); case BI.MultiDateCombo.MULTI_DATE_QUARTER_CARD: return this.quarter.getValue(); case BI.MultiDateCombo.MULTI_DATE_MONTH_CARD: return this.month.getValue(); case BI.MultiDateCombo.MULTI_DATE_WEEK_CARD: return this.week.getValue(); case BI.MultiDateCombo.MULTI_DATE_DAY_CARD: return this.day.getValue(); } } }); BI.MultiDatePopup.BUTTON_OK_EVENT_CHANGE = "BUTTON_OK_EVENT_CHANGE"; BI.MultiDatePopup.BUTTON_lABEL_EVENT_CHANGE = "BUTTON_lABEL_EVENT_CHANGE"; BI.MultiDatePopup.BUTTON_CLEAR_EVENT_CHANGE = "BUTTON_CLEAR_EVENT_CHANGE"; BI.MultiDatePopup.CALENDAR_EVENT_CHANGE = "CALENDAR_EVENT_CHANGE"; BI.shortcut("bi.multidate_popup", BI.MultiDatePopup); /** * 普通控件 * * @class BI.QuarterCard * @extends BI.MultiDateCard */ BI.QuarterCard = BI.inherit(BI.MultiDateCard, { _defaultConfig: function () { return $.extend(BI.QuarterCard.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-quartercard" }); }, _init: function () { BI.QuarterCard.superclass._init.apply(this, arguments); }, dateConfig: function () { return [{ selected: true, value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_PREV, isEditorExist: true, text: BI.i18nText("BI-Multi_Date_Quarter_Prev") }, { value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_AFTER, isEditorExist: true, text: BI.i18nText("BI-Multi_Date_Quarter_Next") }, { value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_BEGIN, isEditorExist: false, text: BI.i18nText("BI-Multi_Date_Quarter_Begin") }, { value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_END, isEditorExist: false, text: BI.i18nText("BI-Multi_Date_Quarter_End") }]; }, defaultSelectedItem: function () { return BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_QUARTER_PREV; } }); BI.QuarterCard.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.quartercard", BI.QuarterCard); /** * 普通控件 * * @class BI.MultiDateSegment * @extends BI.Single */ BI.MultiDateSegment = BI.inherit(BI.Single, { constants: { itemHeight: 24, maxGap: 15, minGap: 10, textWidth: 60, defaultEditorValue: "1" }, _defaultConfig: function () { return $.extend(BI.MultiDateSegment.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-segment", text: "", height: 30, isEditorExist: true, selected: false, defaultEditorValue: "1" }); }, _init: function () { BI.MultiDateSegment.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.radio = BI.createWidget({ type: "bi.radio", selected: opts.selected }); this.radio.on(BI.Controller.EVENT_CHANGE, function (v) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.textEditor = BI.createWidget({ type: "bi.text_editor", value: this.constants.defaultEditorValue, title: function () { return self.textEditor.getValue(); }, tipType: "success", cls: "bi-multidate-editor", width: this.constants.textWidth, height: this.constants.itemHeight }); this.textEditor.on(BI.Controller.EVENT_CHANGE, function (v) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", cls: "bi-multidate-normal-label", text: opts.text, height: this.constants.itemHeight }); this._createSegment(); }, _createSegment: function () { if (this.options.isEditorExist === true) { return BI.createWidget({ element: this, type: "bi.left", items: [{ el: { type: "bi.center_adapt", items: [this.radio], height: this.constants.itemHeight }, lgap: 0 }, { el: { type: "bi.center_adapt", items: [this.textEditor], widgetName: "textEditor" }, lgap: this.constants.maxGap }, { el: this.text, lgap: this.constants.minGap }] }); } return BI.createWidget({ element: this, type: "bi.left", items: [{ el: { type: "bi.center_adapt", items: [this.radio], height: this.constants.itemHeight }, lgap: 0 }, { el: this.text, lgap: this.constants.maxGap }] }); }, setSelected: function (v) { if (BI.isNotNull(this.radio)) { this.radio.setSelected(v); this.textEditor.setEnable(v); } }, isSelected: function () { return this.radio.isSelected(); }, getValue: function () { return this.options.value; }, getInputValue: function () { return this.textEditor.getValue() | 0; }, setInputValue: function (v) { this.textEditor.setValue(v); }, isEditorExist: function () { return this.options.isEditorExist; } }); BI.MultiDateSegment.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multidate_segment", BI.MultiDateSegment);/** * 普通控件 * * @class BI.WeekCard * @extends BI.MultiDateCard */ BI.WeekCard = BI.inherit(BI.MultiDateCard, { _defaultConfig: function () { return $.extend(BI.WeekCard.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-weekcard" }); }, _init: function () { BI.WeekCard.superclass._init.apply(this, arguments); }, dateConfig: function () { return [{ selected: true, isEditorExist: true, text: BI.i18nText("BI-Multi_Date_Week_Prev"), value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_PREV }, { isEditorExist: true, text: BI.i18nText("BI-Multi_Date_Week_Next"), value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_AFTER }]; }, defaultSelectedItem: function () { return BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_WEEK_PREV; } }); BI.WeekCard.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.weekcard", BI.WeekCard); /** * 普通控件 * * @class BI.YearCard * @extends BI.MultiDateCard */ BI.YearCard = BI.inherit(BI.MultiDateCard, { _defaultConfig: function () { return $.extend(BI.YearCard.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multidate-yearcard" }); }, _init: function () { BI.YearCard.superclass._init.apply(this, arguments); }, dateConfig: function () { return [{ selected: true, isEditorExist: true, text: BI.i18nText("BI-Multi_Date_Year_Prev"), value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_PREV }, { isEditorExist: true, text: BI.i18nText("BI-Multi_Date_Year_Next"), value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_AFTER }, { isEditorExist: false, value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_BEGIN, text: BI.i18nText("BI-Multi_Date_Year_Begin") }, { isEditorExist: false, value: BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_END, text: BI.i18nText("BI-Multi_Date_Year_End") }]; }, defaultSelectedItem: function () { return BI.MultiDateCombo.DATE_TYPE.MULTI_DATE_YEAR_PREV; } }); BI.YearCard.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.yearcard", BI.YearCard); /** * @class BI.MultiLayerSelectTreeCombo * @extends BI.Widget */ BI.MultiLayerSelectTreeCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSelectTreeCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multilayer_select_tree-combo", isDefaultInit: false, height: 30, text: "", items: [] }); }, _init: function () { BI.MultiLayerSelectTreeCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.single_tree_trigger", text: o.text, height: o.height, items: o.items }); this.popup = BI.createWidget({ type: "bi.multilayer_select_tree_popup", isDefaultInit: o.isDefaultInit, items: o.items }); this.combo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup } }); this.combo.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.popup.on(BI.MultiLayerSelectTreePopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.MultiLayerSelectTreeCombo.EVENT_CHANGE); }); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); }, populate: function (items) { this.combo.populate(items); } }); BI.MultiLayerSelectTreeCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multilayer_select_tree_combo", BI.MultiLayerSelectTreeCombo);/** * guy * 二级树 * @class BI.MultiLayerSelectLevelTree * @extends BI.Select */ BI.MultiLayerSelectLevelTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSelectLevelTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multilayer-select-level-tree", isDefaultInit: false, items: [], itemsCreator: BI.emptyFn }); }, _init: function () { BI.MultiLayerSelectLevelTree.superclass._init.apply(this, arguments); this.initTree(this.options.items); }, _formatItems: function (nodes, layer) { var self = this; BI.each(nodes, function (i, node) { var extend = {}; node.layer = layer; if (!BI.isKey(node.id)) { node.id = BI.UUID(); } if (node.isParent === true || BI.isNotEmptyArray(node.children)) { switch (i) { case 0 : extend.type = "bi.multilayer_select_tree_first_plus_group_node"; break; case nodes.length - 1 : extend.type = "bi.multilayer_select_tree_last_plus_group_node"; break; default : extend.type = "bi.multilayer_select_tree_mid_plus_group_node"; break; } BI.defaults(node, extend); self._formatItems(node.children, layer + 1); } else { switch (i) { case nodes.length - 1: extend.type = "bi.multilayer_single_tree_last_tree_leaf_item"; break; default : extend.type = "bi.multilayer_single_tree_mid_tree_leaf_item"; } BI.defaults(node, extend); } }); return nodes; }, _assertId: function (sNodes) { BI.each(sNodes, function (i, node) { node.id = node.id || BI.UUID(); }); }, // 构造树结构, initTree: function (nodes) { var self = this, o = this.options; this.empty(); this._assertId(nodes); this.tree = BI.createWidget({ type: "bi.custom_tree", element: this, expander: { type: "bi.select_tree_expander", isDefaultInit: o.isDefaultInit, el: {}, popup: { type: "bi.custom_tree" } }, items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0), itemsCreator: o.itemsCreator, el: { type: "bi.button_tree", chooseType: BI.Selection.Single, layouts: [{ type: "bi.vertical" }] } }); this.tree.on(BI.Controller.EVENT_CHANGE, function (type) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.MultiLayerSelectLevelTree.EVENT_CHANGE, arguments); } }); }, populate: function (nodes) { this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0)); }, setValue: function (v) { this.tree.setValue(v); }, getValue: function () { return this.tree.getValue(); }, getAllLeaves: function () { return this.tree.getAllLeaves(); }, getNodeById: function (id) { return this.tree.getNodeById(id); }, getNodeByValue: function (id) { return this.tree.getNodeByValue(id); } }); BI.MultiLayerSelectLevelTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multilayer_select_level_tree", BI.MultiLayerSelectLevelTree);/** * Created by GUY on 2016/1/26. * * @class BI.MultiLayerSelectTreePopup * @extends BI.Pane */ BI.MultiLayerSelectTreePopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSelectTreePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multilayer-select-tree-popup", tipText: BI.i18nText("BI-No_Selected_Item"), isDefaultInit: false, itemsCreator: BI.emptyFn, items: [] }); }, _init: function () { BI.MultiLayerSelectTreePopup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tree = BI.createWidget({ type: "bi.multilayer_select_level_tree", isDefaultInit: o.isDefaultInit, items: o.items, itemsCreator: o.itemsCreator }); BI.createWidget({ type: "bi.vertical", scrolly: false, scrollable: true, element: this, items: [this.tree] }); this.tree.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.tree.on(BI.MultiLayerSelectLevelTree.EVENT_CHANGE, function () { self.fireEvent(BI.MultiLayerSelectTreePopup.EVENT_CHANGE); }); this.check(); }, getValue: function () { return this.tree.getValue(); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.tree.setValue(v); }, populate: function (items) { BI.MultiLayerSelectTreePopup.superclass.populate.apply(this, arguments); this.tree.populate(items); } }); BI.MultiLayerSelectTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multilayer_select_tree_popup", BI.MultiLayerSelectTreePopup);/** * 加号表示的组节点 * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSelectTreeFirstPlusGroupNode * @extends BI.NodeButton */ BI.MultiLayerSelectTreeFirstPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-multilayer-select-tree-first-plus-group-node bi-list-item-active", layer: 0, // 第几层级 id: "", pId: "", readonly: true, open: false, height: 25 }); }, _init: function () { BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.node = BI.createWidget({ type: "bi.select_tree_first_plus_group_node", cls: "bi-list-item-none", stopPropagation: true, logic: { dynamic: true }, id: o.id, pId: o.pId, open: o.open, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.node.on(BI.Controller.EVENT_CHANGE, function (type) { self.setSelected(self.isSelected()); self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.node); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, isOnce: function () { return true; }, doRedMark: function () { this.node.doRedMark.apply(this.node, arguments); }, unRedMark: function () { this.node.unRedMark.apply(this.node, arguments); }, isSelected: function () { return this.node.isSelected(); }, setSelected: function (b) { BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass.setSelected.apply(this, arguments); this.node.setSelected(b); }, doClick: function () { BI.NodeButton.superclass.doClick.apply(this, arguments); this.node.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MultiLayerSelectTreeFirstPlusGroupNode.superclass.setOpened.apply(this, arguments); this.node.setOpened(v); } }); BI.shortcut("bi.multilayer_select_tree_first_plus_group_node", BI.MultiLayerSelectTreeFirstPlusGroupNode);/** * 加号表示的组节点 * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSelectTreeLastPlusGroupNode * @extends BI.NodeButton */ BI.MultiLayerSelectTreeLastPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MultiLayerSelectTreeLastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-multilayer-select-tree-last-plus-group-node bi-list-item-active", layer: 0, // 第几层级 id: "", pId: "", readonly: true, open: false, height: 25 }); }, _init: function () { BI.MultiLayerSelectTreeLastPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.node = BI.createWidget({ type: "bi.select_tree_last_plus_group_node", cls: "bi-list-item-none", stopPropagation: true, logic: { dynamic: true }, id: o.id, pId: o.pId, open: o.open, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.node.on(BI.Controller.EVENT_CHANGE, function (type) { self.setSelected(self.isSelected()); self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.node); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.node.doRedMark.apply(this.node, arguments); }, unRedMark: function () { this.node.unRedMark.apply(this.node, arguments); }, isSelected: function () { return this.node.isSelected(); }, setSelected: function (b) { BI.MultiLayerSelectTreeLastPlusGroupNode.superclass.setSelected.apply(this, arguments); this.node.setSelected(b); }, doClick: function () { BI.MultiLayerSelectTreeLastPlusGroupNode.superclass.doClick.apply(this, arguments); this.node.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MultiLayerSelectTreeLastPlusGroupNode.superclass.setOpened.apply(this, arguments); this.node.setOpened(v); } }); BI.shortcut("bi.multilayer_select_tree_last_plus_group_node", BI.MultiLayerSelectTreeLastPlusGroupNode);/** * 加号表示的组节点 * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSelectTreeMidPlusGroupNode * @extends BI.NodeButton */ BI.MultiLayerSelectTreeMidPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MultiLayerSelectTreeMidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-multilayer-select-tree-mid-plus-group-node bi-list-item-active", layer: 0, // 第几层级 id: "", pId: "", readonly: true, open: false, height: 25 }); }, _init: function () { BI.MultiLayerSelectTreeMidPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.node = BI.createWidget({ type: "bi.select_tree_mid_plus_group_node", cls: "bi-list-item-none", stopPropagation: true, logic: { dynamic: true }, id: o.id, pId: o.pId, open: o.open, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.node.on(BI.Controller.EVENT_CHANGE, function (type) { self.setSelected(self.isSelected()); self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.node); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.node.doRedMark.apply(this.node, arguments); }, unRedMark: function () { this.node.unRedMark.apply(this.node, arguments); }, isSelected: function () { return this.node.isSelected(); }, setSelected: function (b) { BI.MultiLayerSelectTreeMidPlusGroupNode.superclass.setSelected.apply(this, arguments); this.node.setSelected(b); }, doClick: function () { BI.MultiLayerSelectTreeMidPlusGroupNode.superclass.doClick.apply(this, arguments); this.node.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MultiLayerSelectTreeMidPlusGroupNode.superclass.setOpened.apply(this, arguments); this.node.setOpened(v); } }); BI.shortcut("bi.multilayer_select_tree_mid_plus_group_node", BI.MultiLayerSelectTreeMidPlusGroupNode);/** * 多层级下拉单选树 * Created by GUY on 2016/1/26. * * @class BI.MultiLayerSingleTreeCombo * @extends BI.Widget */ BI.MultiLayerSingleTreeCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSingleTreeCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multilayer-singletree-combo", isDefaultInit: false, height: 30, text: "", itemsCreator: BI.emptyFn, items: [] }); }, _init: function () { BI.MultiLayerSingleTreeCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.single_tree_trigger", text: o.text, height: o.height, items: o.items }); this.popup = BI.createWidget({ type: "bi.multilayer_single_tree_popup", isDefaultInit: o.isDefaultInit, items: o.items }); this.combo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup } }); this.combo.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.popup.on(BI.MultiLayerSingleTreePopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.MultiLayerSingleTreeCombo.EVENT_CHANGE); }); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); }, populate: function (items) { this.combo.populate(items); } }); BI.MultiLayerSingleTreeCombo.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multilayer_single_tree_combo", BI.MultiLayerSingleTreeCombo);/** * guy * 二级树 * @class BI.MultiLayerSingleLevelTree * @extends BI.Single */ BI.MultiLayerSingleLevelTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSingleLevelTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multilayer-single-level-tree", isDefaultInit: false, items: [], itemsCreator: BI.emptyFn }); }, _init: function () { BI.MultiLayerSingleLevelTree.superclass._init.apply(this, arguments); this.initTree(this.options.items); }, _formatItems: function (nodes, layer) { var self = this; BI.each(nodes, function (i, node) { var extend = {}; node.layer = layer; if (!BI.isKey(node.id)) { node.id = BI.UUID(); } if (node.isParent === true || BI.isNotEmptyArray(node.children)) { switch (i) { case 0 : extend.type = "bi.multilayer_single_tree_first_plus_group_node"; break; case nodes.length - 1 : extend.type = "bi.multilayer_single_tree_last_plus_group_node"; break; default : extend.type = "bi.multilayer_single_tree_mid_plus_group_node"; break; } BI.defaults(node, extend); self._formatItems(node.children, layer + 1); } else { switch (i) { case nodes.length - 1: extend.type = "bi.multilayer_single_tree_last_tree_leaf_item"; break; default : extend.type = "bi.multilayer_single_tree_mid_tree_leaf_item"; } BI.defaults(node, extend); } }); return nodes; }, _assertId: function (sNodes) { BI.each(sNodes, function (i, node) { node.id = node.id || BI.UUID(); }); }, // 构造树结构, initTree: function (nodes) { var self = this, o = this.options; this.empty(); this._assertId(nodes); this.tree = BI.createWidget({ type: "bi.custom_tree", element: this, expander: { isDefaultInit: o.isDefaultInit, el: {}, popup: { type: "bi.custom_tree" } }, items: this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0), itemsCreator: function (op, callback) { o.itemsCreator(op, function (items) { callback(BI.Tree.transformToTreeFormat(items), 0); }); }, el: { type: "bi.button_tree", chooseType: BI.Selection.Single, layouts: [{ type: "bi.vertical" }] } }); this.tree.on(BI.Controller.EVENT_CHANGE, function (type, v) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.MultiLayerSingleLevelTree.EVENT_CHANGE, v); } }); }, populate: function (nodes) { this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(nodes), 0)); }, setValue: function (v) { this.tree.setValue(v); }, getValue: function () { return this.tree.getValue(); }, getAllLeaves: function () { return this.tree.getAllLeaves(); }, getNodeById: function (id) { return this.tree.getNodeById(id); }, getNodeByValue: function (id) { return this.tree.getNodeByValue(id); } }); BI.MultiLayerSingleLevelTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multilayer_single_level_tree", BI.MultiLayerSingleLevelTree); /** * Created by GUY on 2016/1/26. * * @class BI.MultiLayerSingleTreePopup * @extends BI.Pane */ BI.MultiLayerSingleTreePopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSingleTreePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multilayer-singletree-popup", tipText: BI.i18nText("BI-No_Selected_Item"), isDefaultInit: false, itemsCreator: BI.emptyFn, items: [] }); }, _init: function () { BI.MultiLayerSingleTreePopup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tree = BI.createWidget({ type: "bi.multilayer_single_level_tree", isDefaultInit: o.isDefaultInit, items: o.items, itemsCreator: o.itemsCreator }); BI.createWidget({ type: "bi.vertical", scrolly: false, scrollable: true, element: this, items: [this.tree] }); this.tree.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.tree.on(BI.MultiLayerSingleLevelTree.EVENT_CHANGE, function () { self.fireEvent(BI.MultiLayerSingleTreePopup.EVENT_CHANGE); }); this.check(); }, getValue: function () { return this.tree.getValue(); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.tree.setValue(v); }, populate: function (items) { BI.MultiLayerSingleTreePopup.superclass.populate.apply(this, arguments); this.tree.populate(items); } }); BI.MultiLayerSingleTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multilayer_single_tree_popup", BI.MultiLayerSingleTreePopup);/** * 加号表示的组节点 * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSingleTreeFirstPlusGroupNode * @extends BI.NodeButton */ BI.MultiLayerSingleTreeFirstPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-multilayer-single-tree-first-plus-group-node bi-list-item", layer: 0, // 第几层级 id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.node = BI.createWidget({ type: "bi.first_plus_group_node", cls: "bi-list-item-none", logic: { dynamic: true }, id: o.id, pId: o.pId, open: o.open, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.node.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) {// 本身实现click功能 return; } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.node); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.node.doRedMark.apply(this.node, arguments); }, unRedMark: function () { this.node.unRedMark.apply(this.node, arguments); }, doClick: function () { BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass.doClick.apply(this, arguments); this.node.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MultiLayerSingleTreeFirstPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.node)) { this.node.setOpened(v); } } }); BI.shortcut("bi.multilayer_single_tree_first_plus_group_node", BI.MultiLayerSingleTreeFirstPlusGroupNode);/** * 加号表示的组节点 * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSingleTreeLastPlusGroupNode * @extends BI.NodeButton */ BI.MultiLayerSingleTreeLastPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MultiLayerSingleTreeLastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-multilayer-single-tree-last-plus-group-node bi-list-item", layer: 0, // 第几层级 id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.MultiLayerSingleTreeLastPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.node = BI.createWidget({ type: "bi.last_plus_group_node", cls: "bi-list-item-none", logic: { dynamic: true }, id: o.id, pId: o.pId, open: o.open, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.node.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) {// 本身实现click功能 return; } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.node); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.node.doRedMark.apply(this.node, arguments); }, unRedMark: function () { this.node.unRedMark.apply(this.node, arguments); }, doClick: function () { BI.MultiLayerSingleTreeLastPlusGroupNode.superclass.doClick.apply(this, arguments); this.node.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MultiLayerSingleTreeLastPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.node)) { this.node.setOpened(v); } } }); BI.shortcut("bi.multilayer_single_tree_last_plus_group_node", BI.MultiLayerSingleTreeLastPlusGroupNode);/** * 加号表示的组节点 * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSingleTreeMidPlusGroupNode * @extends BI.NodeButton */ BI.MultiLayerSingleTreeMidPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.MultiLayerSingleTreeMidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-multilayer-single-tree-mid-plus-group-node bi-list-item", layer: 0, // 第几层级 id: "", pId: "", open: false, height: 25 }); }, _init: function () { BI.MultiLayerSingleTreeMidPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.node = BI.createWidget({ type: "bi.mid_plus_group_node", cls: "bi-list-item-none", logic: { dynamic: true }, id: o.id, pId: o.pId, open: o.open, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.node.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) {// 本身实现click功能 return; } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.node); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.node.doRedMark.apply(this.node, arguments); }, unRedMark: function () { this.node.unRedMark.apply(this.node, arguments); }, doClick: function () { BI.MultiLayerSingleTreeMidPlusGroupNode.superclass.doClick.apply(this, arguments); this.node.setSelected(this.isSelected()); }, setOpened: function (v) { BI.MultiLayerSingleTreeMidPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.node)) { this.node.setOpened(v); } } }); BI.shortcut("bi.multilayer_single_tree_mid_plus_group_node", BI.MultiLayerSingleTreeMidPlusGroupNode);/** * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSingleTreeFirstTreeLeafItem * @extends BI.BasicButton */ BI.MultiLayerSingleTreeFirstTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-multilayer-single-tree-first-tree-leaf-item bi-list-item-active", logic: { dynamic: false }, layer: 0, id: "", pId: "", height: 25 }); }, _init: function () { BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.item = BI.createWidget({ type: "bi.first_tree_leaf_item", cls: "bi-list-item-none", logic: { dynamic: true }, id: o.id, pId: o.pId, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.item.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) {// 本身实现click功能 return; } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.item); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.item.doRedMark.apply(this.item, arguments); }, unRedMark: function () { this.item.unRedMark.apply(this.item, arguments); }, doHighLight: function () { this.item.doHighLight.apply(this.item, arguments); }, unHighLight: function () { this.item.unHighLight.apply(this.item, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass.doClick.apply(this, arguments); this.item.setSelected(this.isSelected()); }, setSelected: function (v) { BI.MultiLayerSingleTreeFirstTreeLeafItem.superclass.setSelected.apply(this, arguments); this.item.setSelected(v); } }); BI.shortcut("bi.multilayer_single_tree_first_tree_leaf_item", BI.MultiLayerSingleTreeFirstTreeLeafItem);/** * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSingleTreeLastTreeLeafItem * @extends BI.BasicButton */ BI.MultiLayerSingleTreeLastTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSingleTreeLastTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-multilayer-single-tree-last-tree-leaf-item bi-list-item-active", logic: { dynamic: false }, layer: 0, id: "", pId: "", height: 25 }); }, _init: function () { BI.MultiLayerSingleTreeLastTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.item = BI.createWidget({ type: "bi.last_tree_leaf_item", cls: "bi-list-item-none", logic: { dynamic: true }, id: o.id, pId: o.pId, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.item.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) {// 本身实现click功能 return; } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.item); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.item.doRedMark.apply(this.item, arguments); }, unRedMark: function () { this.item.unRedMark.apply(this.item, arguments); }, doHighLight: function () { this.item.doHighLight.apply(this.item, arguments); }, unHighLight: function () { this.item.unHighLight.apply(this.item, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.MultiLayerSingleTreeLastTreeLeafItem.superclass.doClick.apply(this, arguments); this.item.setSelected(this.isSelected()); }, setSelected: function (v) { BI.MultiLayerSingleTreeLastTreeLeafItem.superclass.setSelected.apply(this, arguments); this.item.setSelected(v); } }); BI.shortcut("bi.multilayer_single_tree_last_tree_leaf_item", BI.MultiLayerSingleTreeLastTreeLeafItem);/** * * Created by GUY on 2016/1/27. * @class BI.MultiLayerSingleTreeMidTreeLeafItem * @extends BI.BasicButton */ BI.MultiLayerSingleTreeMidTreeLeafItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.MultiLayerSingleTreeMidTreeLeafItem.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-multilayer-single-tree-mid-tree-leaf-item bi-list-item-active", logic: { dynamic: false }, layer: 0, id: "", pId: "", height: 25 }); }, _init: function () { BI.MultiLayerSingleTreeMidTreeLeafItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.item = BI.createWidget({ type: "bi.mid_tree_leaf_item", cls: "bi-list-item-none", logic: { dynamic: true }, id: o.id, pId: o.pId, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.item.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) {// 本身实现click功能 return; } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); var items = []; BI.count(0, o.layer, function () { items.push({ type: "bi.layout", cls: "base-line-conn-background", width: 13, height: o.height }); }); items.push(this.item); BI.createWidget({ type: "bi.td", element: this, columnSize: BI.makeArray(o.layer, 13), items: [items] }); }, doRedMark: function () { this.item.doRedMark.apply(this.item, arguments); }, unRedMark: function () { this.item.unRedMark.apply(this.item, arguments); }, doHighLight: function () { this.item.doHighLight.apply(this.item, arguments); }, unHighLight: function () { this.item.unHighLight.apply(this.item, arguments); }, getId: function () { return this.options.id; }, getPId: function () { return this.options.pId; }, doClick: function () { BI.MultiLayerSingleTreeMidTreeLeafItem.superclass.doClick.apply(this, arguments); this.item.setSelected(this.isSelected()); }, setSelected: function (v) { BI.MultiLayerSingleTreeMidTreeLeafItem.superclass.setSelected.apply(this, arguments); this.item.setSelected(v); } }); BI.shortcut("bi.multilayer_single_tree_mid_tree_leaf_item", BI.MultiLayerSingleTreeMidTreeLeafItem);/** * * @class BI.MultiSelectCheckPane * @extends BI.Widget */ BI.MultiSelectCheckPane = BI.inherit(BI.Widget, { constants: { height: 25, lgap: 10, tgap: 5 }, _defaultConfig: function () { return BI.extend(BI.MultiSelectCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-check-pane bi-background", items: [], itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, onClickContinueSelect: BI.emptyFn }); }, _init: function () { BI.MultiSelectCheckPane.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.storeValue = {}; this.display = BI.createWidget({ type: "bi.display_selected_list", items: opts.items, itemsCreator: function (op, callback) { op = BI.extend(op || {}, { selectedValues: self.storeValue.value }); if (self.storeValue.type === BI.Selection.Multi) { callback({ items: BI.map(self.storeValue.value, function (i, v) { var txt = opts.valueFormatter(v) || v; return { text: txt, value: v, title: txt }; }) }); return; } opts.itemsCreator(op, callback); } }); this.continueSelect = BI.createWidget({ type: "bi.text_button", text: BI.i18nText("BI-Continue_Select"), cls: "multi-select-check-selected bi-high-light" }); this.continueSelect.on(BI.TextButton.EVENT_CHANGE, function () { opts.onClickContinueSelect(); }); BI.createWidget({ type: "bi.vtape", element: this, items: [{ height: this.constants.height, el: { type: "bi.left", cls: "multi-select-continue-select", items: [ { el: { type: "bi.label", text: BI.i18nText("BI-Selected_Data") }, lgap: this.constants.lgap, tgap: this.constants.tgap }, { el: this.continueSelect, lgap: this.constants.lgap, tgap: this.constants.tgap }] } }, { height: "fill", el: this.display }] }); }, setValue: function (v) { this.storeValue = v || {}; }, empty: function () { this.display.empty(); }, populate: function () { this.display.populate.apply(this.display, arguments); } }); BI.shortcut("bi.multi_select_check_pane", BI.MultiSelectCheckPane);/** * * * 查看已选弹出层的展示面板 * @class BI.DisplaySelectedList * @extends BI.Widget */ BI.DisplaySelectedList = BI.inherit(BI.Pane, { constants: { height: 25, lgap: 10 }, _defaultConfig: function () { return BI.extend(BI.DisplaySelectedList.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-display-list", itemsCreator: BI.emptyFn, items: [] }); }, _init: function () { BI.DisplaySelectedList.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.hasNext = false; this.button_group = BI.createWidget({ type: "bi.list_pane", element: this, el: { type: "bi.loader", isDefaultInit: false, logic: { dynamic: true, scrolly: true }, items: this._createItems(opts.items), chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, layouts: [{ type: "bi.vertical", lgap: 10 }] }, itemsCreator: function (options, callback) { opts.itemsCreator(options, function (ob) { self.hasNext = !!ob.hasNext; callback(self._createItems(ob.items)); }); }, hasNext: function () { return self.hasNext; } }); }, _createItems: function (items) { return BI.createItems(items, { type: "bi.icon_text_item", cls: "cursor-default check-font display-list-item bi-tips", once: true, invalid: true, selected: true, height: this.constants.height, logic: { dynamic: true } }); }, empty: function () { this.button_group.empty(); }, populate: function (items) { if (arguments.length === 0) { this.button_group.populate(); } else { this.button_group.populate(this._createItems(items)); } } }); BI.shortcut("bi.display_selected_list", BI.DisplaySelectedList);/** * * @class BI.MultiSelectInsertCombo * @extends BI.Single */ BI.MultiSelectInsertCombo = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.MultiSelectInsertCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-insert-combo", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, height: 28 }); }, _init: function () { BI.MultiSelectInsertCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; var assertShowValue = function () { BI.isKey(self._startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](self._startValue); self.trigger.getSearcher().setState(self.storeValue); self.trigger.getCounter().setButtonChecked(self.storeValue); }; this.storeValue = {}; // 标记正在请求数据 this.requesting = false; this.trigger = BI.createWidget({ type: "bi.multi_select_trigger", height: o.height, // adapter: this.popup, masker: { offset: { left: 1, top: 1, right: 2, bottom: 33 } }, valueFormatter: o.valueFormatter, itemsCreator: function (op, callback) { o.itemsCreator(op, function (res) { if (op.times === 1 && BI.isNotNull(op.keywords)) { // 预防trigger内部把当前的storeValue改掉 self.trigger.setValue(BI.deepClone(self.getValue())); } callback.apply(self, arguments); }); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { self._setStartValue(""); this.getSearcher().setValue(self.storeValue); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { self._setStartValue(""); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_PAUSE, function () { // if (this.getSearcher().hasMatched()) { var keyword = this.getSearcher().getKeyword(); self._join({ type: BI.Selection.Multi, value: [keyword] }, function () { // 如果在不选的状态下直接把该值添加进来 if (self.storeValue.type === BI.Selection.Multi) { self.storeValue.value.pushDistinct(keyword); } self.combo.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); self.populate(); self._setStartValue(""); }); // } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function (keywords) { var last = BI.last(keywords); keywords = BI.initial(keywords || []); if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { self.combo.setValue(self.storeValue); assertShowValue(); self.combo.populate(); self._setStartValue(""); } else { self.combo.setValue(self.storeValue); assertShowValue(); } }); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function (value, obj) { if (obj instanceof BI.MultiSelectBar) { self._joinAll(this.getValue(), function () { assertShowValue(); }); } else { self._join(this.getValue(), function () { assertShowValue(); }); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { this.getCounter().setValue(self.storeValue); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, el: this.trigger, adjustLength: 1, popup: { type: "bi.multi_select_popup_view", ref: function () { self.popup = this; self.trigger.setAdapter(this); }, listeners: [{ eventName: BI.MultiSelectPopupView.EVENT_CHANGE, action: function () { self.storeValue = this.getValue(); self._adjust(function () { assertShowValue(); }); } }, { eventName: BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM, action: function () { self._defaultState(); } }, { eventName: BI.MultiSelectPopupView.EVENT_CLICK_CLEAR, action: function () { self.setValue(); self._defaultState(); } }], itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, onLoaded: function () { BI.nextTick(function () { self.combo.adjustWidth(); self.combo.adjustHeight(); self.trigger.getCounter().adjustView(); self.trigger.getSearcher().adjustView(); }); } }, hideChecker: function (e) { return triggerBtn.element.find(e.target).length === 0; } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { this.setValue(self.storeValue); BI.nextTick(function () { self.populate(); }); }); // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 this.wants2Quit = false; this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { // important:关闭弹出时又可能没有退出编辑状态 self.trigger.stopEditing(); if (self.requesting === true) { self.wants2Quit = true; } else { self.fireEvent(BI.MultiSelectInsertCombo.EVENT_CONFIRM); } }); var triggerBtn = BI.createWidget({ type: "bi.trigger_icon_button", width: o.height, height: o.height, cls: "multi-select-trigger-icon-button bi-border-left" }); triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { self.trigger.getCounter().hideView(); if (self.combo.isViewVisible()) { self.combo.hideView(); } else { self.combo.showView(); } }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.combo, left: 0, right: 0, top: 0, bottom: 0 }, { el: triggerBtn, right: 0, top: 0, bottom: 0 }] }); }, _defaultState: function () { this.trigger.stopEditing(); this.combo.hideView(); }, _assertValue: function (val) { val || (val = {}); val.type || (val.type = BI.Selection.Multi); val.value || (val.value = []); }, _makeMap: function (values) { return BI.makeObject(values || []); }, _joinKeywords: function (keywords, callback) { var self = this, o = this.options; this._assertValue(this.storeValue); this.requesting = true; o.itemsCreator({ type: BI.MultiSelectInsertCombo.REQ_GET_ALL_DATA, keywords: keywords }, function (ob) { var values = BI.pluck(ob.items, "value"); digest(values); }); function digest (items) { var selectedMap = self._makeMap(items); BI.each(keywords, function (i, val) { if (BI.isNotNull(selectedMap[val])) { self.storeValue.value[self.storeValue.type === BI.Selection.Multi ? "pushDistinct" : "remove"](val); } }); self._adjust(callback); } }, _joinAll: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this.requesting = true; o.itemsCreator({ type: BI.MultiSelectInsertCombo.REQ_GET_ALL_DATA, keywords: [this.trigger.getKey()] }, function (ob) { var items = BI.pluck(ob.items, "value"); if (self.storeValue.type === res.type) { var change = false; var map = self._makeMap(self.storeValue.value); BI.each(items, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (self.storeValue.value = BI.values(map)); self._adjust(callback); return; } var selectedMap = self._makeMap(self.storeValue.value); var notSelectedMap = self._makeMap(res.value); var newItems = []; BI.each(items, function (i, item) { if (BI.isNotNull(selectedMap[items[i]])) { delete selectedMap[items[i]]; } if (BI.isNull(notSelectedMap[items[i]])) { newItems.push(item); } }); self.storeValue.value = newItems.concat(BI.values(selectedMap)); self._adjust(callback); }); }, _adjust: function (callback) { var self = this, o = this.options; adjust(); callback(); function adjust () { if (self.wants2Quit === true) { self.fireEvent(BI.MultiSelectInsertCombo.EVENT_CONFIRM); self.wants2Quit = false; } self.requesting = false; } }, _join: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this._assertValue(this.storeValue); if (this.storeValue.type === res.type) { var map = this._makeMap(this.storeValue.value); BI.each(res.value, function (i, v) { if (!map[v]) { self.storeValue.value.push(v); map[v] = v; } }); var change = false; BI.each(res.assist, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (this.storeValue.value = BI.values(map)); self._adjust(callback); return; } this._joinAll(res, callback); }, _setStartValue: function (value) { this._startValue = value; this.popup.setStartValue(value); }, setValue: function (v) { this.storeValue = v || {}; this._assertValue(this.storeValue); this.combo.setValue(this.storeValue); }, getValue: function () { return BI.deepClone(this.storeValue); }, populate: function () { this.combo.populate.apply(this.combo, arguments); } }); BI.extend(BI.MultiSelectInsertCombo, { REQ_GET_DATA_LENGTH: 0, REQ_GET_ALL_DATA: -1 }); BI.MultiSelectInsertCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.shortcut("bi.multi_select_insert_combo", BI.MultiSelectInsertCombo);/** * * @class BI.MultiSelectCombo * @extends BI.Single */ BI.MultiSelectCombo = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.MultiSelectCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-combo", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, height: 28 }); }, _init: function () { BI.MultiSelectCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; var assertShowValue = function () { BI.isKey(self._startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](self._startValue); self.trigger.getSearcher().setState(self.storeValue); self.trigger.getCounter().setButtonChecked(self.storeValue); }; this.storeValue = {}; // 标记正在请求数据 this.requesting = false; this.trigger = BI.createWidget({ type: "bi.multi_select_trigger", height: o.height, // adapter: this.popup, masker: { offset: { left: 1, top: 1, right: 2, bottom: 33 } }, valueFormatter: o.valueFormatter, itemsCreator: function (op, callback) { o.itemsCreator(op, function (res) { if (op.times === 1 && BI.isNotNull(op.keywords)) { // 预防trigger内部把当前的storeValue改掉 self.trigger.setValue(BI.deepClone(self.getValue())); } callback.apply(self, arguments); }); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { self._setStartValue(""); this.getSearcher().setValue(self.storeValue); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { self._setStartValue(""); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_PAUSE, function () { if (this.getSearcher().hasMatched()) { var keyword = this.getSearcher().getKeyword(); self._join({ type: BI.Selection.Multi, value: [keyword] }, function () { self.combo.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); self.populate(); self._setStartValue(""); }); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_SEARCHING, function (keywords) { var last = BI.last(keywords); keywords = BI.initial(keywords || []); if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { self.combo.setValue(self.storeValue); assertShowValue(); self.combo.populate(); self._setStartValue(""); } else { self.combo.setValue(self.storeValue); assertShowValue(); } }); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function (value, obj) { if (obj instanceof BI.MultiSelectBar) { self._joinAll(this.getValue(), function () { assertShowValue(); }); } else { self._join(this.getValue(), function () { assertShowValue(); }); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { this.getCounter().setValue(self.storeValue); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, el: this.trigger, adjustLength: 1, popup: { type: "bi.multi_select_popup_view", ref: function () { self.popup = this; self.trigger.setAdapter(this); }, listeners: [{ eventName: BI.MultiSelectPopupView.EVENT_CHANGE, action: function () { self.storeValue = this.getValue(); self._adjust(function () { assertShowValue(); }); } }, { eventName: BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM, action: function () { self._defaultState(); } }, { eventName: BI.MultiSelectPopupView.EVENT_CLICK_CLEAR, action: function () { self.setValue(); self._defaultState(); } }], itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, onLoaded: function () { BI.nextTick(function () { self.combo.adjustWidth(); self.combo.adjustHeight(); self.trigger.getCounter().adjustView(); self.trigger.getSearcher().adjustView(); }); } }, hideChecker: function (e) { return triggerBtn.element.find(e.target).length === 0; } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { this.setValue(self.storeValue); BI.nextTick(function () { self.populate(); }); }); // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 this.wants2Quit = false; this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { // important:关闭弹出时又可能没有退出编辑状态 self.trigger.stopEditing(); if (self.requesting === true) { self.wants2Quit = true; } else { self.fireEvent(BI.MultiSelectCombo.EVENT_CONFIRM); } }); var triggerBtn = BI.createWidget({ type: "bi.trigger_icon_button", width: o.height, height: o.height, cls: "multi-select-trigger-icon-button bi-border-left" }); triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { self.trigger.getCounter().hideView(); if (self.combo.isViewVisible()) { self.combo.hideView(); } else { self.combo.showView(); } }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.combo, left: 0, right: 0, top: 0, bottom: 0 }, { el: triggerBtn, right: 0, top: 0, bottom: 0 }] }); }, _defaultState: function () { this.trigger.stopEditing(); this.combo.hideView(); }, _assertValue: function (val) { val || (val = {}); val.type || (val.type = BI.Selection.Multi); val.value || (val.value = []); }, _makeMap: function (values) { return BI.makeObject(values || []); }, _joinKeywords: function (keywords, callback) { var self = this, o = this.options; this._assertValue(this.storeValue); this.requesting = true; o.itemsCreator({ type: BI.MultiSelectCombo.REQ_GET_ALL_DATA, keywords: keywords }, function (ob) { var values = BI.pluck(ob.items, "value"); digest(values); }); function digest (items) { var selectedMap = self._makeMap(items); BI.each(keywords, function (i, val) { if (BI.isNotNull(selectedMap[val])) { self.storeValue.value[self.storeValue.type === BI.Selection.Multi ? "pushDistinct" : "remove"](val); } }); self._adjust(callback); } }, _joinAll: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this.requesting = true; o.itemsCreator({ type: BI.MultiSelectCombo.REQ_GET_ALL_DATA, keywords: [this.trigger.getKey()] }, function (ob) { var items = BI.pluck(ob.items, "value"); if (self.storeValue.type === res.type) { var change = false; var map = self._makeMap(self.storeValue.value); BI.each(items, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (self.storeValue.value = BI.values(map)); self._adjust(callback); return; } var selectedMap = self._makeMap(self.storeValue.value); var notSelectedMap = self._makeMap(res.value); var newItems = []; BI.each(items, function (i, item) { if (BI.isNotNull(selectedMap[items[i]])) { delete selectedMap[items[i]]; } if (BI.isNull(notSelectedMap[items[i]])) { newItems.push(item); } }); self.storeValue.value = newItems.concat(BI.values(selectedMap)); self._adjust(callback); }); }, _adjust: function (callback) { var self = this, o = this.options; if (!this._count) { o.itemsCreator({ type: BI.MultiSelectCombo.REQ_GET_DATA_LENGTH }, function (res) { self._count = res.count; adjust(); callback(); }); } else { adjust(); callback(); } function adjust () { if (self.storeValue.type === BI.Selection.All && self.storeValue.value.length >= self._count) { self.storeValue = { type: BI.Selection.Multi, value: [] }; } else if (self.storeValue.type === BI.Selection.Multi && self.storeValue.value.length >= self._count) { self.storeValue = { type: BI.Selection.All, value: [] }; } if (self.wants2Quit === true) { self.fireEvent(BI.MultiSelectCombo.EVENT_CONFIRM); self.wants2Quit = false; } self.requesting = false; } }, _join: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this._assertValue(this.storeValue); if (this.storeValue.type === res.type) { var map = this._makeMap(this.storeValue.value); BI.each(res.value, function (i, v) { if (!map[v]) { self.storeValue.value.push(v); map[v] = v; } }); var change = false; BI.each(res.assist, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (this.storeValue.value = BI.values(map)); self._adjust(callback); return; } this._joinAll(res, callback); }, _setStartValue: function (value) { this._startValue = value; this.popup.setStartValue(value); }, setValue: function (v) { this.storeValue = v || {}; this._assertValue(this.storeValue); this.combo.setValue(this.storeValue); }, getValue: function () { return BI.deepClone(this.storeValue); }, populate: function () { this._count = null; this.combo.populate.apply(this.combo, arguments); } }); BI.extend(BI.MultiSelectCombo, { REQ_GET_DATA_LENGTH: 0, REQ_GET_ALL_DATA: -1 }); BI.MultiSelectCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.shortcut("bi.multi_select_combo", BI.MultiSelectCombo);/** * 多选加载数据面板 * Created by guy on 15/11/2. * @class BI.MultiSelectLoader * @extends Widget */ BI.MultiSelectLoader = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectLoader.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-loader", logic: { dynamic: true }, el: { height: 400 }, valueFormatter: BI.emptyFn, itemsCreator: BI.emptyFn, onLoaded: BI.emptyFn }); }, _init: function () { BI.MultiSelectLoader.superclass._init.apply(this, arguments); var self = this, opts = this.options; var hasNext = false; this.button_group = BI.createWidget({ type: "bi.select_list", element: this, logic: opts.logic, el: BI.extend({ onLoaded: opts.onLoaded, el: { type: "bi.loader", isDefaultInit: false, logic: { dynamic: true, scrolly: true }, el: { chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, behaviors: { redmark: function () { return true; } }, layouts: [{ type: "bi.vertical" }] } } }, opts.el), itemsCreator: function (op, callback) { var startValue = self._startValue; self.storeValue && (op = BI.extend(op || {}, { selectedValues: BI.isKey(startValue) && self.storeValue.type === BI.Selection.Multi ? self.storeValue.value.concat(startValue) : self.storeValue.value })); opts.itemsCreator(op, function (ob) { hasNext = ob.hasNext; var firstItems = []; if (op.times === 1 && self.storeValue) { var json = BI.map(self.storeValue.value, function (i, v) { var txt = opts.valueFormatter(v) || v; return { text: txt, value: v, title: txt, selected: self.storeValue.type === BI.Selection.Multi }; }); if (BI.isKey(self._startValue) && !self.storeValue.value.contains(self._startValue)) { var txt = opts.valueFormatter(startValue) || startValue; json.unshift({ text: txt, value: startValue, title: txt, selected: true }); } firstItems = self._createItems(json); } callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); if (op.times === 1 && self.storeValue) { BI.isKey(startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](startValue); self.setValue(self.storeValue); } (op.times === 1) && self._scrollToTop(); }); }, hasNext: function () { return hasNext; } }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button_group.on(BI.SelectList.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectLoader.EVENT_CHANGE, arguments); }); }, _createItems: function (items) { return BI.createItems(items, { type: "bi.multi_select_item", logic: this.options.logic, height: 25, selected: this.isAllSelected() }); }, _scrollToTop: function () { var self = this; BI.delay(function () { self.button_group.element.scrollTop(0); }, 30); }, isAllSelected: function () { return this.button_group.isAllSelected(); }, _assertValue: function (val) { val || (val = {}); val.type || (val.type = BI.Selection.Multi); val.value || (val.value = []); }, setStartValue: function (v) { this._startValue = v; }, setValue: function (v) { this.storeValue = v || {}; this._assertValue(this.storeValue); this.button_group.setValue(this.storeValue); }, getValue: function () { return this.button_group.getValue(); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, empty: function () { this.button_group.empty(); }, populate: function (items) { this.button_group.populate.apply(this.button_group, arguments); }, resetHeight: function (h) { this.button_group.resetHeight(h); }, resetWidth: function (w) { this.button_group.resetWidth(w); } }); BI.MultiSelectLoader.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multi_select_loader", BI.MultiSelectLoader);/** * 带加载的多选下拉面板 * @class BI.MultiSelectPopupView * @extends Widget */ BI.MultiSelectPopupView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectPopupView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-popup-view", maxWidth: "auto", minWidth: 135, maxHeight: 400, valueFormatter: BI.emptyFn, itemsCreator: BI.emptyFn, onLoaded: BI.emptyFn }); }, _init: function () { BI.MultiSelectPopupView.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.loader = BI.createWidget({ type: "bi.multi_select_loader", itemsCreator: opts.itemsCreator, valueFormatter: opts.valueFormatter, onLoaded: opts.onLoaded }); this.popupView = BI.createWidget({ type: "bi.multi_popup_view", stopPropagation: false, maxWidth: opts.maxWidth, minWidth: opts.minWidth, maxHeight: opts.maxHeight, element: this, buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_Sure")], el: this.loader }); this.popupView.on(BI.MultiPopupView.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectPopupView.EVENT_CHANGE); }); this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { switch (index) { case 0: self.fireEvent(BI.MultiSelectPopupView.EVENT_CLICK_CLEAR); break; case 1: self.fireEvent(BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM); break; } }); }, isAllSelected: function () { return this.loader.isAllSelected(); }, setStartValue: function (v) { this.loader.setStartValue(v); }, setValue: function (v) { this.popupView.setValue(v); }, getValue: function () { return this.popupView.getValue(); }, populate: function (items) { this.popupView.populate.apply(this.popupView, arguments); }, resetHeight: function (h) { this.popupView.resetHeight(h); }, resetWidth: function (w) { this.popupView.resetWidth(w); } }); BI.MultiSelectPopupView.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiSelectPopupView.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; BI.MultiSelectPopupView.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.shortcut("bi.multi_select_popup_view", BI.MultiSelectPopupView);/** * * 复选下拉框 * @class BI.MultiSelectTrigger * @extends BI.Trigger */ BI.MultiSelectTrigger = BI.inherit(BI.Trigger, { constants: { height: 14, rgap: 4, lgap: 4 }, _defaultConfig: function () { return BI.extend(BI.MultiSelectTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-trigger bi-border", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, searcher: {}, switcher: {}, adapter: null, masker: {} }); }, _init: function () { BI.MultiSelectTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options; if (o.height) { this.setHeight(o.height - 2); } this.searcher = BI.createWidget(o.searcher, { type: "bi.multi_select_searcher", height: o.height, itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, popup: {}, adapter: o.adapter, masker: o.masker }); this.searcher.on(BI.MultiSelectSearcher.EVENT_START, function () { self.fireEvent(BI.MultiSelectTrigger.EVENT_START); }); this.searcher.on(BI.MultiSelectSearcher.EVENT_PAUSE, function () { self.fireEvent(BI.MultiSelectTrigger.EVENT_PAUSE); }); this.searcher.on(BI.MultiSelectSearcher.EVENT_SEARCHING, function () { self.fireEvent(BI.MultiSelectTrigger.EVENT_SEARCHING, arguments); }); this.searcher.on(BI.MultiSelectSearcher.EVENT_STOP, function () { self.fireEvent(BI.MultiSelectTrigger.EVENT_STOP); }); this.searcher.on(BI.MultiSelectSearcher.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectTrigger.EVENT_CHANGE, arguments); }); this.numberCounter = BI.createWidget(o.switcher, { type: "bi.multi_select_check_selected_switcher", valueFormatter: o.valueFormatter, itemsCreator: o.itemsCreator, adapter: o.adapter, masker: o.masker }); this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE, function () { self.fireEvent(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK); }); this.numberCounter.on(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW); }); var wrapNumberCounter = BI.createWidget({ type: "bi.right_vertical_adapt", hgap: 4, items: [{ el: this.numberCounter }] }); var wrapper = BI.createWidget({ type: "bi.htape", element: this, items: [ { el: this.searcher, width: "fill" }, { el: wrapNumberCounter, width: 0 }, { el: BI.createWidget(), width: 30 }] }); this.numberCounter.on(BI.Events.VIEW, function (b) { BI.nextTick(function () {// 自动调整宽度 wrapper.attr("items")[1].width = (b === true ? self.numberCounter.element.outerWidth() + 8 : 0); wrapper.resize(); }); }); this.element.click(function (e) { if (self.element.__isMouseInBounds__(e) && !self.numberCounter.element.__isMouseInBounds__(e)) { self.numberCounter.hideView(); } }); }, getCounter: function () { return this.numberCounter; }, getSearcher: function () { return this.searcher; }, stopEditing: function () { this.searcher.stopSearch(); this.numberCounter.hideView(); }, setAdapter: function (adapter) { this.searcher.setAdapter(adapter); this.numberCounter.setAdapter(adapter); }, setValue: function (ob) { this.searcher.setValue(ob); this.numberCounter.setValue(ob); }, getKey: function () { return this.searcher.getKey(); }, getValue: function () { return this.searcher.getValue(); } }); BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; BI.MultiSelectTrigger.EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; BI.MultiSelectTrigger.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiSelectTrigger.EVENT_START = "EVENT_START"; BI.MultiSelectTrigger.EVENT_STOP = "EVENT_STOP"; BI.MultiSelectTrigger.EVENT_PAUSE = "EVENT_PAUSE"; BI.MultiSelectTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; BI.shortcut("bi.multi_select_trigger", BI.MultiSelectTrigger);/** * 多选加载数据搜索loader面板 * Created by guy on 15/11/4. * @class BI.MultiSelectSearchLoader * @extends Widget */ BI.MultiSelectSearchLoader = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectSearchLoader.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-search-loader", itemsCreator: BI.emptyFn, keywordGetter: BI.emptyFn, valueFormatter: BI.emptyFn }); }, _init: function () { BI.MultiSelectSearchLoader.superclass._init.apply(this, arguments); var self = this, opts = this.options; var hasNext = false; this.button_group = BI.createWidget({ type: "bi.select_list", element: this, logic: { dynamic: false }, el: { tipText: BI.i18nText("BI-No_Select"), el: { type: "bi.loader", isDefaultInit: false, logic: { dynamic: true, scrolly: true }, el: { chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, behaviors: { redmark: function () { return true; } }, layouts: [{ type: "bi.vertical" }] } } }, itemsCreator: function (op, callback) { self.storeValue && (op = BI.extend(op || {}, { selectedValues: self.storeValue.value })); opts.itemsCreator(op, function (ob) { var keyword = ob.keyword = opts.keywordGetter(); hasNext = ob.hasNext; var firstItems = []; if (op.times === 1 && self.storeValue) { var json = self._filterValues(self.storeValue); firstItems = self._createItems(json); } callback(firstItems.concat(self._createItems(ob.items)), keyword); if (op.times === 1 && self.storeValue) { self.setValue(self.storeValue); } }); }, hasNext: function () { return hasNext; } }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button_group.on(BI.SelectList.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectSearchLoader.EVENT_CHANGE, arguments); }); }, _createItems: function (items) { return BI.createItems(items, { type: "bi.multi_select_item", logic: { dynamic: false }, height: 25, selected: this.isAllSelected() }); }, isAllSelected: function () { return this.button_group.isAllSelected(); }, _filterValues: function (src) { var o = this.options; var keyword = o.keywordGetter(); var values = BI.deepClone(src.value) || []; var newValues = BI.map(values, function (i, v) { return { text: o.valueFormatter(v) || v, value: v }; }); if (BI.isKey(keyword)) { var search = BI.Func.getSearchResult(newValues, keyword); values = search.matched.concat(search.finded); } return BI.map(values, function (i, v) { return { text: v.text, title: v.text, value: v.value, selected: src.type === BI.Selection.All }; }); }, setValue: function (v) { // 暂存的值一定是新的值,不然v改掉后,storeValue也跟着改了 this.storeValue = BI.deepClone(v); this.button_group.setValue(v); }, getValue: function () { return this.button_group.getValue(); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, empty: function () { this.button_group.empty(); }, populate: function (items) { this.button_group.populate.apply(this.button_group, arguments); }, resetHeight: function (h) { this.button_group.resetHeight(h); }, resetWidth: function (w) { this.button_group.resetWidth(w); } }); BI.MultiSelectSearchLoader.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multi_select_search_loader", BI.MultiSelectSearchLoader);/** * * 在搜索框中输入文本弹出的面板 * @class BI.MultiSelectSearchPane * @extends Widget */ BI.MultiSelectSearchPane = BI.inherit(BI.Widget, { constants: { height: 25, lgap: 10, tgap: 5 }, _defaultConfig: function () { return BI.extend(BI.MultiSelectSearchPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-search-pane bi-card", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, keywordGetter: BI.emptyFn }); }, _init: function () { BI.MultiSelectSearchPane.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tooltipClick = BI.createWidget({ type: "bi.label", invisible: true, text: BI.i18nText("BI-Click_Blank_To_Select"), cls: "multi-select-toolbar", height: this.constants.height }); this.loader = BI.createWidget({ type: "bi.multi_select_search_loader", keywordGetter: o.keywordGetter, valueFormatter: o.valueFormatter, itemsCreator: function (op, callback) { o.itemsCreator.apply(self, [op, function (res) { callback(res); self.setKeyword(o.keywordGetter()); }]); } }); this.loader.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.resizer = BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.tooltipClick, height: 0 }, { el: this.loader }] }); this.tooltipClick.setVisible(false); }, setKeyword: function (keyword) { var btn; var isVisible = this.loader.getAllButtons().length > 0 && (btn = this.loader.getAllButtons()[0]) && (keyword === btn.getValue()); if (isVisible !== this.tooltipClick.isVisible()) { this.tooltipClick.setVisible(isVisible); this.resizer.attr("items")[0].height = (isVisible ? this.constants.height : 0); this.resizer.resize(); } }, isAllSelected: function () { return this.loader.isAllSelected(); }, hasMatched: function () { return this.tooltipClick.isVisible(); }, setValue: function (v) { this.loader.setValue(v); }, getValue: function () { return this.loader.getValue(); }, empty: function () { this.loader.empty(); }, populate: function (items) { this.loader.populate.apply(this.loader, arguments); } }); BI.MultiSelectSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multi_select_search_pane", BI.MultiSelectSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiSelectCheckSelectedButton * @extends BI.Single */ BI.MultiSelectCheckSelectedButton = BI.inherit(BI.Single, { _const: { checkSelected: BI.i18nText("BI-Check_Selected") }, _defaultConfig: function () { return BI.extend(BI.MultiSelectCheckSelectedButton.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-check-selected-button bi-high-light", itemsCreator: BI.emptyFn }); }, _init: function () { BI.MultiSelectCheckSelectedButton.superclass._init.apply(this, arguments); var self = this; this.numberCounter = BI.createWidget({ type: "bi.text_button", element: this, hgap: 4, text: "0", textAlign: "center", textHeight: 15 }); this.numberCounter.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.numberCounter.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectCheckSelectedButton.EVENT_CHANGE, arguments); }); this.numberCounter.element.hover(function () { self.numberCounter.setTag(self.numberCounter.getText()); self.numberCounter.setText(self._const.checkSelected); }, function () { self.numberCounter.setText(self.numberCounter.getTag()); }); this.setVisible(false); }, setValue: function (ob) { var self = this, o = this.options; ob || (ob = {}); ob.type || (ob.type = BI.Selection.Multi); ob.value || (ob.value = []); if (ob.type === BI.Selection.All) { o.itemsCreator({ type: BI.MultiSelectCombo.REQ_GET_DATA_LENGTH }, function (res) { var length = res.count - ob.value.length; BI.nextTick(function () { self.numberCounter.setText(length); self.setVisible(length > 0); }); }); return; } BI.nextTick(function () { self.numberCounter.setText(ob.value.length); self.setVisible(ob.value.length > 0); }); }, getValue: function () { } }); BI.MultiSelectCheckSelectedButton.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multi_select_check_selected_button", BI.MultiSelectCheckSelectedButton);/** * 多选输入框 * Created by guy on 15/11/3. * @class BI.MultiSelectEditor * @extends Widget */ BI.MultiSelectEditor = BI.inherit(BI.Widget, { _const: { checkSelected: BI.i18nText("BI-Check_Selected") }, _defaultConfig: function () { return BI.extend(BI.MultiSelectEditor.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-editor", el: {} }); }, _init: function () { BI.MultiSelectEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget(o.el, { type: "bi.state_editor", element: this, height: o.height, watermark: BI.i18nText("BI-Basic_Search"), allowBlank: true }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.StateEditor.EVENT_PAUSE, function () { self.fireEvent(BI.MultiSelectEditor.EVENT_PAUSE); }); this.editor.on(BI.StateEditor.EVENT_CLICK_LABEL, function () { }); }, focus: function () { this.editor.focus(); }, blur: function () { this.editor.blur(); }, setState: function (state) { this.editor.setState(state); }, setValue: function (v) { this.editor.setValue(v); }, getValue: function () { var v = this.editor.getState(); if (BI.isArray(v) && v.length > 0) { return v[v.length - 1]; } return ""; }, getKeywords: function () { var val = this.editor.getLastValidValue(); var keywords = val.match(/[\S]+/g); if (BI.isEndWithBlank(val)) { return keywords.concat([" "]); } return keywords; }, populate: function (items) { } }); BI.MultiSelectEditor.EVENT_PAUSE = "MultiSelectEditor.EVENT_PAUSE"; BI.shortcut("bi.multi_select_editor", BI.MultiSelectEditor);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiSelectSearcher * @extends Widget */ BI.MultiSelectSearcher = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectSearcher.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-searcher", itemsCreator: BI.emptyFn, el: {}, popup: {}, valueFormatter: BI.emptyFn, adapter: null, masker: {} }); }, _init: function () { BI.MultiSelectSearcher.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget(o.el, { type: "bi.multi_select_editor", height: o.height }); this.searcher = BI.createWidget({ type: "bi.searcher", element: this, height: o.height, isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback(); }, el: this.editor, popup: BI.extend({ type: "bi.multi_select_search_pane", valueFormatter: o.valueFormatter, keywordGetter: function () { return self.editor.getValue(); }, itemsCreator: function (op, callback) { op.keyword = self.editor.getValue(); this.setKeyword(op.keyword); o.itemsCreator(op, callback); } }, o.popup), adapter: o.adapter, masker: o.masker }); this.searcher.on(BI.Searcher.EVENT_START, function () { self.fireEvent(BI.MultiSelectSearcher.EVENT_START); }); this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { if (this.hasMatched()) { } self.fireEvent(BI.MultiSelectSearcher.EVENT_PAUSE); }); this.searcher.on(BI.Searcher.EVENT_STOP, function () { self.fireEvent(BI.MultiSelectSearcher.EVENT_STOP); }); this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectSearcher.EVENT_CHANGE, arguments); }); this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { var keywords = this.getKeywords(); self.fireEvent(BI.MultiSelectSearcher.EVENT_SEARCHING, keywords); }); }, adjustView: function () { this.searcher.adjustView(); }, isSearching: function () { return this.searcher.isSearching(); }, stopSearch: function () { this.searcher.stopSearch(); }, getKeyword: function () { return this.editor.getValue(); }, hasMatched: function () { return this.searcher.hasMatched(); }, hasChecked: function () { return this.searcher.getView() && this.searcher.getView().hasChecked(); }, setAdapter: function (adapter) { this.searcher.setAdapter(adapter); }, setState: function (ob) { var o = this.options; ob || (ob = {}); ob.value || (ob.value = []); if (ob.type === BI.Selection.All) { if (ob.value.length === 0) { this.editor.setState(BI.Selection.All); } else if (BI.size(ob.assist) <= 20) { var state = ""; BI.each(ob.assist, function (i, v) { if (i === 0) { state += "" + (o.valueFormatter(v + "") || v); } else { state += "," + (o.valueFormatter(v + "") || v); } }); this.editor.setState(state); } else { this.editor.setState(BI.Selection.Multi); } } else { if (ob.value.length === 0) { this.editor.setState(BI.Selection.None); } else if (BI.size(ob.value) <= 20) { var state = ""; BI.each(ob.value, function (i, v) { if (i === 0) { state += "" + (o.valueFormatter(v + "") || v); } else { state += "," + (o.valueFormatter(v + "") || v); } }); this.editor.setState(state); } else { this.editor.setState(BI.Selection.Multi); } } }, setValue: function (ob) { this.setState(ob); this.searcher.setValue(ob); }, getKey: function () { return this.editor.getValue(); }, getValue: function () { return this.searcher.getValue(); }, populate: function (items) { this.searcher.populate.apply(this.searcher, arguments); } }); BI.MultiSelectSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.MultiSelectSearcher.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiSelectSearcher.EVENT_START = "EVENT_START"; BI.MultiSelectSearcher.EVENT_STOP = "EVENT_STOP"; BI.MultiSelectSearcher.EVENT_PAUSE = "EVENT_PAUSE"; BI.MultiSelectSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; BI.shortcut("bi.multi_select_searcher", BI.MultiSelectSearcher);/** * 查看已选switcher * Created by guy on 15/11/3. * @class BI.MultiSelectCheckSelectedSwitcher * @extends Widget */ BI.MultiSelectCheckSelectedSwitcher = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectCheckSelectedSwitcher.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-check-selected-switcher", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, el: {}, popup: {}, adapter: null, masker: {} }); }, _init: function () { BI.MultiSelectCheckSelectedSwitcher.superclass._init.apply(this, arguments); var self = this, o = this.options; this.button = BI.createWidget(o.el, { type: "bi.multi_select_check_selected_button", itemsCreator: o.itemsCreator }); this.button.on(BI.Events.VIEW, function () { self.fireEvent(BI.Events.VIEW, arguments); }); this.switcher = BI.createWidget({ type: "bi.switcher", toggle: false, element: this, el: this.button, popup: BI.extend({ type: "bi.multi_select_check_pane", valueFormatter: o.valueFormatter, itemsCreator: o.itemsCreator, onClickContinueSelect: function () { self.switcher.hideView(); } }, o.popup), adapter: o.adapter, masker: o.masker }); this.switcher.on(BI.Switcher.EVENT_TRIGGER_CHANGE, function () { self.fireEvent(BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE); }); this.switcher.on(BI.Switcher.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW); }); this.switcher.on(BI.Switcher.EVENT_AFTER_POPUPVIEW, function () { var me = this; BI.nextTick(function () { me.populate(); }); }); this.switcher.element.click(function (e) { e.stopPropagation(); }); }, adjustView: function () { this.switcher.adjustView(); }, hideView: function () { this.switcher.empty(); this.switcher.hideView(); }, setAdapter: function (adapter) { this.switcher.setAdapter(adapter); }, setValue: function (v) { this.switcher.setValue(v); }, setButtonChecked: function (v) { this.button.setValue(v); }, getValue: function () { }, populate: function (items) { this.switcher.populate.apply(this.switcher, arguments); } }); BI.MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE = "MultiSelectCheckSelectedSwitcher.EVENT_TRIGGER_CHANGE"; BI.MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW = "MultiSelectCheckSelectedSwitcher.EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.multi_select_check_selected_switcher", BI.MultiSelectCheckSelectedSwitcher);/** * Created by zcf_1 on 2017/5/2. */ BI.MultiSelectInsertList = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectInsertList.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-insert-list", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn }); }, _init: function () { BI.MultiSelectInsertList.superclass._init.apply(this, arguments); var self = this, o = this.options; this.storeValue = {}; var assertShowValue = function () { BI.isKey(self._startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](self._startValue); // self.trigger.setValue(self.storeValue); }; this.adapter = BI.createWidget({ type: "bi.multi_select_loader", cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, logic: { dynamic: false }, // onLoaded: o.onLoaded, el: {} }); this.adapter.on(BI.MultiSelectLoader.EVENT_CHANGE, function () { self.storeValue = this.getValue(); assertShowValue(); self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); }); this.searcherPane = BI.createWidget({ type: "bi.multi_select_search_pane", cls: "bi-border-left bi-border-right bi-border-bottom", valueFormatter: o.valueFormatter, keywordGetter: function () { return self.trigger.getKeyword(); }, itemsCreator: function (op, callback) { op.keyword = self.trigger.getKeyword(); this.setKeyword(op.keyword); o.itemsCreator(op, callback); } }); this.searcherPane.setVisible(false); this.trigger = BI.createWidget({ type: "bi.searcher", isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback(); }, adapter: this.adapter, popup: this.searcherPane, height: 200, masker: false, listeners: [{ eventName: BI.Searcher.EVENT_START, action: function () { self._showSearcherPane(); self._setStartValue(""); this.setValue(BI.deepClone(self.storeValue)); } }, { eventName: BI.Searcher.EVENT_STOP, action: function () { self._showAdapter(); self._setStartValue(""); self.adapter.setValue(self.storeValue); // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 self.adapter.populate(); } }, { eventName: BI.Searcher.EVENT_PAUSE, action: function () { var keyword = this.getKeyword(); if (this.hasMatched()) { self._join({ type: BI.Selection.Multi, value: [keyword] }, function () { if (self.storeValue.type === BI.Selection.Multi) { self.storeValue.value.pushDistinct(keyword); } self._showAdapter(); self.adapter.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); self.adapter.populate(); self._setStartValue(""); self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); }); } else { if (self.storeValue.type === BI.Selection.Multi) { self.storeValue.value.pushDistinct(keyword); } self._showAdapter(); self.adapter.setValue(self.storeValue); self.adapter.populate(); if (self.storeValue.type === BI.Selection.Multi) { self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); } } } }, { eventName: BI.Searcher.EVENT_SEARCHING, action: function () { var keywords = this.getKeyword(); var last = BI.last(keywords); keywords = BI.initial(keywords || []); if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { self.adapter.setValue(self.storeValue); assertShowValue(); self.adapter.populate(); self._setStartValue(""); } else { self.adapter.setValue(self.storeValue); assertShowValue(); } }); } } }, { eventName: BI.Searcher.EVENT_CHANGE, action: function (value, obj) { if (obj instanceof BI.MultiSelectBar) { self._joinAll(this.getValue(), function () { assertShowValue(); self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); }); } else { self._join(this.getValue(), function () { assertShowValue(); self.fireEvent(BI.MultiSelectInsertList.EVENT_CHANGE); }); } } }] }); BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.trigger, height: 24 }, { el: this.adapter, height: "fill" }] }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.searcherPane, top: 30, bottom: 0, left: 0, right: 0 }] }); }, _showAdapter: function () { this.adapter.setVisible(true); this.searcherPane.setVisible(false); }, _showSearcherPane: function () { this.searcherPane.setVisible(true); this.adapter.setVisible(false); }, _defaultState: function () { this.trigger.stopEditing(); }, _assertValue: function (val) { val || (val = {}); val.type || (val.type = BI.Selection.Multi); val.value || (val.value = []); }, _makeMap: function (values) { return BI.makeObject(values || []); }, _joinKeywords: function (keywords, callback) { var self = this, o = this.options; this._assertValue(this.storeValue); if (!this._allData) { o.itemsCreator({ type: BI.MultiSelectInsertList.REQ_GET_ALL_DATA }, function (ob) { self._allData = BI.pluck(ob.items, "value"); digest(self._allData); }); } else { digest(this._allData); } function digest (items) { var selectedMap = self._makeMap(items); BI.each(keywords, function (i, val) { if (BI.isNotNull(selectedMap[val])) { self.storeValue.value[self.storeValue.type === BI.Selection.Multi ? "pushDistinct" : "remove"](val); } }); callback(); } }, _joinAll: function (res, callback) { var self = this, o = this.options; this._assertValue(res); o.itemsCreator({ type: BI.MultiSelectInsertList.REQ_GET_ALL_DATA, keyword: self.trigger.getKeyword() }, function (ob) { var items = BI.pluck(ob.items, "value"); if (self.storeValue.type === res.type) { var change = false; var map = self._makeMap(self.storeValue.value); BI.each(items, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (self.storeValue.value = BI.values(map)); callback(); return; } var selectedMap = self._makeMap(self.storeValue.value); var notSelectedMap = self._makeMap(res.value); var newItems = []; BI.each(items, function (i, item) { if (BI.isNotNull(selectedMap[items[i]])) { delete selectedMap[items[i]]; } if (BI.isNull(notSelectedMap[items[i]])) { newItems.push(item); } }); self.storeValue.value = newItems.concat(BI.values(selectedMap)); callback(); }); }, _join: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this._assertValue(this.storeValue); if (this.storeValue.type === res.type) { var map = this._makeMap(this.storeValue.value); BI.each(res.value, function (i, v) { if (!map[v]) { self.storeValue.value.push(v); map[v] = v; } }); var change = false; BI.each(res.assist, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (this.storeValue.value = BI.values(map)); callback(); return; } this._joinAll(res, callback); }, _setStartValue: function (value) { this._startValue = value; this.adapter.setStartValue(value); }, isAllSelected: function () { return this.adapter.isAllSelected(); }, resize: function () { // this.trigger.getCounter().adjustView(); // this.trigger.adjustView(); }, setValue: function (v) { this.storeValue = v || {}; this._assertValue(this.storeValue); this.adapter.setValue(this.storeValue); this.trigger.setValue(this.storeValue); }, getValue: function () { return BI.deepClone(this.storeValue); }, populate: function () { this._count = null; this._allData = null; this.adapter.populate.apply(this.adapter, arguments); this.trigger.populate.apply(this.trigger, arguments); } }); BI.extend(BI.MultiSelectInsertList, { REQ_GET_DATA_LENGTH: 0, REQ_GET_ALL_DATA: -1 }); BI.MultiSelectInsertList.EVENT_CHANGE = "BI.MultiSelectInsertList.EVENT_CHANGE"; BI.shortcut("bi.multi_select_insert_list", BI.MultiSelectInsertList);/** * Created by zcf_1 on 2017/5/2. */ BI.MultiSelectList = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectList.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-list", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn }); }, _init: function () { BI.MultiSelectList.superclass._init.apply(this, arguments); var self = this, o = this.options; this.storeValue = {}; var assertShowValue = function () { BI.isKey(self._startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](self._startValue); // self.trigger.setValue(self.storeValue); }; this.adapter = BI.createWidget({ type: "bi.multi_select_loader", cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom", itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, logic: { dynamic: false }, // onLoaded: o.onLoaded, el: {} }); this.adapter.on(BI.MultiSelectLoader.EVENT_CHANGE, function () { self.storeValue = this.getValue(); self._adjust(function () { assertShowValue(); self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); }); }); this.searcherPane = BI.createWidget({ type: "bi.multi_select_search_pane", cls: "bi-border-left bi-border-right bi-border-bottom", valueFormatter: o.valueFormatter, keywordGetter: function () { return self.trigger.getKeyword(); }, itemsCreator: function (op, callback) { op.keyword = self.trigger.getKeyword(); this.setKeyword(op.keyword); o.itemsCreator(op, callback); } }); this.searcherPane.setVisible(false); this.trigger = BI.createWidget({ type: "bi.searcher", isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback(); }, adapter: this.adapter, popup: this.searcherPane, height: 200, masker: false, listeners: [{ eventName: BI.Searcher.EVENT_START, action: function () { self._showSearcherPane(); self._setStartValue(""); this.setValue(BI.deepClone(self.storeValue)); } }, { eventName: BI.Searcher.EVENT_STOP, action: function () { self._showAdapter(); self._setStartValue(""); self.adapter.setValue(self.storeValue); // 需要刷新回到初始界面,否则搜索的结果不能放在最前面 self.adapter.populate(); } }, { eventName: BI.Searcher.EVENT_PAUSE, action: function () { var keyword = this.getKeyword(); if (this.hasMatched()) { self._join({ type: BI.Selection.Multi, value: [keyword] }, function () { self._showAdapter(); self.adapter.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); self.adapter.populate(); self._setStartValue(""); self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); }); } } }, { eventName: BI.Searcher.EVENT_SEARCHING, action: function () { var keywords = this.getKeyword(); var last = BI.last(keywords); keywords = BI.initial(keywords || []); if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { self.adapter.setValue(self.storeValue); assertShowValue(); self.adapter.populate(); self._setStartValue(""); } else { self.adapter.setValue(self.storeValue); assertShowValue(); } }); } } }, { eventName: BI.Searcher.EVENT_CHANGE, action: function (value, obj) { if (obj instanceof BI.MultiSelectBar) { self._joinAll(this.getValue(), function () { assertShowValue(); self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); }); } else { self._join(this.getValue(), function () { assertShowValue(); self.fireEvent(BI.MultiSelectList.EVENT_CHANGE); }); } } }] }); BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.trigger, height: 24 }, { el: this.adapter, height: "fill" }] }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.searcherPane, top: 30, bottom: 0, left: 0, right: 0 }] }); }, _showAdapter: function () { this.adapter.setVisible(true); this.searcherPane.setVisible(false); }, _showSearcherPane: function () { this.searcherPane.setVisible(true); this.adapter.setVisible(false); }, _defaultState: function () { this.trigger.stopEditing(); }, _assertValue: function (val) { val || (val = {}); val.type || (val.type = BI.Selection.Multi); val.value || (val.value = []); }, _makeMap: function (values) { return BI.makeObject(values || []); }, _joinKeywords: function (keywords, callback) { var self = this, o = this.options; this._assertValue(this.storeValue); if (!this._allData) { o.itemsCreator({ type: BI.MultiSelectList.REQ_GET_ALL_DATA }, function (ob) { self._allData = BI.pluck(ob.items, "value"); digest(self._allData); }); } else { digest(this._allData); } function digest (items) { var selectedMap = self._makeMap(items); BI.each(keywords, function (i, val) { if (BI.isNotNull(selectedMap[val])) { self.storeValue.value[self.storeValue.type === BI.Selection.Multi ? "pushDistinct" : "remove"](val); } }); self._adjust(callback); } }, _joinAll: function (res, callback) { var self = this, o = this.options; this._assertValue(res); o.itemsCreator({ type: BI.MultiSelectList.REQ_GET_ALL_DATA, keyword: self.trigger.getKeyword() }, function (ob) { var items = BI.pluck(ob.items, "value"); if (self.storeValue.type === res.type) { var change = false; var map = self._makeMap(self.storeValue.value); BI.each(items, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (self.storeValue.value = BI.values(map)); self._adjust(callback); return; } var selectedMap = self._makeMap(self.storeValue.value); var notSelectedMap = self._makeMap(res.value); var newItems = []; BI.each(items, function (i, item) { if (BI.isNotNull(selectedMap[items[i]])) { delete selectedMap[items[i]]; } if (BI.isNull(notSelectedMap[items[i]])) { newItems.push(item); } }); self.storeValue.value = newItems.concat(BI.values(selectedMap)); self._adjust(callback); }); }, _adjust: function (callback) { var self = this, o = this.options; if (!this._count) { o.itemsCreator({ type: BI.MultiSelectList.REQ_GET_DATA_LENGTH }, function (res) { self._count = res.count; adjust(); callback(); }); } else { adjust(); callback(); } function adjust () { if (self.storeValue.type === BI.Selection.All && self.storeValue.value.length >= self._count) { self.storeValue = { type: BI.Selection.Multi, value: [] }; } else if (self.storeValue.type === BI.Selection.Multi && self.storeValue.value.length >= self._count) { self.storeValue = { type: BI.Selection.All, value: [] }; } } }, _join: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this._assertValue(this.storeValue); if (this.storeValue.type === res.type) { var map = this._makeMap(this.storeValue.value); BI.each(res.value, function (i, v) { if (!map[v]) { self.storeValue.value.push(v); map[v] = v; } }); var change = false; BI.each(res.assist, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (this.storeValue.value = BI.values(map)); self._adjust(callback); return; } this._joinAll(res, callback); }, _setStartValue: function (value) { this._startValue = value; this.adapter.setStartValue(value); }, isAllSelected: function () { return this.adapter.isAllSelected(); }, resize: function () { // this.trigger.getCounter().adjustView(); // this.trigger.adjustView(); }, setValue: function (v) { this.storeValue = v || {}; this._assertValue(this.storeValue); this.adapter.setValue(this.storeValue); this.trigger.setValue(this.storeValue); }, getValue: function () { return BI.deepClone(this.storeValue); }, populate: function () { this._count = null; this._allData = null; this.adapter.populate.apply(this.adapter, arguments); this.trigger.populate.apply(this.trigger, arguments); } }); BI.extend(BI.MultiSelectList, { REQ_GET_DATA_LENGTH: 0, REQ_GET_ALL_DATA: -1 }); BI.MultiSelectList.EVENT_CHANGE = "BI.MultiSelectList.EVENT_CHANGE"; BI.shortcut("bi.multi_select_list", BI.MultiSelectList);/** * Created by zcf_1 on 2017/5/11. */ BI.MultiSelectTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-tree", itemsCreator: BI.emptyFn }); }, _init: function () { BI.MultiSelectTree.superclass._init.apply(this, arguments); var self = this, o = this.options; this.storeValue = {value: {}}; this.adapter = BI.createWidget({ type: "bi.multi_select_tree_popup", itemsCreator: o.itemsCreator }); this.adapter.on(BI.MultiSelectTreePopup.EVENT_CHANGE, function () { if (self.searcher.isSearching()) { self.storeValue = {value: self.searcherPane.getValue()}; } else { self.storeValue = {value: self.adapter.getValue()}; } self.setSelectedValue(self.storeValue.value); self.fireEvent(BI.MultiSelectTree.EVENT_CHANGE); }); // 搜索中的时候用的是parttree,同adapter中的synctree不一样 this.searcherPane = BI.createWidget({ type: "bi.multi_tree_search_pane", cls: "bi-border-left bi-border-right bi-border-bottom", keywordGetter: function () { return self.searcher.getKeyword(); }, itemsCreator: function (op, callback) { op.keyword = self.searcher.getKeyword(); o.itemsCreator(op, callback); } }); this.searcherPane.setVisible(false); this.searcher = BI.createWidget({ type: "bi.searcher", isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback({ keyword: self.searcher.getKeyword() }); }, adapter: this.adapter, popup: this.searcherPane, masker: false, listeners: [{ eventName: BI.Searcher.EVENT_START, action: function () { self._showSearcherPane(); // self.storeValue = {value: self.adapter.getValue()}; // self.searcherPane.setSelectedValue(self.storeValue.value); } }, { eventName: BI.Searcher.EVENT_STOP, action: function () { self._showAdapter(); // self.storeValue = {value: self.searcherPane.getValue()}; // self.adapter.setSelectedValue(self.storeValue.value); BI.nextTick(function () { self.adapter.populate(); }); } }, { eventName: BI.Searcher.EVENT_CHANGE, action: function () { if (self.searcher.isSearching()) { self.storeValue = {value: self.searcherPane.getValue()}; } else { self.storeValue = {value: self.adapter.getValue()}; } self.setSelectedValue(self.storeValue.value); self.fireEvent(BI.MultiSelectTree.EVENT_CHANGE); } }, { eventName: BI.Searcher.EVENT_PAUSE, action: function () { self._showAdapter(); } }] }); BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.searcher, height: 24 }, { el: this.adapter, height: "fill" }] }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.searcherPane, top: 30, bottom: 0, left: 0, right: 0 }] }); }, _showAdapter: function () { this.adapter.setVisible(true); this.searcherPane.setVisible(false); }, _showSearcherPane: function () { this.searcherPane.setVisible(true); this.adapter.setVisible(false); }, resize: function () { }, setSelectedValue: function (v) { this.storeValue.value = v || {}; this.adapter.setSelectedValue(v); this.searcherPane.setSelectedValue(v); this.searcher.setValue({ value: v || {} }); }, setValue: function (v) { this.adapter.setValue(v); }, stopSearch: function () { this.searcher.stopSearch(); }, updateValue: function (v) { this.adapter.updateValue(v); }, getValue: function () { return this.storeValue.value; }, populate: function () { this.searcher.populate.apply(this.searcher, arguments); this.adapter.populate.apply(this.adapter, arguments); } }); BI.MultiSelectTree.EVENT_CHANGE = "BI.MultiSelectTree.EVENT_CHANGE"; BI.shortcut("bi.multi_select_tree", BI.MultiSelectTree);/** * Created by zcf on 2016/12/21. */ BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectTreePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-select-tree-popup bi-border-left bi-border-right bi-border-bottom", itemsCreator: BI.emptyFn }); }, _init: function () { BI.MultiSelectTreePopup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.popup = BI.createWidget({ type: "bi.async_tree", element: this, itemsCreator: o.itemsCreator }); this.popup.on(BI.TreeView.EVENT_AFTERINIT, function () { self.fireEvent(BI.MultiSelectTreePopup.EVENT_AFTER_INIT); }); this.popup.on(BI.TreeView.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectTreePopup.EVENT_CHANGE); }); }, hasChecked: function () { return this.popup.hasChecked(); }, getValue: function () { return this.popup.getValue(); }, setValue: function (v) { v || (v = {}); this.popup.setValue(v); }, setSelectedValue: function (v) { v || (v = {}); this.popup.setSelectedValue(v); }, updateValue: function (v) { this.popup.updateValue(v); this.popup.refresh(); }, populate: function (config) { this.popup.stroke(config); } }); BI.MultiSelectTreePopup.EVENT_AFTER_INIT = "BI.MultiSelectTreePopup.EVENT_AFTER_INIT"; BI.MultiSelectTreePopup.EVENT_CHANGE = "BI.MultiSelectTreePopup.EVENT_CHANGE"; BI.shortcut("bi.multi_select_tree_popup", BI.MultiSelectTreePopup);/** * * @class BI.MultiTreeCheckPane * @extends BI.Pane */ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { constants: { height: 25, lgap: 10, tgap: 5 }, _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", onClickContinueSelect: BI.emptyFn }); }, _init: function () { BI.MultiTreeCheckPane.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.selectedValues = {}; var continueSelect = BI.createWidget({ type: "bi.text_button", text: BI.i18nText("BI-Continue_Select"), cls: "multi-tree-check-selected" }); continueSelect.on(BI.TextButton.EVENT_CHANGE, function () { opts.onClickContinueSelect(); BI.nextTick(function () { self.empty(); }); }); var backToPopup = BI.createWidget({ type: "bi.left", cls: "multi-tree-continue-select", items: [ { el: { type: "bi.label", text: BI.i18nText("BI-Selected_Data") }, lgap: this.constants.lgap, tgap: this.constants.tgap }, { el: continueSelect, lgap: this.constants.lgap, tgap: this.constants.tgap }] }); this.display = BI.createWidget({ type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { op.type = BI.TreeView.REQ_TYPE_GET_SELECTED_DATA; opts.itemsCreator(op, callback); } }); this.display.on(BI.Events.AFTERINIT, function () { self.fireEvent(BI.Events.AFTERINIT); }); this.display.on(BI.TreeView.EVENT_INIT, function () { backToPopup.setVisible(false); }); this.display.on(BI.TreeView.EVENT_AFTERINIT, function () { backToPopup.setVisible(true); }); BI.createWidget({ type: "bi.vtape", element: this, items: [{ height: this.constants.height, el: backToPopup }, { height: "fill", el: this.display }] }); }, empty: function () { this.display.empty(); }, populate: function (configs) { this.display.stroke(configs); }, setValue: function (v) { v || (v = {}); this.display.setSelectedValue(v.value); }, getValue: function () { } }); BI.MultiTreeCheckPane.EVENT_CONTINUE_CLICK = "EVENT_CONTINUE_CLICK"; BI.shortcut("bi.multi_tree_check_pane", BI.MultiTreeCheckPane);/** * * @class BI.MultiTreeCombo * @extends BI.Single */ BI.MultiTreeCombo = BI.inherit(BI.Single, { constants: { offset: { top: 1, left: 1, right: 2, bottom: 33 } }, _defaultConfig: function () { return BI.extend(BI.MultiTreeCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-combo", itemsCreator: BI.emptyFn, height: 25 }); }, _init: function () { BI.MultiTreeCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; var isInit = false; var want2showCounter = false; this.trigger = BI.createWidget({ type: "bi.multi_select_trigger", height: o.height, // adapter: this.popup, masker: { offset: this.constants.offset }, searcher: { type: "bi.multi_tree_searcher", itemsCreator: o.itemsCreator }, switcher: { el: { type: "bi.multi_tree_check_selected_button" }, popup: { type: "bi.multi_tree_check_pane", itemsCreator: o.itemsCreator } } }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, el: this.trigger, adjustLength: 1, popup: { type: "bi.multi_tree_popup_view", ref: function () { self.popup = this; self.trigger.setAdapter(this); }, listeners: [{ eventName: BI.MultiTreePopup.EVENT_AFTERINIT, action: function () { self.trigger.getCounter().adjustView(); isInit = true; if (want2showCounter === true) { showCounter(); } } }, { eventName: BI.MultiTreePopup.EVENT_CHANGE, action: function () { change = true; var val = { type: BI.Selection.Multi, value: this.hasChecked() ? this.getValue() : {} }; self.trigger.getSearcher().setState(val); self.trigger.getCounter().setButtonChecked(val); } }, { eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, action: function () { self.combo.hideView(); } }, { eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, action: function () { clear = true; self.setValue(); self._defaultState(); } }], itemsCreator: o.itemsCreator, onLoaded: function () { BI.nextTick(function () { self.trigger.getCounter().adjustView(); self.trigger.getSearcher().adjustView(); }); } }, hideChecker: function (e) { return triggerBtn.element.find(e.target).length === 0; } }); this.storeValue = {value: {}}; var change = false; var clear = false; // 标识当前是否点击了清空 var isSearching = function () { return self.trigger.getSearcher().isSearching(); }; var isPopupView = function () { return self.combo.isViewVisible(); }; this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { self.storeValue = {value: self.combo.getValue()}; this.setValue(self.storeValue); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { self.storeValue = {value: this.getValue()}; self.combo.setValue(self.storeValue); BI.nextTick(function () { if (isPopupView()) { self.combo.populate(); } }); }); function showCounter () { if (isSearching()) { self.storeValue = {value: self.trigger.getValue()}; } else if (isPopupView()) { self.storeValue = {value: self.combo.getValue()}; } self.trigger.setValue(self.storeValue); } this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { if (want2showCounter === false) { want2showCounter = true; } if (isInit === true) { want2showCounter = null; showCounter(); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { self.combo.toggle(); }); this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { var checked = this.getSearcher().hasChecked(); var val = { type: BI.Selection.Multi, value: checked ? {1: 1} : {} }; this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); this.getCounter().setButtonChecked(val); }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { if (isSearching()) { return; } if (change === true) { self.storeValue = {value: self.combo.getValue()}; change = false; } self.combo.setValue(self.storeValue); self.populate(); }); this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { if (isSearching()) { self.trigger.stopEditing(); self.fireEvent(BI.MultiTreeCombo.EVENT_CONFIRM); } else { if (isPopupView()) { self.trigger.stopEditing(); self.storeValue = {value: self.combo.getValue()}; if (clear === true) { self.storeValue = {value: {}}; } self.fireEvent(BI.MultiTreeCombo.EVENT_CONFIRM); } } clear = false; change = false; }); var triggerBtn = BI.createWidget({ type: "bi.trigger_icon_button", width: o.height, height: o.height, cls: "multi-select-trigger-icon-button bi-border-left" }); triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { self.trigger.getCounter().hideView(); if (self.combo.isViewVisible()) { self.combo.hideView(); } else { self.combo.showView(); } }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.combo, left: 0, right: 0, top: 0, bottom: 0 }, { el: triggerBtn, right: 0, top: 0, bottom: 0 }] }); }, _defaultState: function () { this.trigger.stopEditing(); this.combo.hideView(); }, setValue: function (v) { this.storeValue.value = v || {}; this.combo.setValue({ value: v || {} }); }, getValue: function () { return this.storeValue.value; }, populate: function () { this.combo.populate.apply(this.combo, arguments); } }); BI.MultiTreeCombo.EVENT_CONFIRM = "MultiTreeCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_combo", BI.MultiTreeCombo);/** * 带加载的多选下拉面板 * @class BI.MultiTreePopup * @extends BI.Pane */ BI.MultiTreePopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-popup", maxWidth: "auto", minWidth: 100, maxHeight: 400, onLoaded: BI.emptyFn }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.selectedValues = {}; this.tree = BI.createWidget({ type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded }); this.popupView = BI.createWidget({ type: "bi.multi_popup_view", element: this, stopPropagation: false, maxWidth: opts.maxWidth, minWidth: opts.minWidth, maxHeight: opts.maxHeight, buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_Sure")], el: this.tree }); this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { switch (index) { case 0: self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CLEAR); break; case 1: self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CONFIRM); break; } }); this.tree.on(BI.TreeView.EVENT_CHANGE, function () { self.fireEvent(BI.MultiTreePopup.EVENT_CHANGE); }); this.tree.on(BI.TreeView.EVENT_AFTERINIT, function () { self.fireEvent(BI.MultiTreePopup.EVENT_AFTERINIT); }); }, getValue: function () { return this.tree.getValue(); }, setValue: function (v) { v || (v = {}); this.tree.setSelectedValue(v.value); }, populate: function (config) { this.tree.stroke(config); }, hasChecked: function () { return this.tree.hasChecked(); }, resetHeight: function (h) { this.popupView.resetHeight(h); }, resetWidth: function (w) { this.popupView.resetWidth(w); } }); BI.MultiTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiTreePopup.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; BI.MultiTreePopup.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** * * 在搜索框中输入文本弹出的面板 * @class BI.MultiTreeSearchPane * @extends BI.Pane */ BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-search-pane bi-card", itemsCreator: BI.emptyFn, keywordGetter: BI.emptyFn }); }, _init: function () { BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.partTree = BI.createWidget({ type: "bi.part_tree", element: this, tipText: BI.i18nText("BI-No_Select"), itemsCreator: function (op, callback) { op.keyword = opts.keywordGetter(); opts.itemsCreator(op, callback); } }); this.partTree.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); }); }, hasChecked: function () { return this.partTree.hasChecked(); }, setValue: function (v) { this.setSelectedValue(v.value); }, setSelectedValue: function (v) { v || (v = {}); this.partTree.setSelectedValue(v); }, getValue: function () { return this.partTree.getValue(); }, empty: function () { this.partTree.empty(); }, populate: function (op) { this.partTree.stroke.apply(this.partTree, arguments); } }); BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton * @extends BI.Single */ BI.MultiTreeCheckSelectedButton = BI.inherit(BI.Single, { _const: { checkSelected: BI.i18nText("BI-Check_Selected") }, _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckSelectedButton.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-selected-button", itemsCreator: BI.emptyFn }); }, _init: function () { BI.MultiTreeCheckSelectedButton.superclass._init.apply(this, arguments); var self = this; this.indicator = BI.createWidget({ type: "bi.icon_button", cls: "check-font trigger-check-selected", width: 15, height: 15, stopPropagation: true }); this.checkSelected = BI.createWidget({ type: "bi.text_button", cls: "trigger-check-selected", invisible: true, hgap: 4, text: this._const.checkSelected, textAlign: "center", textHeight: 15 }); this.checkSelected.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.checkSelected.on(BI.TextButton.EVENT_CHANGE, function () { self.fireEvent(BI.MultiSelectCheckSelectedButton.EVENT_CHANGE, arguments); }); BI.createWidget({ type: "bi.horizontal", element: this, items: [this.indicator, this.checkSelected] }); this.element.hover(function () { self.indicator.setVisible(false); self.checkSelected.setVisible(true); }, function () { self.indicator.setVisible(true); self.checkSelected.setVisible(false); }); this.setVisible(false); }, setValue: function (v) { v || (v = {}); this.setVisible(BI.size(v.value) > 0); } }); BI.MultiTreeCheckSelectedButton.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.multi_tree_check_selected_button", BI.MultiTreeCheckSelectedButton);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiTreeSearcher * @extends Widget */ BI.MultiTreeSearcher = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiTreeSearcher.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-searcher", itemsCreator: BI.emptyFn, popup: {}, adapter: null, masker: {} }); }, _init: function () { BI.MultiTreeSearcher.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.multi_select_editor", height: o.height, el: { type: "bi.simple_state_editor", height: o.height } }); this.searcher = BI.createWidget({ type: "bi.searcher", element: this, isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback({ keyword: self.editor.getValue() }); }, el: this.editor, popup: BI.extend({ type: "bi.multi_tree_search_pane", keywordGetter: function () { return self.editor.getValue(); }, itemsCreator: function (op, callback) { op.keyword = self.editor.getValue(); o.itemsCreator(op, callback); } }, o.popup), adapter: o.adapter, masker: o.masker }); this.searcher.on(BI.Searcher.EVENT_START, function () { self.fireEvent(BI.MultiTreeSearcher.EVENT_START); }); this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { if (this.hasMatched()) { } self.fireEvent(BI.MultiTreeSearcher.EVENT_PAUSE); }); this.searcher.on(BI.Searcher.EVENT_STOP, function () { self.fireEvent(BI.MultiTreeSearcher.EVENT_STOP); }); this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { self.fireEvent(BI.MultiTreeSearcher.EVENT_CHANGE, arguments); }); }, adjustView: function () { this.searcher.adjustView(); }, setAdapter: function (adapter) { this.searcher.setAdapter(adapter); }, isSearching: function () { return this.searcher.isSearching(); }, stopSearch: function () { this.searcher.stopSearch(); }, getKeyword: function () { return this.editor.getValue(); }, hasMatched: function () { return this.searcher.hasMatched(); }, hasChecked: function () { return this.searcher.getView() && this.searcher.getView().hasChecked(); }, setState: function (ob) { ob || (ob = {}); ob.value || (ob.value = {}); if (BI.isNumber(ob)) { this.editor.setState(ob); } else if (BI.size(ob.value) === 0) { this.editor.setState(BI.Selection.None); } else { var text = ""; BI.each(ob.value, function (name, children) { var childNodes = getChildrenNode(children); text += name + (childNodes === "" ? "" : (":" + childNodes)) + "; "; }); this.editor.setState(text); } function getChildrenNode (ob) { var text = ""; var index = 0, size = BI.size(ob); BI.each(ob, function (name, children) { index++; var childNodes = getChildrenNode(children); text += name + (childNodes === "" ? "" : (":" + childNodes)) + (index === size ? "" : ","); }); return text; } }, setValue: function (ob) { this.setState(ob); this.searcher.setValue(ob); }, getKey: function () { return this.editor.getValue(); }, getValue: function () { return this.searcher.getValue(); }, populate: function (items) { this.searcher.populate.apply(this.searcher, arguments); } }); BI.MultiTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.MultiTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; BI.MultiTreeSearcher.EVENT_START = "EVENT_START"; BI.MultiTreeSearcher.EVENT_STOP = "EVENT_STOP"; BI.MultiTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; BI.shortcut("bi.multi_tree_searcher", BI.MultiTreeSearcher);/** * Created by windy on 2017/3/13. * 数值微调器 */ BI.NumberEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.NumberEditor.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-number-editor bi-border", validationChecker: function () { return true; }, valueFormatter: function (v) { return v; }, value: 0, allowBlank: false, errorText: "", step: 1 }); }, _init: function () { BI.NumberEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.sign_editor", height: o.height, allowBlank: o.allowBlank, value: o.valueFormatter(o.value), validationChecker: o.validationChecker, errorText: o.errorText }); this.editor.on(BI.TextEditor.EVENT_CHANGE, function () { o.value = this.getValue(); self.fireEvent(BI.NumberEditor.EVENT_CHANGE); }); this.editor.on(BI.TextEditor.EVENT_CONFIRM, function () { self.fireEvent(BI.NumberEditor.EVENT_CONFIRM); }); this.topBtn = BI.createWidget({ type: "bi.icon_button", trigger: "lclick,", cls: "column-pre-page-h-font top-button bi-border-left bi-border-bottom" }); this.topBtn.on(BI.IconButton.EVENT_CHANGE, function () { self._finetuning(o.step); self.fireEvent(BI.NumberEditor.EVENT_CHANGE); self.fireEvent(BI.NumberEditor.EVENT_CONFIRM); }); this.bottomBtn = BI.createWidget({ type: "bi.icon_button", trigger: "lclick,", cls: "column-next-page-h-font bottom-button bi-border-left bi-border-top" }); this.bottomBtn.on(BI.IconButton.EVENT_CHANGE, function () { self._finetuning(-o.step); self.fireEvent(BI.NumberEditor.EVENT_CHANGE); self.fireEvent(BI.NumberEditor.EVENT_CONFIRM); }); BI.createWidget({ type: "bi.htape", element: this, items: [this.editor, { el: { type: "bi.grid", columns: 1, rows: 2, items: [{ column: 0, row: 0, el: this.topBtn }, { column: 0, row: 1, el: this.bottomBtn }] }, width: 23 }] }); }, // 微调 _finetuning: function (add) { var v = BI.parseFloat(this.getValue()); this.setValue(v.add(add)); }, setUpEnable: function (v) { this.topBtn.setEnable(!!v); }, setDownEnable: function (v) { this.bottomBtn.setEnable(!!v); }, getValue: function () { return this.options.value; }, setValue: function (v) { var o = this.options; o.value = v; this.editor.setValue(o.valueFormatter(v)); } }); BI.NumberEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.NumberEditor.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.number_editor", BI.NumberEditor);// 小于号的值为:0,小于等于号的值为:1 // closeMIn:最小值的符号,closeMax:最大值的符号 /** * Created by roy on 15/9/17. * */ BI.NumberInterval = BI.inherit(BI.Single, { constants: { typeError: "typeBubble", numberError: "numberBubble", signalError: "signalBubble", editorWidth: 114, columns: 5, width: 30, rows: 1, numberErrorCls: "number-error", border: 1, less: 0, less_equal: 1, numTip: "" }, _defaultConfig: function () { var conf = BI.NumberInterval.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-number-interval", height: 25, validation: "valid" }); }, _init: function () { var self = this, c = this.constants, o = this.options; BI.NumberInterval.superclass._init.apply(this, arguments); this.smallEditor = BI.createWidget({ type: "bi.editor", height: o.height - 2, watermark: BI.i18nText("BI-Basic_Unrestricted"), allowBlank: true, value: o.min, level: "warning", tipType: "warning", quitChecker: function () { return false; }, validationChecker: function (v) { if (!BI.isNumeric(v)) { self.smallEditorBubbleType = c.typeError; return false; } return true; }, cls: "number-interval-small-editor bi-border-top bi-border-bottom bi-border-left" }); this.smallTip = BI.createWidget({ type: "bi.label", text: o.numTip, height: o.height - 2, invisible: true }); BI.createWidget({ type: "bi.absolute", element: this.smallEditor.element, items: [{ el: this.smallTip, top: 0, right: 5 }] }); this.bigEditor = BI.createWidget({ type: "bi.editor", height: o.height - 2, watermark: BI.i18nText("BI-Basic_Unrestricted"), allowBlank: true, value: o.max, level: "warning", tipType: "warning", quitChecker: function () { return false; }, validationChecker: function (v) { if (!BI.isNumeric(v)) { self.bigEditorBubbleType = c.typeError; return false; } return true; }, cls: "number-interval-big-editor bi-border-top bi-border-bottom bi-border-right" }); this.bigTip = BI.createWidget({ type: "bi.label", text: o.numTip, height: o.height - 2, invisible: true }); BI.createWidget({ type: "bi.absolute", element: this.bigEditor.element, items: [{ el: this.bigTip, top: 0, right: 5 }] }); // this.smallCombo = BI.createWidget({ // type: "bi.number_interval_combo", // cls: "number-interval-small-combo", // height: o.height, // value: o.closemin ? 1 : 0, // offsetStyle: "left" // }); // // this.bigCombo = BI.createWidget({ // type: "bi.number_interval_combo", // cls: "number-interval-big-combo", // height: o.height, // value: o.closemax ? 1 : 0, // offsetStyle: "left" // }); this.smallCombo = BI.createWidget({ type: "bi.icon_combo", cls: "number-interval-small-combo bi-border", height: o.height - 2, items: [{ text: "(" + BI.i18nText("BI-Less_Than") + ")", iconClass: "less-font", value: 0 }, { text: "(" + BI.i18nText("BI-Less_And_Equal") + ")", value: 1, iconClass: "less-equal-font" }] }); if (o.closemin === true) { this.smallCombo.setValue(1); } else { this.smallCombo.setValue(0); } this.bigCombo = BI.createWidget({ type: "bi.icon_combo", cls: "number-interval-big-combo bi-border", height: o.height - 2, items: [{ text: "(" + BI.i18nText("BI-Less_Than") + ")", iconClass: "less-font", value: 0 }, { text: "(" + BI.i18nText("BI-Less_And_Equal") + ")", value: 1, iconClass: "less-equal-font" }] }); if (o.closemax === true) { this.bigCombo.setValue(1); } else { this.bigCombo.setValue(0); } this.label = BI.createWidget({ type: "bi.label", text: BI.i18nText("BI-Basic_Value"), textHeight: o.height - c.border * 2, width: c.width - c.border * 2, height: o.height - c.border * 2, level: "warning", tipType: "warning" }); this.left = BI.createWidget({ type: "bi.htape", items: [{ el: self.smallEditor }, { el: self.smallCombo, width: c.width - c.border * 2 }] }); this.right = BI.createWidget({ type: "bi.htape", items: [{ el: self.bigCombo, width: c.width - c.border * 2 }, { el: self.bigEditor }] }); BI.createWidget({ element: self, type: "bi.center", hgap: 15, height: o.height, items: [ { type: "bi.absolute", items: [{ el: self.left, left: -15, right: 0, top: 0, bottom: 0 }] }, { type: "bi.absolute", items: [{ el: self.right, left: 0, right: -15, top: 0, bottom: 0 }] } ] }); BI.createWidget({ element: self, type: "bi.horizontal_auto", items: [ self.label ] }); self._setValidEvent(self.bigEditor, c.bigEditor); self._setValidEvent(self.smallEditor, c.smallEditor); self._setErrorEvent(self.bigEditor, c.bigEditor); self._setErrorEvent(self.smallEditor, c.smallEditor); self._setBlurEvent(self.bigEditor); self._setBlurEvent(self.smallEditor); self._setFocusEvent(self.bigEditor); self._setFocusEvent(self.smallEditor); self._setComboValueChangedEvent(self.bigCombo); self._setComboValueChangedEvent(self.smallCombo); self._setEditorValueChangedEvent(self.bigEditor); self._setEditorValueChangedEvent(self.smallEditor); }, _checkValidation: function () { var self = this, c = this.constants, o = this.options; self._setTitle(""); BI.Bubbles.hide(c.typeError); BI.Bubbles.hide(c.numberError); BI.Bubbles.hide(c.signalError); if (!self.smallEditor.isValid() || !self.bigEditor.isValid()) { self.element.removeClass("number-error"); o.validation = "invalid"; return c.typeError; } if (BI.isEmptyString(self.smallEditor.getValue()) || BI.isEmptyString(self.bigEditor.getValue())) { self.element.removeClass("number-error"); o.validation = "valid"; return ""; } var smallValue = parseFloat(self.smallEditor.getValue()), bigValue = parseFloat(self.bigEditor.getValue()), bigComboValue = self.bigCombo.getValue(), smallComboValue = self.smallCombo.getValue(); if (bigComboValue[0] === c.less_equal && smallComboValue[0] === c.less_equal) { if (smallValue > bigValue) { self.element.addClass("number-error"); o.validation = "invalid"; return c.numberError; } self.element.removeClass("number-error"); o.validation = "valid"; return ""; } if (smallValue > bigValue) { self.element.addClass("number-error"); o.validation = "invalid"; return c.numberError; } else if (smallValue === bigValue) { self.element.addClass("number-error"); o.validation = "invalid"; return c.signalError; } self.element.removeClass("number-error"); o.validation = "valid"; return ""; }, _setTitle: function (v) { var self = this; self.bigEditor.setTitle(v); self.smallEditor.setTitle(v); self.label.setTitle(v); }, _setFocusEvent: function (w) { var self = this, c = this.constants; w.on(BI.Editor.EVENT_FOCUS, function () { self._setTitle(""); switch (self._checkValidation()) { case c.typeError: BI.Bubbles.show(c.typeError, BI.i18nText("BI-Numerical_Interval_Input_Data"), self, { offsetStyle: "center" }); break; case c.numberError: BI.Bubbles.show(c.numberError, BI.i18nText("BI-Numerical_Interval_Number_Value"), self, { offsetStyle: "center" }); break; case c.signalError: BI.Bubbles.show(c.signalError, BI.i18nText("BI-Numerical_Interval_Signal_Value"), self, { offsetStyle: "center" }); break; default : return; } }); }, _setBlurEvent: function (w) { var c = this.constants, self = this; w.on(BI.Editor.EVENT_BLUR, function () { BI.Bubbles.hide(c.typeError); BI.Bubbles.hide(c.numberError); BI.Bubbles.hide(c.signalError); switch (self._checkValidation()) { case c.typeError: self._setTitle(BI.i18nText("BI-Numerical_Interval_Input_Data")); break; case c.numberError: self._setTitle(BI.i18nText("BI-Numerical_Interval_Number_Value")); break; case c.signalError: self._setTitle(BI.i18nText("BI-Numerical_Interval_Signal_Value")); break; default: self._setTitle(""); } }); }, _setErrorEvent: function (w) { var c = this.constants, self = this; w.on(BI.Editor.EVENT_ERROR, function () { self._checkValidation(); BI.Bubbles.show(c.typeError, BI.i18nText("BI-Numerical_Interval_Input_Data"), self, { offsetStyle: "center" }); self.fireEvent(BI.NumberInterval.EVENT_ERROR); }); }, _setValidEvent: function (w) { var self = this, c = this.constants; w.on(BI.Editor.EVENT_VALID, function () { switch (self._checkValidation()) { case c.numberError: BI.Bubbles.show(c.numberError, BI.i18nText("BI-Numerical_Interval_Number_Value"), self, { offsetStyle: "center" }); self.fireEvent(BI.NumberInterval.EVENT_ERROR); break; case c.signalError: BI.Bubbles.show(c.signalError, BI.i18nText("BI-Numerical_Interval_Signal_Value"), self, { offsetStyle: "center" }); self.fireEvent(BI.NumberInterval.EVENT_ERROR); break; default: self.fireEvent(BI.NumberInterval.EVENT_VALID); } }); }, _setEditorValueChangedEvent: function (w) { var self = this, c = this.constants; w.on(BI.Editor.EVENT_CHANGE, function () { switch (self._checkValidation()) { case c.typeError: BI.Bubbles.show(c.typeError, BI.i18nText("BI-Numerical_Interval_Input_Data"), self, { offsetStyle: "center" }); break; case c.numberError: BI.Bubbles.show(c.numberError, BI.i18nText("BI-Numerical_Interval_Number_Value"), self, { offsetStyle: "center" }); break; case c.signalError: BI.Bubbles.show(c.signalError, BI.i18nText("BI-Numerical_Interval_Signal_Value"), self, { offsetStyle: "center" }); break; default : break; } self.fireEvent(BI.NumberInterval.EVENT_CHANGE); }); }, _setComboValueChangedEvent: function (w) { var self = this, c = this.constants; w.on(BI.IconCombo.EVENT_CHANGE, function () { switch (self._checkValidation()) { case c.typeError: self._setTitle(BI.i18nText("BI-Numerical_Interval_Input_Data")); self.fireEvent(BI.NumberInterval.EVENT_ERROR); break; case c.numberError: self._setTitle(BI.i18nText("BI-Numerical_Interval_Number_Value")); self.fireEvent(BI.NumberInterval.EVENT_ERROR); break; case c.signalError: self._setTitle(BI.i18nText("BI-Numerical_Interval_Signal_Value")); self.fireEvent(BI.NumberInterval.EVENT_ERROR); break; default : self.fireEvent(BI.NumberInterval.EVENT_CHANGE); self.fireEvent(BI.NumberInterval.EVENT_VALID); } }); }, isStateValid: function () { return this.options.validation === "valid"; }, setMinEnable: function (b) { this.smallEditor.setEnable(b); }, setCloseMinEnable: function (b) { this.smallCombo.setEnable(b); }, setMaxEnable: function (b) { this.bigEditor.setEnable(b); }, setCloseMaxEnable: function (b) { this.bigCombo.setEnable(b); }, showNumTip: function () { this.smallTip.setVisible(true); this.bigTip.setVisible(true); }, hideNumTip: function () { this.smallTip.setVisible(false); this.bigTip.setVisible(false); }, setNumTip: function (numTip) { this.smallTip.setText(numTip); this.bigTip.setText(numTip); }, getNumTip: function () { return this.smallTip.getText(); }, setValue: function (data) { data = data || {}; var self = this, combo_value; if (BI.isNumeric(data.min) || BI.isEmptyString(data.min)) { self.smallEditor.setValue(data.min); } if (!BI.isNotNull(data.min)) { self.smallEditor.setValue(""); } if (BI.isNumeric(data.max) || BI.isEmptyString(data.max)) { self.bigEditor.setValue(data.max); } if (!BI.isNotNull(data.max)) { self.bigEditor.setValue(""); } if (!BI.isNull(data.closemin)) { if (data.closemin === true) { combo_value = 1; } else { combo_value = 0; } self.smallCombo.setValue(combo_value); } if (!BI.isNull(data.closemax)) { if (data.closemax === true) { combo_value = 1; } else { combo_value = 0; } self.bigCombo.setValue(combo_value); } }, getValue: function () { var self = this, value = {}, minComboValue = self.smallCombo.getValue(), maxComboValue = self.bigCombo.getValue(); value.min = self.smallEditor.getValue(); value.max = self.bigEditor.getValue(); if (minComboValue[0] === 0) { value.closemin = false; } else { value.closemin = true; } if (maxComboValue[0] === 0) { value.closemax = false; } else { value.closemax = true; } return value; } }); BI.NumberInterval.EVENT_CHANGE = "EVENT_CHANGE"; BI.NumberInterval.EVENT_VALID = "EVENT_VALID"; BI.NumberInterval.EVENT_ERROR = "EVENT_ERROR"; BI.shortcut("bi.number_interval", BI.NumberInterval);/** * * 表格 * * Created by GUY on 2015/9/22. * @class BI.PageTableCell * @extends BI.Single */ BI.PageTableCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PageTableCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-page-table-cell", text: "", title: "" }); }, _init: function () { BI.PageTableCell.superclass._init.apply(this, arguments); var label = BI.createWidget({ type: "bi.label", element: this, textAlign: "left", whiteSpace: "nowrap", height: this.options.height, text: this.options.text, title: this.options.title, value: this.options.value, lgap: 5, rgap: 5 }); if (BI.isNotNull(this.options.styles) && BI.isObject(this.options.styles)) { this.element.css(this.options.styles); } } }); BI.shortcut("bi.page_table_cell", BI.PageTableCell);/** * 分页表格 * * Created by GUY on 2016/2/15. * @class BI.PageTable * @extends BI.Widget */ BI.PageTable = BI.inherit(BI.Widget, { _const: { scrollWidth: 18, minScrollWidth: 100 }, _defaultConfig: function () { return BI.extend(BI.PageTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-page-table", el: { type: "bi.sequence_table" }, pager: { horizontal: { pages: false, // 总页数 curr: 1, // 初始化当前页, pages为数字时可用 hasPrev: BI.emptyFn, hasNext: BI.emptyFn, firstPage: 1, lastPage: BI.emptyFn }, vertical: { pages: false, // 总页数 curr: 1, // 初始化当前页, pages为数字时可用 hasPrev: BI.emptyFn, hasNext: BI.emptyFn, firstPage: 1, lastPage: BI.emptyFn } }, itemsCreator: BI.emptyFn, isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为true时生效 isNeedMerge: false, // 是否需要合并单元格 mergeCols: [], // 合并的单元格列号 mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], headerRowSize: 25, rowSize: 25, regionColumnSize: [], headerCellStyleGetter: BI.emptyFn, summaryCellStyleGetter: BI.emptyFn, sequenceCellStyleGetter: BI.emptyFn, header: [], items: [], // 二维数组 // 交叉表头 crossHeader: [], crossItems: [] }); }, _init: function () { BI.PageTable.superclass._init.apply(this, arguments); var self = this, o = this.options; this.hCurr = 1; this.vCurr = 1; this.table = BI.createWidget(o.el, { type: "bi.sequence_table", width: o.width, height: o.height && o.height - 30, isNeedResize: true, isResizeAdapt: false, isNeedFreeze: o.isNeedFreeze, freezeCols: o.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: o.mergeCols, mergeRule: o.mergeRule, columnSize: o.columnSize, minColumnSize: o.minColumnSize, maxColumnSize: o.maxColumnSize, headerRowSize: o.headerRowSize, rowSize: o.rowSize, regionColumnSize: o.regionColumnSize, headerCellStyleGetter: o.headerCellStyleGetter, summaryCellStyleGetter: o.summaryCellStyleGetter, sequenceCellStyleGetter: o.sequenceCellStyleGetter, header: o.header, items: o.items, // 交叉表头 crossHeader: o.crossHeader, crossItems: o.crossItems }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); this.pager = BI.createWidget(o.pager, { type: "bi.direction_pager", height: 30 }); this.pager.on(BI.Pager.EVENT_CHANGE, function () { var vpage = this.getVPage && this.getVPage(); if (BI.isNull(vpage)) { vpage = this.getCurrentPage(); } var hpage = this.getHPage && this.getHPage(); o.itemsCreator({ vpage: vpage, hpage: hpage }, function (items, header, crossItems, crossHeader) { self.table.setVPage ? self.table.setVPage(vpage) : self.table.setValue(vpage); self.table.setHPage && self.table.setHPage(hpage); self.populate.apply(self, arguments); }); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.table, left: 0, top: 0 }, { el: this.pager, left: 0, right: 0, bottom: 0 }] }); }, setHPage: function (v) { this.hCurr = v; this.pager.setHPage && this.pager.setHPage(v); this.table.setHPage && this.table.setHPage(v); }, setVPage: function (v) { this.vCurr = v; this.pager.setVPage && this.pager.setVPage(v); this.table.setVPage && this.table.setVPage(v); }, getHPage: function () { var hpage = this.pager.getHPage && this.pager.getHPage(); if (BI.isNotNull(hpage)) { return hpage; } hpage = this.pager.getCurrentPage && this.pager.getCurrentPage(); if (BI.isNotNull(hpage)) { return hpage; } return this.hpage; }, getVPage: function () { var vpage = this.pager.getVPage && this.pager.getVPage(); if (BI.isNotNull(vpage)) { return vpage; } vpage = this.pager.getCurrentPage && this.pager.getCurrentPage(); if (BI.isNotNull(vpage)) { return vpage; } return this.vpage; }, setWidth: function (width) { BI.PageTable.superclass.setWidth.apply(this, arguments); this.table.setWidth(width); }, setHeight: function (height) { BI.PageTable.superclass.setHeight.apply(this, arguments); var showPager = false; if (this.pager.alwaysShowPager) { showPager = true; } else if (this.pager.hasHNext && this.pager.hasHNext()) { showPager = true; } else if (this.pager.hasHPrev && this.pager.hasHPrev()) { showPager = true; } else if (this.pager.hasVNext && this.pager.hasVNext()) { showPager = true; } else if (this.pager.hasVPrev && this.pager.hasVPrev()) { showPager = true; } else if (this.pager.hasNext && this.pager.hasNext()) { showPager = true; } else if (this.pager.hasPrev && this.pager.hasPrev()) { showPager = true; } this.table.setHeight(height - (showPager ? 30 : 0)); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; this.table.setColumnSize(columnSize); }, getColumnSize: function () { return this.table.getColumnSize(); }, setRegionColumnSize: function (columnSize) { this.options.columnSize = columnSize; this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, restore: function () { this.table.restore(); }, attr: function () { BI.PageTable.superclass.attr.apply(this, arguments); this.table.attr.apply(this.table, arguments); }, populate: function () { this.pager.populate(); this.table.populate.apply(this.table, arguments); }, destroy: function () { this.table.destroy(); this.pager && this.pager.destroy(); BI.PageTable.superclass.destroy.apply(this, arguments); } }); BI.shortcut("bi.page_table", BI.PageTable);/** * 路径选择 * * Created by GUY on 2015/12/4. * @class BI.PathChooser * @extends BI.Widget */ BI.PathChooser = BI.inherit(BI.Widget, { _const: { lineColor: "#d4dadd", selectLineColor: "#3f8ce8" }, _defaultConfig: function () { return BI.extend(BI.PathChooser.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-path-chooser", items: [] }); }, _init: function () { BI.PathChooser.superclass._init.apply(this, arguments); this.populate(this.options.items); }, _createRegions: function (regions) { var self = this; this.regions = BI.createWidgets(BI.map(regions, function (i, region) { return { type: "bi.path_region", title: self.texts[region] || region }; })); this.regionMap = {}; BI.each(regions, function (i, region) { self.regionMap[region] = i; }); this.container = BI.createWidget({ type: "bi.horizontal", verticalAlign: "top", scrollx: false, scrolly: false, hgap: 10, items: this.regions }); BI.createWidget({ type: "bi.vertical_adapt", element: this, scrollable: true, hgap: 10, items: [this.container] }); }, getRegionIndexById: function (id) { var node = this.cache[id]; var regionType = node.get("region"); return this.regionMap[regionType]; }, _drawPath: function (start, offset, index) { var self = this; var starts = []; if (BI.contains(this.start, start)) { starts = this.start; } else { starts = [start]; } BI.each(starts, function (i, s) { BI.each(self.radios[s], function (i, rad) { rad.setSelected(false); }); BI.each(self.lines[s], function (i, line) { line.attr("stroke", self._const.lineColor); }); BI.each(self.regionIndexes[s], function (i, idx) { self.regions[idx].reset(); }); }); BI.each(this.routes[start][index], function (i, id) { var regionIndex = self.getRegionIndexById(id); self.regions[regionIndex].setSelect(offset + index, id); }); var current = BI.last(this.routes[start][index]); while (current && this.routes[current] && this.routes[current].length === 1) { BI.each(this.routes[current][0], function (i, id) { var regionIndex = self.getRegionIndexById(id); self.regions[regionIndex].setSelect(0, id); }); this.lines[current][0].attr("stroke", self._const.selectLineColor).toFront(); current = BI.last(this.routes[current][0]); } this.lines[start][index].attr("stroke", self._const.selectLineColor).toFront(); this.radios[start] && this.radios[start][index] && this.radios[start][index].setSelected(true); }, _drawRadio: function (start, offset, index, x, y) { var self = this; var radio = BI.createWidget({ type: "bi.radio", cls: "path-chooser-radio", selected: offset + index === 0, start: start, index: index }); radio.on(BI.Radio.EVENT_CHANGE, function () { self._drawPath(start, offset, index); self.fireEvent(BI.PathChooser.EVENT_CHANGE, start, index); }); if (!this.radios[start]) { this.radios[start] = []; } this.radios[start].push(radio); BI.createWidget({ type: "bi.absolute", element: this.container, items: [{ el: radio, left: x - 6.5, top: y - 6.5 }] }); }, _drawLine: function (start, lines) { var self = this; if (!this.lines[start]) { this.lines[start] = []; } if (!this.pathes[start]) { this.pathes[start] = []; } var startRegionIndex = this.getRegionIndexById(start); // start所在的位置,然后接着往下画其他的路径 var offset = this.regions[startRegionIndex].getIndexByValue(start); BI.each(lines, function (i, line) { self.pathes[start][i] = []; var idx = i + offset; var path = ""; var stop = 47.5 + 29 * idx; var sleft = 50 + 100 * startRegionIndex; var radioStartX = sleft, radioStartY = stop; var etop = stop; var endRegionIndex = self.getRegionIndexById(BI.last(line)); var endOffset = self.regions[endRegionIndex].getIndexByValue(BI.last(line)); var eleft = 50 + 100 * endRegionIndex; if (BI.contains(self.start, start)) { radioStartX = sleft - 50; path += "M" + (sleft - 50) + "," + stop; self.pathes[start][i].push({ x: sleft - 50, y: stop }); } else if (idx === 0) { radioStartX = sleft + 50; path += "M" + sleft + "," + stop; self.pathes[start][i].push({ x: sleft, y: stop }); } else { radioStartX = sleft + 50; path += "M" + sleft + "," + 47.5 + "L" + (sleft + 50) + "," + 47.5 + "L" + (sleft + 50) + "," + stop; self.pathes[start][i].push({ x: sleft, y: 47.5 }); self.pathes[start][i].push({ x: sleft + 50, y: 47.5 }); self.pathes[start][i].push({ x: sleft + 50, y: stop }); } if (idx > 0) { var endY = endOffset * 29 + 47.5; path += "L" + (eleft - 50) + "," + etop + "L" + (eleft - 50) + "," + endY + "L" + eleft + "," + endY; self.pathes[start][i].push({ x: eleft - 50, y: etop }); self.pathes[start][i].push({ x: eleft - 50, y: endY }); self.pathes[start][i].push({ x: eleft, y: endY }); } else { path += "L" + eleft + "," + etop; self.pathes[start][i].push({ x: eleft, y: etop }); } var graph = self.svg.path(path) .attr({ stroke: idx === 0 ? self._const.selectLineColor : self._const.lineColor, "stroke-dasharray": "-" }); self.lines[start].push(graph); if (lines.length > 1) { self.lines[start][0].toFront(); } // 第一个元素无论有多少个都要显示radio if (BI.contains(self.start, start)) { self.lines[self.regions[0].getValueByIndex(0)][0].toFront(); } if (lines.length > 1 || BI.contains(self.start, start)) { self._drawRadio(start, offset, i, radioStartX, radioStartY); } }); }, _drawLines: function (routes) { var self = this; this.lines = {}; this.pathes = {}; this.radios = {}; this.regionIndexes = {}; BI.each(routes, function (k, route) { if (!self.regionIndexes[k]) { self.regionIndexes[k] = []; } BI.each(route, function (i, rs) { BI.each(rs, function (j, id) { var regionIndex = self.getRegionIndexById(id); if (!BI.contains(self.regionIndexes[k], regionIndex)) { self.regionIndexes[k].push(regionIndex); } }); }); }); BI.each(routes, function (k, route) { self._drawLine(k, route); }); }, _pushNodes: function (nodes) { var self = this; var indexes = []; for (var i = 0; i < nodes.length; i++) { var id = nodes[i]; var index = self.getRegionIndexById(id); indexes.push(index); var region = self.regions[index]; if (i === nodes.length - 1) { if (!region.hasItem(id)) { region.addItem(id, self.texts[id]); } break; } if (i > 0 || BI.contains(self.start, id)) { region.addItem(id, self.texts[id]); } } for (var i = BI.first(indexes); i < BI.last(indexes); i++) { if (!BI.contains(indexes, i)) { self.regions[i].addItem(""); } } }, _createNodes: function () { var self = this, o = this.options; this.cache = {}; this.texts = {}; this.start = []; this.end = []; BI.each(o.items, function (i, item) { self.start.push(BI.first(item).value); self.end.push(BI.last(item).value); }); this.start = BI.uniq(this.start); this.end = BI.uniq(this.end); var regions = []; var tree = new BI.Tree(); var branches = {}, max = 0; BI.each(o.items, function (i, items) { BI.each(items, function (j, item) { if (!BI.has(branches, item.value)) { branches[item.value] = 0; } branches[item.value]++; max = Math.max(max, branches[item.value]); var prev = {}; if (j > 0) { prev = items[j - 1]; } var parent = self.cache[prev.value || ""]; var node = self.cache[item.value] || new BI.Node(item.value); node.set(item); self.cache[item.value] = node; self.texts[item.value] = item.text; self.texts[item.region] = item.regionText; parent = BI.isNull(parent) ? tree.getRoot() : parent; if (parent.getChildIndex(item.value) === -1) { tree.addNode(parent, node); } }); }); // 算出区域列表 tree.traverse(function (node) { BI.each(node.getChildren(), function (i, child) { if (BI.contains(regions, child.get("region"))) { var index1 = BI.indexOf(regions, node.get("region")); var index2 = BI.indexOf(regions, child.get("region")); // 交换区域 if (index1 > index2) { var t = regions[index2]; for (var j = index2; j < index1; j++) { regions[j] = regions[j + 1]; } regions[index1] = t; } } else { regions.push(child.get("region")); } }); }); this._createRegions(regions); // 算出节点 BI.each(branches, function (k, branch) { if (branch < max) { delete branches[k]; } }); // 过滤节点 var nodes = []; var n = tree.getRoot(); while (n && n.getChildrenLength() === 1) { if (BI.has(branches, n.getChildren()[0].id)) { delete branches[n.getChildren()[0].id]; n = n.getChildren()[0]; } else { n = null; } } tree.traverse(function (node) { if (BI.has(branches, node.id)) { nodes.push(node.id); delete branches[node.id]; } }); // 填充节点 var routes = {}; var s, e; for (var i = 0, len = nodes.length; i < len + 1; i++) { if (len === 0) { s = []; BI.each(this.start, function (i, id) { s.push(tree.search(id)); }); e = []; BI.each(this.end, function (i, id) { e.push(tree.search(id)); }); } else if (i === len) { s = e; e = []; BI.each(this.end, function (i, id) { e.push(tree.search(id)); }); } else if (i === 0) { s = []; BI.each(this.start, function (i, id) { s.push(tree.search(id)); }); e = [tree.search(nodes[i])]; } else { s = [tree.search(e[0] || tree.getRoot(), nodes[i - 1])]; e = [tree.search(s[0], nodes[i])]; } BI.each(s, function (i, n) { tree._recursion(n, [n.id], function (node, route) { if (BI.contains(e, node)) { if (!routes[n.id]) { routes[n.id] = []; } routes[n.id].push(route); self._pushNodes(route); if (e.length <= 1) { return true; } } }); }); } this.routes = routes; this._drawLines(routes); }, _unselectAllPath: function () { var self = this; BI.each(this.radios, function (idx, rad) { BI.each(rad, function (i, r) { r.setSelected(false); }); }); BI.each(this.lines, function (idx, line) { BI.each(line, function (i, li) { li.attr("stroke", self._const.lineColor); }); }); BI.each(this.regions, function (idx, region) { region.reset(); }); }, populate: function (items) { this.options.items = items || []; var self = this; this.empty(); if (this.options.items.length <= 0) { return; } this.svg = BI.createWidget({ type: "bi.svg" }); this._createNodes(); BI.createWidget({ type: "bi.absolute", element: this.container, items: [{ el: this.svg, top: 0, left: 0, right: 0, bottom: 0 }] }); }, setValue: function (v) { this._unselectAllPath(); var nodes = BI.keys(this.routes), self = this; var result = [], array = []; BI.each(v, function (i, val) { if (BI.contains(nodes, val)) { if (array.length > 0) { array.push(val); result.push(array); array = []; } } array.push(val); }); if (array.length > 0) { result.push(array); } // 画这n条路径 BI.each(result, function (idx, path) { var start = path[0]; var index = BI.findIndex(self.routes[start], function (idx, p) { if (BI.isEqual(path, p)) { return true; } }); if (index >= 0) { var startRegionIndex = self.getRegionIndexById(start); var offset = self.regions[startRegionIndex].getIndexByValue(start); self._drawPath(start, offset, index); } }); }, getValue: function () { var path = []; BI.each(this.regions, function (i, region) { var val = region.getValue(); if (BI.isKey(val)) { path.push(val); } }); return path; } }); BI.PathChooser.EVENT_CHANGE = "PathChooser.EVENT_CHANGE"; BI.shortcut("bi.path_chooser", BI.PathChooser);/** * 路径选择区域 * * Created by GUY on 2015/12/4. * @class BI.PathRegion * @extends BI.Widget */ BI.PathRegion = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PathRegion.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-path-region bi-background", width: 80, title: "" }); }, _init: function () { BI.PathRegion.superclass._init.apply(this, arguments); var self = this, o = this.options; this.zIndex = 100; var title = BI.createWidget({ type: "bi.label", text: o.title, title: o.title, height: 30 }); title.element.css("zIndex", this.zIndex--); this.items = []; this.vertical = BI.createWidget({ type: "bi.vertical", element: this, bgap: 5, hgap: 10, items: [title] }); }, hasItem: function (val) { return BI.any(this.items, function (i, item) { return val === item.getValue(); }); }, addItem: function (value, text) { if (BI.isKey(value)) { var label = BI.createWidget({ type: "bi.label", cls: "path-region-label bi-card bi-border bi-list-item-select", text: text, value: value, title: text || value, height: 24 }); } else { var label = BI.createWidget({ type: "bi.layout", height: 24 }); } label.element.css("zIndex", this.zIndex--); this.items.push(label); this.vertical.addItem(label); if (this.items.length === 1) { this.setSelect(0, value); } }, reset: function () { BI.each(this.items, function (i, item) { item.element.removeClass("active"); }); }, setSelect: function (index, value) { this.reset(); if (this.items.length <= 0) { return; } if (this.items.length === 1) { this.items[0].element.addClass("active"); return; } if (this.items[index].attr("value") === value) { this.items[index].element.addClass("active"); } }, setValue: function (value) { this.setSelect(this.getIndexByValue(value), value); }, getValueByIndex: function (idx) { return this.items[idx].attr("value"); }, getIndexByValue: function (value) { return BI.findIndex(this.items, function (i, item) { return item.attr("value") === value; }); }, getValue: function () { var res; BI.any(this.items, function (i, item) { if (item.element.hasClass("active")) { res = item.getValue(); return true; } }); return res; } }); BI.PathRegion.EVENT_CHANGE = "PathRegion.EVENT_CHANGE"; BI.shortcut("bi.path_region", BI.PathRegion);/** * 预览表列 * * Created by GUY on 2015/12/25. * @class BI.PreviewTableCell * @extends BI.Widget */ BI.PreviewTableCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PreviewTableCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-preview-table-cell", text: "" }); }, _init: function () { BI.PreviewTableCell.superclass._init.apply(this, arguments); var self = this, o = this.options; BI.createWidget({ type: "bi.label", element: this, textAlign: "left", whiteSpace: "normal", height: this.options.height, text: this.options.text, value: this.options.value }); } }); BI.shortcut("bi.preview_table_cell", BI.PreviewTableCell);/** * 预览表 * * Created by GUY on 2015/12/25. * @class BI.PreviewTableHeaderCell * @extends BI.Widget */ BI.PreviewTableHeaderCell = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PreviewTableHeaderCell.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-preview-table-header-cell", text: "" }); }, _init: function () { BI.PreviewTableHeaderCell.superclass._init.apply(this, arguments); var self = this, o = this.options; BI.createWidget({ type: "bi.label", element: this, textAlign: "left", whiteSpace: "normal", height: this.options.height, text: this.options.text, value: this.options.value }); } }); BI.shortcut("bi.preview_table_header_cell", BI.PreviewTableHeaderCell);/** * 预览表 * * Created by GUY on 2015/12/25. * @class BI.PreviewTable * @extends BI.Widget */ BI.PreviewTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PreviewTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-preview-table", isNeedFreeze: false, freezeCols: [], rowSize: null, columnSize: [], headerRowSize: 30, header: [], items: [] }); }, _init: function () { BI.PreviewTable.superclass._init.apply(this, arguments); var self = this, o = this.options; this.table = BI.createWidget({ type: "bi.table_view", element: this, isNeedResize: false, isResizeAdapt: false, isNeedFreeze: o.isNeedFreeze, freezeCols: o.freezeCols, rowSize: o.rowSize, columnSize: o.columnSize, headerRowSize: o.headerRowSize, header: BI.map(o.header, function (i, items) { return BI.map(items, function (j, item) { return BI.extend({ type: "bi.preview_table_header_cell" }, item); }); }), items: BI.map(o.items, function (i, items) { return BI.map(items, function (j, item) { return BI.extend({ type: "bi.preview_table_cell" }, item); }); }) }); this.table.on(BI.Table.EVENT_TABLE_AFTER_INIT, function () { self._adjustColumns(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT, arguments); }); this.table.on(BI.Table.EVENT_TABLE_RESIZE, function () { self._adjustColumns(); }); }, // 是否有自适应调节的列,即列宽为"" _hasAdaptCol: function (columnSize) { return BI.any(columnSize, function (i, size) { return size === ""; }); }, _isPercentage: function (columnSize) { return columnSize[0] <= 1; }, _adjustColumns: function () { var self = this, o = this.options; if (o.isNeedFreeze === true) { // 如果存在百分比的情况 if (this._isPercentage(o.columnSize)) { if (this._hasAdaptCol(o.columnSize)) { var findCols = [], remain = 0; BI.each(o.columnSize, function (i, size) { if (size === "") { findCols.push(i); } else { remain += size; } }); remain = 1 - remain; var average = remain / findCols.length; BI.each(findCols, function (i, col) { o.columnSize[col] = average; }); } var isRight = BI.first(o.freezeCols) !== 0; var freezeSize = [], notFreezeSize = []; BI.each(o.columnSize, function (i, size) { if (o.freezeCols.contains(i)) { freezeSize.push(size); } else { notFreezeSize.push(size); } }); var sumFreezeSize = BI.sum(freezeSize), sumNotFreezeSize = BI.sum(notFreezeSize); BI.each(freezeSize, function (i, size) { freezeSize[i] = size / sumFreezeSize; }); BI.each(notFreezeSize, function (i, size) { notFreezeSize[i] = size / sumNotFreezeSize; }); this.table.setRegionColumnSize(isRight ? ["fill", sumFreezeSize] : [sumFreezeSize, "fill"]); this.table.setColumnSize(isRight ? (notFreezeSize.concat(freezeSize)) : (freezeSize.concat(notFreezeSize))); } } else { // 如果存在自适应宽度的列或者是百分比计算的列,需要将整个表宽设为100% if (this._hasAdaptCol(o.columnSize) || this._isPercentage(o.columnSize)) { this.table.setRegionColumnSize(["100%"]); } } }, setColumnSize: function (columnSize) { return this.table.setColumnSize(columnSize); }, getColumnSize: function () { return this.table.getColumnSize(); }, getCalculateColumnSize: function () { return this.table.getCalculateColumnSize(); }, setHeaderColumnSize: function (columnSize) { return this.table.setHeaderColumnSize(columnSize); }, setRegionColumnSize: function (columnSize) { return this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, getCalculateRegionColumnSize: function () { return this.table.getCalculateRegionColumnSize(); }, getCalculateRegionRowSize: function () { return this.table.getCalculateRegionRowSize(); }, getClientRegionColumnSize: function () { return this.table.getClientRegionColumnSize(); }, getScrollRegionColumnSize: function () { return this.table.getScrollRegionColumnSize(); }, getScrollRegionRowSize: function () { return this.table.getScrollRegionRowSize(); }, hasVerticalScroll: function () { return this.table.hasVerticalScroll(); }, setVerticalScroll: function (scrollTop) { return this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { return this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { return this.table.setRightHorizontalScroll(scrollLeft); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, getColumns: function () { return this.table.getColumns(); }, populate: function (items, header) { this.table.populate(items, header); } }); BI.PreviewTable.EVENT_CHANGE = "PreviewTable.EVENT_CHANGE"; BI.shortcut("bi.preview_table", BI.PreviewTable);/** * 季度下拉框 * * Created by GUY on 2015/8/28. * @class BI.QuarterCombo * @extends BI.Widget */ BI.QuarterCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.QuarterCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-quarter-combo", behaviors: {}, height: 25 }); }, _init: function () { BI.QuarterCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.storeValue = ""; this.trigger = BI.createWidget({ type: "bi.quarter_trigger" }); this.trigger.on(BI.QuarterTrigger.EVENT_FOCUS, function () { self.storeValue = this.getKey(); }); this.trigger.on(BI.QuarterTrigger.EVENT_START, function () { self.combo.isViewVisible() && self.combo.hideView(); }); this.trigger.on(BI.QuarterTrigger.EVENT_STOP, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.trigger.on(BI.QuarterTrigger.EVENT_CONFIRM, function () { if (self.combo.isViewVisible()) { return; } if (this.getKey() && this.getKey() !== self.storeValue) { self.setValue(this.getKey()); } else if (!this.getKey()) { self.setValue(); } self.fireEvent(BI.QuarterCombo.EVENT_CONFIRM); }); this.popup = BI.createWidget({ type: "bi.quarter_popup", behaviors: o.behaviors }); this.popup.on(BI.QuarterPopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.QuarterCombo.EVENT_CONFIRM); }); this.combo = BI.createWidget({ type: "bi.combo", element: this, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, popup: { minWidth: 85, el: this.popup } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.QuarterCombo.EVENT_BEFORE_POPUPVIEW); }); }, setValue: function (v) { this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue() || ""; } }); BI.QuarterCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.QuarterCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.quarter_combo", BI.QuarterCombo);/** * 季度展示面板 * * Created by GUY on 2015/9/2. * @class BI.QuarterPopup * @extends BI.Trigger */ BI.QuarterPopup = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.QuarterPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-quarter-popup", behaviors: {} }); }, _init: function () { BI.QuarterPopup.superclass._init.apply(this, arguments); var self = this, o = this.options; var items = [{ text: Date._QN[01], value: 1 }, { text: Date._QN[2], value: 2 }, { text: Date._QN[3], value: 3 }, { text: Date._QN[4], value: 4 }]; items = BI.map(items, function (j, item) { return BI.extend(item, { type: "bi.text_item", cls: "bi-list-item-active", textAlign: "left", whiteSpace: "nowrap", once: false, forceSelected: true, height: 25 }); }); this.quarter = BI.createWidget({ type: "bi.button_group", element: this, behaviors: o.behaviors, items: BI.createItems(items, {}), layouts: [{ type: "bi.vertical" }] }); this.quarter.on(BI.Controller.EVENT_CHANGE, function (type) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); if (type === BI.Events.CLICK) { self.fireEvent(BI.MonthPopup.EVENT_CHANGE); } }); }, getValue: function () { return this.quarter.getValue()[0]; }, setValue: function (v) { this.quarter.setValue([v]); } }); BI.QuarterPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.quarter_popup", BI.QuarterPopup);/** * 季度trigger * * Created by GUY on 2015/8/21. * @class BI.QuarterTrigger * @extends BI.Trigger */ BI.QuarterTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4, vgap: 2, textWidth: 40, errorText: BI.i18nText("BI-Quarter_Trigger_Error_Text") }, _defaultConfig: function () { return BI.extend(BI.QuarterTrigger.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-quarter-trigger bi-border", height: 24 }); }, _init: function () { BI.QuarterTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.editor = BI.createWidget({ type: "bi.sign_editor", height: o.height, validationChecker: function (v) { return v === "" || (BI.isPositiveInteger(v) && v >= 1 && v <= 4); }, quitChecker: function (v) { return false; }, hgap: c.hgap, vgap: c.vgap, allowBlank: true, errorText: c.errorText }); this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { self.fireEvent(BI.QuarterTrigger.EVENT_FOCUS); }); this.editor.on(BI.SignEditor.EVENT_CHANGE, function () { self.fireEvent(BI.QuarterTrigger.EVENT_CHANGE); }); this.editor.on(BI.SignEditor.EVENT_CONFIRM, function () { var value = self.editor.getValue(); if (BI.isNotNull(value)) { self.editor.setValue(value); self.editor.setTitle(value); } self.fireEvent(BI.QuarterTrigger.EVENT_CONFIRM); }); this.editor.on(BI.SignEditor.EVENT_SPACE, function () { if (self.editor.isValid()) { self.editor.blur(); } }); this.editor.on(BI.SignEditor.EVENT_START, function () { self.fireEvent(BI.QuarterTrigger.EVENT_START); }); this.editor.on(BI.SignEditor.EVENT_STOP, function () { self.fireEvent(BI.QuarterTrigger.EVENT_STOP); }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: this.editor }, { el: { type: "bi.text_button", baseCls: "bi-trigger-quarter-text", text: BI.i18nText("BI-Multi_Date_Quarter"), width: c.textWidth }, width: c.textWidth }, { el: { type: "bi.trigger_icon_button", width: o.height }, width: o.height } ] }); }, setValue: function (v) { v = v || ""; this.editor.setState(v); this.editor.setValue(v); this.editor.setTitle(v); }, getKey: function () { return this.editor.getValue(); } }); BI.QuarterTrigger.EVENT_FOCUS = "EVENT_FOCUS"; BI.QuarterTrigger.EVENT_CHANGE = "EVENT_CHANGE"; BI.QuarterTrigger.EVENT_START = "EVENT_START"; BI.QuarterTrigger.EVENT_STOP = "EVENT_STOP"; BI.QuarterTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.shortcut("bi.quarter_trigger", BI.QuarterTrigger);/** * 关联视图字段Item * * Created by GUY on 2015/12/23. * @class BI.RelationViewItem * @extends BI.Widget */ BI.RelationViewItem = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.RelationViewItem.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-relation-view-item bi-list-item-active", hoverIn: BI.emptyFn, hoverOut: BI.emptyFn }); }, _init: function () { BI.RelationViewItem.superclass._init.apply(this, arguments); var self = this, o = this.options; this.element.hover(o.hoverIn, o.hoverOut); o.text = BI.isArray(o.text) ? o.text : [o.text]; var body = []; var header = { type: "bi.vertical_adapt", cls: "primary-key-font", items: [] }; if (o.isPrimary) { header.items.push({ type: "bi.icon", width: 12, height: 16, title: BI.i18nText("BI-Primary_Key") }); } header.items.push({ type: "bi.label", text: o.text.length > 1 ? BI.i18nText("BI-Basic_Union_Relation") : o.text[0], value: o.value, height: 25, textAlign: "left", width: o.isPrimary ? 70 : 90, lgap: o.isPrimary ? 0 : 10 }); if(o.text.length > 1){ body = BI.map(o.text, function (idx, text) { return { type: "bi.label", text: text, value: o.value, height: 25, textAlign: "left", width: 70, lgap: 15 } }) } BI.createWidget({ type: "bi.vertical", element: this, items: BI.concat([header], body) }); }, enableHover: function (opt) { BI.RelationViewRegion.superclass.enableHover.apply(this, [{ container: "body" }]); }, setSelected: function (b) { this.element[b ? "addClass" : "removeClass"]("active"); } }); BI.shortcut("bi.relation_view_item", BI.RelationViewItem);/** * 关联视图 * * Created by GUY on 2015/12/22. * @class BI.RelationView * @extends BI.Widget */ BI.RelationView = BI.inherit(BI.Widget, { _const: { lineColor: "#c4c6c6", selectLineColor: "#009de3" }, _defaultConfig: function () { return BI.extend(BI.RelationView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-relation-view", items: [] }); }, _init: function () { BI.RelationView.superclass._init.apply(this, arguments); this.populate(this.options.items); }, _calculateWidths: function () { var widths = []; BI.each(this.views, function (i, items) { BI.each(items, function (j, obj) { if (!widths[j]) { widths[j] = BI.MIN; } widths[j] = Math.max(widths[j], obj.getWidth()); }); }); return widths; }, _calculateHeights: function () { var heights = BI.makeArray(BI.size(this.views), BI.MIN); BI.each(this.views, function (i, items) { BI.each(items, function (j, obj) { heights[i] = Math.max(heights[i], obj.getHeight()); }); }); return heights; }, _hoverIn: function (target) { var self = this, c = this._const; BI.each(this.relations, function (start, rs) { BI.each(rs, function (end, relation) { if (relation[0].primary.value === target || relation[0].foreign.value === target) { self.lines[start][end].attr("stroke", c.selectLineColor).toFront(); self.storeViews[start].setValue(relation[0].primary.value); self.storeViews[end].setValue(relation[0].foreign.value); } }); }); }, _hoverOut: function (target) { var self = this, c = this._const; BI.each(this.relations, function (start, rs) { BI.each(rs, function (end, relation) { if (relation[0].primary.value === target || relation[0].foreign.value === target) { self.lines[start][end].attr("stroke", c.lineColor); self.storeViews[start].setValue([]); self.storeViews[end].setValue([]); } }); }); }, previewRelationTables: function (relationTables, show) { if (!show) { BI.each(this.storeViews, function (i, view) { view.toggleRegion(true); view.setPreviewSelected(false); }); BI.each(this.lines, function (i, lines) { BI.each(lines, function (j, line) { line.show(); }); }); return; } BI.each(this.storeViews, function (id, view) { if (!relationTables.contains(id)) { view.toggleRegion(false); } else { view.setPreviewSelected(true); } }); BI.each(this.lines, function (id, lines) { BI.each(lines, function (cId, line) { if (!relationTables.contains(id) || !relationTables.contains(cId)) { line.hide(); } }); }); }, doRedMark: function (keyword) { BI.each(this.storeViews, function (idx, view) { view.doRedMark(keyword); }); }, populate: function (items) { var self = this, o = this.options, c = this._const; o.items = items || []; this.empty(); this.svg = BI.createWidget({ type: "bi.svg" }); // 算出所有的区域和关联 var regions = this.regions = {}, relations = this.relations = {}; BI.each(items, function (i, item) { var pr = item.primary.region, fr = item.foreign && item.foreign.region; if (pr && !relations[pr]) { relations[pr] = {}; } if (pr && fr && !relations[pr][fr]) { relations[pr][fr] = []; } if (pr && !regions[pr]) { regions[pr] = []; } if (fr && !regions[fr]) { regions[fr] = []; } if (pr && !BI.deepContains(regions[pr], item.primary)) { regions[pr].push(item.primary); } if (fr && !BI.deepContains(regions[fr], item.foreign)) { regions[fr].push(item.foreign); } pr && fr && relations[pr][fr].push(item); }); // 求拓扑 var topology = []; var rs = BI.clone(regions), store = {}; while (!BI.isEmpty(rs)) { var clone = BI.clone(rs); BI.each(o.items, function (i, item) { if (!store[item.primary.region]) { delete clone[item.foreign && item.foreign.region]; } }); topology.push(BI.keys(clone)); BI.extend(store, clone); BI.each(clone, function (k, v) { delete rs[k]; }); } // 构建视图 var views = this.views = {}, storeViews = this.storeViews = {}, indexes = this.indexes = {}; var verticals = []; BI.each(topology, function (i, items) { if (!views[i]) { views[i] = {}; } var horizontal = []; BI.each(items, function (j, region) { var items = regions[region]; views[i][j] = storeViews[region] = BI.createWidget({ type: "bi.relation_view_region_container", value: region, header: items[0].regionTitle, text: items.length > 0 ? items[0].regionText : "", handler: items.length > 0 ? items[0].regionHandler : BI.emptyFn, items: items, disabled: items[0].disabled, belongPackage: items.length > 0 ? items[0].belongPackage : true }); if (BI.isNotNull(items[0]) && BI.isNotNull(items[0].keyword)) { views[i][j].doRedMark(items[0].keyword); } views[i][j].on(BI.RelationViewRegionContainer.EVENT_HOVER_IN, function (v) { self._hoverIn(v); }); views[i][j].on(BI.RelationViewRegionContainer.EVENT_HOVER_OUT, function (v) { self._hoverOut(v); }); views[i][j].on(BI.RelationViewRegionContainer.EVENT_PREVIEW, function (v) { self.fireEvent(BI.RelationView.EVENT_PREVIEW, region, v); }); indexes[region] = {i: i, j: j}; horizontal.push(views[i][j]); }); verticals.push({ type: "bi.horizontal", items: horizontal }); }); // 求每一行的高度 var heights = this._calculateHeights(); // 求每一列的宽度 var widths = this._calculateWidths(); // 求相对宽度和高度 var offsetWidths = [0], offsetHeights = [0]; BI.each(heights, function (i, h) { if (i === 0) { return; } offsetHeights[i] = offsetHeights[i - 1] + heights[i - 1]; }); BI.each(widths, function (i, w) { if (i === 0) { return; } offsetWidths[i] = offsetWidths[i - 1] + widths[i - 1]; }); // 画线 var lines = this.lines = {};// 缓存所有的线 BI.each(relations, function (start, rs) { BI.each(rs, function (end, relation) { var startIndex = indexes[start], endIndex = indexes[end]; var top = 0, right = 1, bottom = 2, left = 3; var startDirection = bottom, endDirection = top; // if (startIndex.j > endIndex.j) { // startDirection = left; // endDirection = right; // } else if (startIndex.j < endIndex.j) { // startDirection = right; // endDirection = left; // } else if (startIndex.i < endIndex.i) { // startDirection = bottom; // endDirection = top; // } else if (startIndex.i > endIndex.i) { // startDirection = top; // endDirection = bottom; // } var draw = function (i, j, direction, isForeign) { var x = offsetWidths[j] + (widths[j] - views[i][j].getWidth()) / 2; var y = offsetHeights[i]; var path = "", position; switch (direction) { case top: position = isForeign ? views[i][j].getTopRightPosition() : views[i][j].getTopLeftPosition(); x += position.x; y += position.y; path = "M" + x + "," + y + "L" + x + "," + (y - 10); y -= 10; break; case right: position = views[i][j].getRightPosition(); x += position.x; y += position.y; path = "M" + x + "," + y + "L" + (x + 10) + "," + y; x += 10; break; case bottom: position = views[i][j].getBottomPosition(); x += position.x; y += position.y; path = "M" + x + "," + y + "L" + x + "," + (y + 10); y += 10; break; case left: position = views[i][j].getLeftPosition(); x += position.x; y += position.y; path = "M" + x + "," + y + "L" + (x - 10) + "," + y; x -= 10; break; } return {x: x, y: y, path: path}; }; var path = ""; var si = draw(startIndex.i, startIndex.j, startDirection); var ei = draw(endIndex.i, endIndex.j, endDirection, true); path += si.path + ei.path; if (!lines[start]) { lines[start] = {}; } path += "M" + si.x + "," + si.y + "L" + ei.x + "," + ei.y; var line = lines[start][end] = self.svg.path(path) .attr({stroke: c.lineColor, "stroke-width": "2"}) .hover(function () { line.attr("stroke", c.selectLineColor).toFront(); storeViews[start].setValue(relation[0].primary.value); storeViews[end].setValue(relation[0].foreign.value); }, function () { line.attr("stroke", c.lineColor); storeViews[start].setValue([]); storeViews[end].setValue([]); }); }); }); var container = BI.createWidget(); BI.createWidget({ type: "bi.vertical", element: container, items: verticals }); BI.createWidget({ type: "bi.absolute", element: container, items: [{ el: this.svg, left: 0, right: 0, top: 0, bottom: 0 }] }); BI.createWidget({ type: "bi.center_adapt", scrollable: true, element: this, items: [container] }); } }); BI.RelationView.EVENT_CHANGE = "RelationView.EVENT_CHANGE"; BI.RelationView.EVENT_PREVIEW = "EVENT_PREVIEW"; BI.shortcut("bi.relation_view", BI.RelationView);/** * Created by Young's on 2017/3/10. */ BI.RelationViewRegionContainer = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.RelationViewRegionContainer.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-relation-view-region-container", width: 200 }); }, _init: function () { BI.RelationViewRegionContainer.superclass._init.apply(this, arguments); var self = this, o = this.options; this.region = BI.createWidget({ type: "bi.relation_view_region", value: o.value, width: o.width, header: o.header, text: o.text, handler: o.handler, disabled: o.disabled, items: o.items, belongPackage: o.belongPackage }); this.region.on(BI.RelationViewRegion.EVENT_PREVIEW, function (v) { self.fireEvent(BI.RelationViewRegionContainer.EVENT_PREVIEW, v); }); this.region.on(BI.RelationViewRegion.EVENT_HOVER_IN, function (v) { self.fireEvent(BI.RelationViewRegionContainer.EVENT_HOVER_IN, v); }); this.region.on(BI.RelationViewRegion.EVENT_HOVER_OUT, function (v) { self.fireEvent(BI.RelationViewRegionContainer.EVENT_HOVER_OUT, v); }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.region], width: this.region.getWidth(), height: this.region.getHeight() }); }, doRedMark: function () { this.region.doRedMark.apply(this.region, arguments); }, unRedMark: function () { this.region.unRedMark.apply(this.region, arguments); }, getWidth: function () { return this.region.getWidth(); }, getHeight: function () { return this.region.getHeight(); }, // 获取上方开始划线的位置 getTopLeftPosition: function () { return this.region.getTopLeftPosition(); }, getTopRightPosition: function () { return this.region.getTopRightPosition(); }, getBottomPosition: function () { return this.region.getBottomPosition(); }, getLeftPosition: function () { return this.region.getLeftPosition(); }, getRightPosition: function () { return this.region.getRightPosition(); }, setValue: function (v) { this.region.setValue(v); }, toggleRegion: function (v) { v === true ? this.region.element.fadeIn() : this.region.element.fadeOut(); }, setPreviewSelected: function (v) { this.region.setPreviewSelected(v); } }); BI.RelationViewRegionContainer.EVENT_HOVER_IN = "RelationViewRegion.EVENT_HOVER_IN"; BI.RelationViewRegionContainer.EVENT_HOVER_OUT = "RelationViewRegion.EVENT_HOVER_OUT"; BI.RelationViewRegionContainer.EVENT_PREVIEW = "RelationViewRegion.EVENT_PREVIEW"; BI.shortcut("bi.relation_view_region_container", BI.RelationViewRegionContainer);/** * 关联视图 * * Created by GUY on 2015/12/23. * @class BI.RelationViewRegion * @extends BI.BasicButton */ BI.RelationViewRegion = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.RelationViewRegion.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-relation-view-region cursor-pointer", width: 150, text: "", value: "", header: "", items: [], belongPackage: true }); }, _init: function () { BI.RelationViewRegion.superclass._init.apply(this, arguments); var self = this, o = this.options; this.preview = BI.createWidget({ type: "bi.icon_button", cls: "relation-table-preview-font", width: 25, height: 25, stopPropagation: true }); this.preview.on(BI.IconButton.EVENT_CHANGE, function () { self.fireEvent(BI.RelationViewRegion.EVENT_PREVIEW, this.isSelected()); }); this.title = BI.createWidget({ type: "bi.label", height: 25, width: 70, text: o.text, value: o.value, textAlign: "left" }); // title放body上 if (BI.isKey(o.header)) { this.title.setTitle(o.header, { container: "body" }); } this.button_group = BI.createWidget({ type: "bi.button_group", items: this._createItems(o.items), layouts: [{ type: "bi.vertical" }] }); BI.createWidget({ type: "bi.vertical", element: this, items: [{ type: "bi.vertical", cls: "relation-view-region-container bi-card bi-border " + (o.belongPackage ? "" : "other-package"), items: [{ type: "bi.vertical_adapt", cls: "relation-view-region-title bi-border-bottom bi-background", items: [this.preview, this.title] }, this.button_group] }], hgap: 25, vgap: 20 }); }, _createItems: function (items) { var self = this; return BI.map(items, function (i, item) { var texts = BI.isArray(item.text) ? item.text : [item.text]; return BI.extend(item, { type: "bi.relation_view_item", height: texts.length > 1 ? (texts.length + 1) * 25 : 25, hoverIn: function () { self.setValue(item.value); self.fireEvent(BI.RelationViewRegion.EVENT_HOVER_IN, item.value); }, hoverOut: function () { self.setValue([]); self.fireEvent(BI.RelationViewRegion.EVENT_HOVER_OUT, item.value); } }); }); }, doRedMark: function () { this.title.doRedMark.apply(this.title, arguments); }, unRedMark: function () { this.title.unRedMark.apply(this.title, arguments); }, getWidth: function () { return this.options.width; }, getHeight: function () { var height = 0; BI.each(this.button_group.getAllButtons(), function (idx, button) { height += button.getHeight(); }); return height + 25 + 2 * 20 + 3; }, // 获取上方开始划线的位置 getTopLeftPosition: function () { return { x: 25 + 10, y: 20 }; }, getTopRightPosition: function () { return { x: this.getWidth() - 25 - 10, y: 20 }; }, getBottomPosition: function () { return { x: 25 + 10, y: this.getHeight() - 20 }; }, getLeftPosition: function () { return { x: 25, y: 20 + 10 }; }, getRightPosition: function () { return { x: this.getWidth() - 25, y: 20 + 10 }; }, setValue: function (v) { this.button_group.setValue(v); }, setPreviewSelected: function (v) { this.preview.setSelected(v); } }); BI.RelationViewRegion.EVENT_HOVER_IN = "RelationViewRegion.EVENT_HOVER_IN"; BI.RelationViewRegion.EVENT_HOVER_OUT = "RelationViewRegion.EVENT_HOVER_OUT"; BI.RelationViewRegion.EVENT_PREVIEW = "RelationViewRegion.EVENT_PREVIEW"; BI.shortcut("bi.relation_view_region", BI.RelationViewRegion);/** * 自适应宽度的表格 * * Created by GUY on 2016/2/3. * @class BI.ResponisveTable * @extends BI.Widget */ BI.ResponisveTable = BI.inherit(BI.Widget, { _const: { perColumnSize: 100 }, _defaultConfig: function () { return BI.extend(BI.ResponisveTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-responsive-table", isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为true时生效 isNeedMerge: false, // 是否需要合并单元格 mergeCols: [], // 合并的单元格列号 mergeRule: function (row1, row2) { // 合并规则, 默认相等时合并 return BI.isEqual(row1, row2); }, columnSize: [], headerRowSize: 25, footerRowSize: 25, rowSize: 25, regionColumnSize: false, header: [], footer: false, items: [], // 二维数组 // 交叉表头 crossHeader: [], crossItems: [] }); }, _init: function () { BI.ResponisveTable.superclass._init.apply(this, arguments); var self = this, o = this.options; this.table = BI.createWidget({ type: "bi.table_view", element: this, isNeedFreeze: o.isNeedFreeze, freezeCols: o.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: o.mergeCols, mergeRule: o.mergeRule, columnSize: o.columnSize, headerRowSize: o.headerRowSize, footerRowSize: o.footerRowSize, rowSize: o.rowSize, regionColumnSize: o.regionColumnSize, header: o.header, footer: o.footer, items: o.items, // 交叉表头 crossHeader: o.crossHeader, crossItems: o.crossItems }); this.table.on(BI.Table.EVENT_TABLE_AFTER_INIT, function () { self._initRegionSize(); self.table.resize(); self._resizeHeader(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_INIT, arguments); }); this.table.on(BI.Table.EVENT_TABLE_RESIZE, function () { self._resizeRegion(); self._resizeHeader(); self.fireEvent(BI.Table.EVENT_TABLE_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function () { self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE, function () { self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_REGION_RESIZE, function () { // important:在冻结并自适应列宽的情况下要随时变更表头宽度 if (o.isNeedResize === true && self._isAdaptiveColumn()) { self._resizeHeader(); } self.fireEvent(BI.Table.EVENT_TABLE_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { self._resizeHeader(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE, function () { self._resizeBody(); self.fireEvent(BI.Table.EVENT_TABLE_BEFORE_COLUMN_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_COLUMN_RESIZE, function () { self.fireEvent(BI.Table.EVENT_TABLE_COLUMN_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { self._resizeRegion(); self._resizeHeader(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); }, _initRegionSize: function () { var o = this.options; if (o.isNeedFreeze === true) { var regionColumnSize = this.table.getRegionColumnSize(); var maxWidth = this.table.element.width(); if (!regionColumnSize[0] || (regionColumnSize[0] === "fill") || regionColumnSize[0] > maxWidth || regionColumnSize[1] > maxWidth) { var freezeCols = o.freezeCols; if (freezeCols.length === 0) { this.table.setRegionColumnSize([0, "fill"]); } else if (freezeCols.length > 0 && freezeCols.length < o.columnSize.length) { var size = maxWidth / 3; if (freezeCols.length > o.columnSize.length / 2) { size = maxWidth * 2 / 3; } this.table.setRegionColumnSize([size, "fill"]); } else { this.table.setRegionColumnSize(["fill", 0]); } } } }, _getBlockSize: function () { var o = this.options; var columnSize = this.table.getCalculateColumnSize(); if (o.isNeedFreeze === true) { var columnSizeLeft = [], columnSizeRight = []; BI.each(columnSize, function (i, size) { if (o.freezeCols.contains(i)) { columnSizeLeft.push(size); } else { columnSizeRight.push(size); } }); // 因为有边框,所以加上数组长度的参数调整 var sumLeft = BI.sum(columnSizeLeft) + columnSizeLeft.length, sumRight = BI.sum(columnSizeRight) + columnSizeRight.length; return { sumLeft: sumLeft, sumRight: sumRight, left: columnSizeLeft, right: columnSizeRight }; } return { size: columnSize, sum: BI.sum(columnSize) + columnSize.length }; }, _isAdaptiveColumn: function (columnSize) { return !(BI.last(columnSize || this.table.getColumnSize()) > 1.05); }, _resizeHeader: function () { var self = this, o = this.options; if (o.isNeedFreeze === true) { // 若是当前处于自适应调节阶段 if (this._isAdaptiveColumn()) { var columnSize = this.table.getCalculateColumnSize(); this.table.setHeaderColumnSize(columnSize); } else { var regionColumnSize = this.table.getClientRegionColumnSize(); var block = this._getBlockSize(); var sumLeft = block.sumLeft, sumRight = block.sumRight; var columnSizeLeft = block.left, columnSizeRight = block.right; columnSizeLeft[columnSizeLeft.length - 1] += regionColumnSize[0] - sumLeft; columnSizeRight[columnSizeRight.length - 1] += regionColumnSize[1] - sumRight; var newLeft = BI.clone(columnSizeLeft), newRight = BI.clone(columnSizeRight); newLeft[newLeft.length - 1] = ""; newRight[newRight.length - 1] = ""; this.table.setColumnSize(newLeft.concat(newRight)); block = self._getBlockSize(); if (columnSizeLeft[columnSizeLeft.length - 1] < block.left[block.left.length - 1]) { columnSizeLeft[columnSizeLeft.length - 1] = block.left[block.left.length - 1]; } if (columnSizeRight[columnSizeRight.length - 1] < block.right[block.right.length - 1]) { columnSizeRight[columnSizeRight.length - 1] = block.right[block.right.length - 1]; } self.table.setColumnSize(columnSizeLeft.concat(columnSizeRight)); } } else { if (!this._isAdaptiveColumn()) { var regionColumnSize = this.table.getClientRegionColumnSize(); var block = this._getBlockSize(); var sum = block.sum; var size = block.size; size[size.length - 1] += regionColumnSize[0] - sum; var newSize = BI.clone(size); newSize[newSize.length - 1] = ""; this.table.setColumnSize(newSize); block = this._getBlockSize(); if (size[size.length - 1] < block.size[block.size.length - 1]) { size[size.length - 1] = block.size[block.size.length - 1]; } this.table.setColumnSize(size); } } }, _resizeBody: function () { if (this._isAdaptiveColumn()) { var columnSize = this.table.getCalculateColumnSize(); this.setColumnSize(columnSize); } }, _adjustRegion: function () { var o = this.options; var regionColumnSize = this.table.getCalculateRegionColumnSize(); if (o.isNeedFreeze === true && o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) { var block = this._getBlockSize(); var sumLeft = block.sumLeft, sumRight = block.sumRight; if (sumLeft < regionColumnSize[0] || regionColumnSize[0] >= (sumLeft + sumRight)) { this.table.setRegionColumnSize([sumLeft, "fill"]); } this._resizeRegion(); } }, _resizeRegion: function () { var o = this.options; var regionColumnSize = this.table.getCalculateRegionColumnSize(); if (o.isNeedFreeze === true && o.freezeCols.length > 0 && o.freezeCols.length < o.columnSize.length) { var maxWidth = this.table.element.width(); if (regionColumnSize[0] < 15 || regionColumnSize[1] < 15) { var freezeCols = o.freezeCols; var size = maxWidth / 3; if (freezeCols.length > o.columnSize.length / 2) { size = maxWidth * 2 / 3; } this.table.setRegionColumnSize([size, "fill"]); } } }, resize: function () { this.table.resize(); this._resizeRegion(); this._resizeHeader(); }, setColumnSize: function (columnSize) { this.table.setColumnSize(columnSize); this._adjustRegion(); this._resizeHeader(); }, getColumnSize: function () { return this.table.getColumnSize(); }, getCalculateColumnSize: function () { return this.table.getCalculateColumnSize(); }, setHeaderColumnSize: function (columnSize) { this.table.setHeaderColumnSize(columnSize); this._adjustRegion(); this._resizeHeader(); }, setRegionColumnSize: function (columnSize) { this.table.setRegionColumnSize(columnSize); this._resizeHeader(); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, getCalculateRegionColumnSize: function () { return this.table.getCalculateRegionColumnSize(); }, getCalculateRegionRowSize: function () { return this.table.getCalculateRegionRowSize(); }, getClientRegionColumnSize: function () { return this.table.getClientRegionColumnSize(); }, getScrollRegionColumnSize: function () { return this.table.getScrollRegionColumnSize(); }, getScrollRegionRowSize: function () { return this.table.getScrollRegionRowSize(); }, hasVerticalScroll: function () { return this.table.hasVerticalScroll(); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, getLeftHorizontalScroll: function () { return this.table.getLeftHorizontalScroll(); }, getRightHorizontalScroll: function () { return this.table.getRightHorizontalScroll(); }, getColumns: function () { return this.table.getColumns(); }, attr: function () { BI.ResponisveTable.superclass.attr.apply(this, arguments); this.table.attr.apply(this.table, arguments); }, populate: function (items) { var self = this, o = this.options; this.table.populate.apply(this.table, arguments); if (o.isNeedFreeze === true) { BI.nextTick(function () { self._initRegionSize(); self.table.resize(); self._resizeHeader(); }); } } }); BI.shortcut("bi.responsive_table", BI.ResponisveTable);/** * 加号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.SelectTreeFirstPlusGroupNode * @extends BI.NodeButton */ BI.SelectTreeFirstPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.SelectTreeFirstPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-select-tree-first-plus-group-node bi-list-item-active", logic: { dynamic: false }, id: "", pId: "", readonly: true, open: false, height: 25 }); }, _init: function () { BI.SelectTreeFirstPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.first_tree_node_checkbox", stopPropagation: true }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { if (this.isSelected()) { self.triggerExpand(); } else { self.triggerCollapse(); } } }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, isOnce: function () { return true; }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.NodeButton.superclass.doClick.apply(this, arguments); }, setOpened: function (v) { BI.SelectTreeFirstPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.checkbox)) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.select_tree_first_plus_group_node", BI.SelectTreeFirstPlusGroupNode);/** * 加号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.SelectTreeLastPlusGroupNode * @extends BI.NodeButton */ BI.SelectTreeLastPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.SelectTreeLastPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-select-tree-last-plus-group-node bi-list-item-active", logic: { dynamic: false }, id: "", pId: "", readonly: true, open: false, height: 25 }); }, _init: function () { BI.SelectTreeLastPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.last_tree_node_checkbox", stopPropagation: true }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { if (this.isSelected()) { self.triggerExpand(); } else { self.triggerCollapse(); } } }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, isOnce: function () { return true; }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.NodeButton.superclass.doClick.apply(this, arguments); }, setOpened: function (v) { BI.SelectTreeLastPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.checkbox)) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.select_tree_last_plus_group_node", BI.SelectTreeLastPlusGroupNode);/** * 加号表示的组节点 * Created by GUY on 2015/9/6. * @class BI.SelectTreeMidPlusGroupNode * @extends BI.NodeButton */ BI.SelectTreeMidPlusGroupNode = BI.inherit(BI.NodeButton, { _defaultConfig: function () { var conf = BI.SelectTreeMidPlusGroupNode.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-select-tree-mid-plus-group-node bi-list-item-active", logic: { dynamic: false }, id: "", pId: "", readonly: true, open: false, height: 25 }); }, _init: function () { BI.SelectTreeMidPlusGroupNode.superclass._init.apply(this, arguments); var self = this, o = this.options; this.checkbox = BI.createWidget({ type: "bi.mid_tree_node_checkbox", stopPropagation: true }); this.text = BI.createWidget({ type: "bi.label", textAlign: "left", whiteSpace: "nowrap", textHeight: o.height, height: o.height, hgap: o.hgap, text: o.text, value: o.value, py: o.py }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { if (this.isSelected()) { self.triggerExpand(); } else { self.triggerCollapse(); } } }); var type = BI.LogicFactory.createLogicTypeByDirection(BI.Direction.Left); var items = BI.LogicFactory.createLogicItemsByDirection(BI.Direction.Left, { width: 25, el: this.checkbox }, this.text); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(type, BI.extend(o.logic, { items: items })))); }, isOnce: function () { return true; }, doRedMark: function () { this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doClick: function () { BI.NodeButton.superclass.doClick.apply(this, arguments); }, setOpened: function (v) { BI.SelectTreeMidPlusGroupNode.superclass.setOpened.apply(this, arguments); if (BI.isNotNull(this.checkbox)) { this.checkbox.setSelected(v); } } }); BI.shortcut("bi.select_tree_mid_plus_group_node", BI.SelectTreeMidPlusGroupNode);/** * @class BI.SelectTreeCombo * @extends BI.Widget */ BI.SelectTreeCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SelectTreeCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-select-tree-combo", height: 30, text: "", items: [] }); }, _init: function () { BI.SelectTreeCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.single_tree_trigger", text: o.text, height: o.height, items: o.items }); this.popup = BI.createWidget({ type: "bi.select_level_tree", items: o.items }); this.combo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup } }); this.combo.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.popup.on(BI.SingleTreePopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); }); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); }, populate: function (items) { this.combo.populate(items); } }); BI.shortcut("bi.select_tree_combo", BI.SelectTreeCombo);/** * @class BI.SelectTreeExpander * @extends BI.Widget */ BI.SelectTreeExpander = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SelectTreeExpander.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-select-tree-expander", trigger: "click", toggle: true, direction: "bottom", isDefaultInit: true, el: {}, popup: {} }); }, _init: function () { BI.SelectTreeExpander.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(BI.extend({stopPropagation: true}, o.el)); this.trigger.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { if (this.isSelected()) { self.expander.setValue([]); } } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.expander = BI.createWidget({ type: "bi.expander", element: this, trigger: o.trigger, toggle: o.toggle, direction: o.direction, isDefaultInit: o.isDefaultInit, el: this.trigger, popup: o.popup }); this.expander.on(BI.Controller.EVENT_CHANGE, function (type) { if (type === BI.Events.CLICK) { self.trigger.setSelected(false); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); }, setValue: function (v) { if (BI.contains(v, this.trigger.getValue())) { this.trigger.setSelected(true); this.expander.setValue([]); } else { this.trigger.setSelected(false); this.expander.setValue(v); } }, getValue: function () { if (this.trigger.isSelected()) { return [this.trigger.getValue()]; } return this.expander.getValue(); }, populate: function (items) { this.expander.populate(items); } }); BI.shortcut("bi.select_tree_expander", BI.SelectTreeExpander);/** * @class BI.SelectTreePopup * @extends BI.Pane */ BI.SelectTreePopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.SelectTreePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-select-level-tree", tipText: BI.i18nText("BI-No_Selected_Item"), items: [] }); }, _formatItems: function (nodes, layer) { var self = this; BI.each(nodes, function (i, node) { var extend = {layer: layer}; node.id = node.id || BI.UUID(); if (node.isParent === true || BI.isNotEmptyArray(node.children)) { switch (i) { case 0 : extend.type = "bi.select_tree_first_plus_group_node"; break; case nodes.length - 1 : extend.type = "bi.select_tree_last_plus_group_node"; break; default : extend.type = "bi.select_tree_mid_plus_group_node"; break; } BI.defaults(node, extend); self._formatItems(node.children); } else { switch (i) { case nodes.length - 1: extend.type = "bi.last_tree_leaf_item"; break; default : extend.type = "bi.mid_tree_leaf_item"; } BI.defaults(node, extend); } }); return nodes; }, _init: function () { BI.SelectTreePopup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tree = BI.createWidget({ type: "bi.level_tree", expander: { type: "bi.select_tree_expander", isDefaultInit: true }, items: this._formatItems(BI.Tree.transformToTreeFormat(o.items)), chooseType: BI.Selection.Single }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.tree] }); this.tree.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.tree.on(BI.LevelTree.EVENT_CHANGE, function () { self.fireEvent(BI.SelectTreePopup.EVENT_CHANGE); }); this.check(); }, getValue: function () { return this.tree.getValue(); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.tree.setValue(v); }, populate: function (items) { BI.SelectTreePopup.superclass.populate.apply(this, arguments); this.tree.populate(this._formatItems(BI.Tree.transformToTreeFormat(items))); } }); BI.SelectTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.select_level_tree", BI.SelectTreePopup);/** * * Created by GUY on 2016/8/10. * @class BI.SequenceTableDynamicNumber * @extends BI.SequenceTableTreeNumber */ BI.SequenceTableDynamicNumber = BI.inherit(BI.SequenceTableTreeNumber, { _defaultConfig: function () { return BI.extend(BI.SequenceTableDynamicNumber.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-sequence-table-dynamic-number" }); }, _init: function () { BI.SequenceTableDynamicNumber.superclass._init.apply(this, arguments); }, _formatNumber: function (nodes) { var self = this, o = this.options; var result = []; var count = this._getStart(nodes); function getLeafCount (node) { var cnt = 0; if (BI.isNotEmptyArray(node.children)) { BI.each(node.children, function (index, child) { cnt += getLeafCount(child); }); if (node.children.length > 1 && BI.isNotEmptyArray(node.values)) { cnt++; } } else { cnt++; } return cnt; } var start = 0, top = 0; BI.each(nodes, function (i, node) { if (BI.isArray(node.children)) { BI.each(node.children, function (index, child) { var cnt = getLeafCount(child); result.push({ text: count++, start: start, top: top, cnt: cnt, index: index, height: cnt * o.rowSize }); start += cnt; top += cnt * o.rowSize; }); if (BI.isNotEmptyArray(node.values)) { result.push({ text: BI.i18nText("BI-Summary_Values"), start: start++, top: top, cnt: 1, isSummary: true, height: o.rowSize }); top += o.rowSize; } } }); return result; } }); BI.shortcut("bi.sequence_table_dynamic_number", BI.SequenceTableDynamicNumber);/** * * Created by GUY on 2016/5/26. * @class BI.SequenceTableListNumber * @extends BI.Widget */ BI.SequenceTableListNumber = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SequenceTableListNumber.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-sequence-table-list-number", isNeedFreeze: false, scrollTop: 0, startSequence: 1, // 开始的序号 headerRowSize: 25, rowSize: 25, sequenceHeaderCreator: null, header: [], items: [], // 二维数组 // 交叉表头 crossHeader: [], crossItems: [], pageSize: 20 }); }, _init: function () { BI.SequenceTableListNumber.superclass._init.apply(this, arguments); var self = this, o = this.options; this.start = o.startSequence; this.renderedCells = []; this.renderedKeys = []; this.container = BI.createWidget({ type: "bi.absolute", width: 60, scrollable: false }); this.scrollContainer = BI.createWidget({ type: "bi.vertical", scrollable: false, scrolly: false, items: [this.container] }); this.headerContainer = BI.createWidget({ type: "bi.absolute", cls: "bi-border", width: 58, scrollable: false }); this.layout = BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.headerContainer, height: o.headerRowSize * o.header.length - 2 }, { el: {type: "bi.layout"}, height: 2 }, { el: this.scrollContainer }] }); this._populate(); }, _layout: function () { var self = this, o = this.options; var headerHeight = o.headerRowSize * o.header.length - 2; var items = this.layout.attr("items"); if (o.isNeedFreeze === false) { items[0].height = 0; items[1].height = 0; } else if (o.isNeedFreeze === true) { items[0].height = headerHeight; items[1].height = 2; } this.layout.attr("items", items); this.layout.resize(); this.container.setHeight(o.items.length * o.rowSize); try { this.scrollContainer.element.scrollTop(o.scrollTop); } catch (e) { } }, _createHeader: function () { var o = this.options; BI.createWidget({ type: "bi.absolute", element: this.headerContainer, items: [{ el: o.sequenceHeaderCreator || { type: "bi.table_style_cell", cls: "sequence-table-title-cell", styleGetter: o.headerCellStyleGetter, text: BI.i18nText("BI-Number_Index") }, left: 0, top: 0, right: 0, bottom: 0 }] }); }, _calculateChildrenToRender: function () { var self = this, o = this.options; var scrollTop = BI.clamp(o.scrollTop, 0, o.rowSize * o.items.length - (o.height - o.header.length * o.headerRowSize) + BI.DOM.getScrollWidth()); var start = Math.floor(scrollTop / o.rowSize); var end = start + Math.floor((o.height - o.header.length * o.headerRowSize) / o.rowSize); var renderedCells = [], renderedKeys = []; for (var i = start, cnt = 0; i <= end && i < o.items.length; i++, cnt++) { var index = BI.deepIndexOf(this.renderedKeys, this.start + i); var top = i * o.rowSize; if (index > -1) { if (o.rowSize !== this.renderedCells[index]._height) { this.renderedCells[index]._height = o.rowSize; this.renderedCells[index].el.setHeight(o.rowSize); } if (this.renderedCells[index].top !== top) { this.renderedCells[index].top = top; this.renderedCells[index].el.element.css("top", top + "px"); } renderedCells.push(this.renderedCells[index]); } else { var child = BI.createWidget(BI.extend({ type: "bi.table_style_cell", cls: "sequence-table-number-cell bi-border-left bi-border-right bi-border-bottom", width: 60, height: o.rowSize, text: this.start + i, styleGetter: function (index) { return function () { return o.sequenceCellStyleGetter(self.start + i - 1); }; }(cnt) })); renderedCells.push({ el: child, left: 0, top: top, _height: o.rowSize }); } renderedKeys.push(this.start + i); } // 已存在的, 需要添加的和需要删除的 var existSet = {}, addSet = {}, deleteArray = []; BI.each(renderedKeys, function (i, key) { if (BI.deepContains(self.renderedKeys, key)) { existSet[i] = key; } else { addSet[i] = key; } }); BI.each(this.renderedKeys, function (i, key) { if (BI.deepContains(existSet, key)) { return; } if (BI.deepContains(addSet, key)) { return; } deleteArray.push(i); }); BI.each(deleteArray, function (i, index) { self.renderedCells[index].el.destroy(); }); var addedItems = []; BI.each(addSet, function (index) { addedItems.push(renderedCells[index]); }); BI.createWidget({ type: "bi.absolute", element: this.container, items: addedItems }); this.renderedCells = renderedCells; this.renderedKeys = renderedKeys; }, _populate: function () { this.headerContainer.empty(); this._createHeader(); this._layout(); this._calculateChildrenToRender(); }, setVerticalScroll: function (scrollTop) { if (this.options.scrollTop !== scrollTop) { this.options.scrollTop = scrollTop; try { this.scrollContainer.element.scrollTop(scrollTop); } catch (e) { } } }, getVerticalScroll: function () { return this.options.scrollTop; }, setVPage: function (v) { v = v < 1 ? 1 : v; var o = this.options; this.start = (v - 1) * o.pageSize + 1; }, _restore: function () { var o = this.options; BI.each(this.renderedCells, function (i, cell) { cell.el.destroy(); }); this.renderedCells = []; this.renderedKeys = []; }, restore: function () { this._restore(); }, populate: function (items, header) { var o = this.options; if (items && items !== this.options.items) { o.items = items; this._restore(); } if (header && header !== this.options.header) { o.header = header; } this._populate(); } }); BI.shortcut("bi.sequence_table_list_number", BI.SequenceTableListNumber);/** * 带有序号的表格 * * Created by GUY on 2016/5/26. * @class BI.SequenceTable * @extends BI.Widget */ BI.SequenceTable = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SequenceTable.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-sequence-table", el: { type: "bi.adaptive_table" }, sequence: {}, isNeedResize: true, isResizeAdapt: false, isNeedFreeze: false, // 是否需要冻结单元格 freezeCols: [], // 冻结的列号,从0开始,isNeedFreeze为true时生效 isNeedMerge: false, // 是否需要合并单元格 mergeCols: [], // 合并的单元格列号 mergeRule: BI.emptyFn, columnSize: [], minColumnSize: [], maxColumnSize: [], headerRowSize: 25, rowSize: 25, regionColumnSize: [], headerCellStyleGetter: BI.emptyFn, summaryCellStyleGetter: BI.emptyFn, sequenceCellStyleGetter: BI.emptyFn, header: [], items: [], // 二维数组 // 交叉表头 crossHeader: [], crossItems: [], showSequence: false, startSequence: 1// 开始的序号 }); }, _init: function () { BI.SequenceTable.superclass._init.apply(this, arguments); var self = this, o = this.options; this.sequence = BI.createWidget(o.sequence, { type: "bi.sequence_table_list_number", invisible: o.showSequence === false, startSequence: o.startSequence, isNeedFreeze: o.isNeedFreeze, header: o.header, items: o.items, crossHeader: o.crossHeader, crossItems: o.crossItems, headerRowSize: o.headerRowSize, rowSize: o.rowSize, width: 60, height: o.height && o.height - BI.GridTableScrollbar.SIZE, headerCellStyleGetter: o.headerCellStyleGetter, summaryCellStyleGetter: o.summaryCellStyleGetter, sequenceCellStyleGetter: o.sequenceCellStyleGetter }); this.table = BI.createWidget(o.el, { type: "bi.adaptive_table", width: o.showSequence === true ? o.width - 60 : o.width, height: o.height, isNeedResize: o.isNeedResize, isResizeAdapt: o.isResizeAdapt, isNeedFreeze: o.isNeedFreeze, freezeCols: o.freezeCols, isNeedMerge: o.isNeedMerge, mergeCols: o.mergeCols, mergeRule: o.mergeRule, columnSize: o.columnSize, minColumnSize: o.minColumnSize, maxColumnSize: o.maxColumnSize, headerRowSize: o.headerRowSize, rowSize: o.rowSize, regionColumnSize: o.regionColumnSize, headerCellStyleGetter: o.headerCellStyleGetter, summaryCellStyleGetter: o.summaryCellStyleGetter, sequenceCellStyleGetter: o.sequenceCellStyleGetter, header: o.header, items: o.items, // 交叉表头 crossHeader: o.crossHeader, crossItems: o.crossItems }); this.table.on(BI.Table.EVENT_TABLE_SCROLL, function (scroll) { if (self.sequence.getVerticalScroll() !== this.getVerticalScroll()) { self.sequence.setVerticalScroll(this.getVerticalScroll()); self.sequence.populate(); } self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_REGION_RESIZE, arguments); }); this.table.on(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, function () { o.regionColumnSize = this.getRegionColumnSize(); o.columnSize = this.getColumnSize(); self.fireEvent(BI.Table.EVENT_TABLE_AFTER_COLUMN_RESIZE, arguments); }); this.htape = BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.sequence, left: 0, top: 0 }, { el: this.table, top: 0, left: o.showSequence === true ? 60 : 0 }] }); this._populate(); }, _populate: function () { var o = this.options; if (o.showSequence === true) { this.sequence.setVisible(true); this.table.element.css("left", "60px"); this.table.setWidth(o.width - 60); } else { this.sequence.setVisible(false); this.table.element.css("left", "0px"); this.table.setWidth(o.width); } }, setWidth: function (width) { BI.PageTable.superclass.setWidth.apply(this, arguments); this.table.setWidth(this.options.showSequence ? width - 60 : width); }, setHeight: function (height) { BI.PageTable.superclass.setHeight.apply(this, arguments); this.table.setHeight(height); this.sequence.setHeight(height - BI.GridTableScrollbar.SIZE); }, setColumnSize: function (columnSize) { this.options.columnSize = columnSize; this.table.setColumnSize(columnSize); }, getColumnSize: function () { return this.table.getColumnSize(); }, setRegionColumnSize: function (columnSize) { this.options.columnSize = columnSize; this.table.setRegionColumnSize(columnSize); }, getRegionColumnSize: function () { return this.table.getRegionColumnSize(); }, hasLeftHorizontalScroll: function () { return this.table.hasLeftHorizontalScroll(); }, hasRightHorizontalScroll: function () { return this.table.hasRightHorizontalScroll(); }, setLeftHorizontalScroll: function (scrollLeft) { this.table.setLeftHorizontalScroll(scrollLeft); }, setRightHorizontalScroll: function (scrollLeft) { this.table.setRightHorizontalScroll(scrollLeft); }, setVerticalScroll: function (scrollTop) { this.table.setVerticalScroll(scrollTop); this.sequence.setVerticalScroll(scrollTop); }, getVerticalScroll: function () { return this.table.getVerticalScroll(); }, setVPage: function (page) { this.sequence.setVPage && this.sequence.setVPage(page); }, setHPage: function (page) { this.sequence.setHPage && this.sequence.setHPage(page); }, attr: function () { BI.SequenceTable.superclass.attr.apply(this, arguments); this.table.attr.apply(this.table, arguments); this.sequence.attr.apply(this.sequence, arguments); }, restore: function () { this.table.restore(); this.sequence.restore(); }, populate: function (items, header, crossItems, crossHeader) { var o = this.options; if (items) { o.items = items; } if (header) { o.header = header; } if (crossItems) { o.crossItems = crossItems; } if (crossHeader) { o.crossHeader = crossHeader; } this._populate(); this.table.populate.apply(this.table, arguments); this.sequence.populate.apply(this.sequence, arguments); this.sequence.setVerticalScroll(this.table.getVerticalScroll()); }, destroy: function () { this.table.destroy(); BI.SequenceTable.superclass.destroy.apply(this, arguments); } }); BI.shortcut("bi.sequence_table", BI.SequenceTable);/** * 单选加载数据搜索loader面板 * Created by guy on 15/11/4. * @class BI.SingleSelectSearchLoader * @extends Widget */ BI.SingleSelectSearchLoader = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleSelectSearchLoader.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-search-loader", itemsCreator: BI.emptyFn, keywordGetter: BI.emptyFn, valueFormatter: BI.emptyFn }); }, _init: function () { BI.SingleSelectSearchLoader.superclass._init.apply(this, arguments); var self = this, opts = this.options; var hasNext = false; this.button_group = BI.createWidget({ type: "bi.single_select_list", element: this, logic: { dynamic: false }, el: { tipText: BI.i18nText("BI-No_Select"), el: { type: "bi.loader", isDefaultInit: false, logic: { dynamic: true, scrolly: true }, el: { chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, behaviors: { redmark: function () { return true; } }, layouts: [{ type: "bi.vertical" }] } } }, itemsCreator: function (op, callback) { self.storeValue && (op = BI.extend(op || {}, { selectedValues: [self.storeValue] })); opts.itemsCreator(op, function (ob) { var keyword = ob.keyword = opts.keywordGetter(); hasNext = ob.hasNext; var firstItems = []; if (op.times === 1 && self.storeValue) { var json = BI.map([self.storeValue], function (i, v) { var txt = opts.valueFormatter(v) || v; return { text: txt, value: v, title: txt, selected: false }; }); firstItems = self._createItems(json); } callback(firstItems.concat(self._createItems(ob.items)), keyword); if (op.times === 1 && self.storeValue) { self.setValue(self.storeValue); } }); }, hasNext: function () { return hasNext; } }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button_group.on(BI.SingleSelectList.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectSearchLoader.EVENT_CHANGE, arguments); }); }, _createItems: function (items) { return BI.createItems(items, { type: "bi.single_select_radio_item", logic: { dynamic: false }, height: 25, selected: false }); }, _filterValues: function (src) { var o = this.options; var keyword = o.keywordGetter(); var values = BI.deepClone(src.value) || []; var newValues = BI.map(values, function (i, v) { return { text: o.valueFormatter(v) || v, value: v }; }); if (BI.isKey(keyword)) { var search = BI.Func.getSearchResult(newValues, keyword); values = search.matched.concat(search.finded); } return BI.map(values, function (i, v) { return { text: v.text, title: v.text, value: v.value, selected: false }; }); }, setValue: function (v) { // 暂存的值一定是新的值,不然v改掉后,storeValue也跟着改了 this.storeValue = v; this.button_group.setValue(v); }, getValue: function () { return this.button_group.getValue(); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, empty: function () { this.button_group.empty(); }, populate: function (items) { this.button_group.populate.apply(this.button_group, arguments); }, resetHeight: function (h) { this.button_group.resetHeight(h); }, resetWidth: function (w) { this.button_group.resetWidth(w); } }); BI.SingleSelectSearchLoader.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_select_search_loader", BI.SingleSelectSearchLoader);/** * * 在搜索框中输入文本弹出的面板 * @class BI.SingleSelectSearchPane * @extends Widget */ BI.SingleSelectSearchPane = BI.inherit(BI.Widget, { constants: { height: 25, lgap: 10, tgap: 5 }, _defaultConfig: function () { return BI.extend(BI.SingleSelectSearchPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-search-pane bi-card", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, keywordGetter: BI.emptyFn }); }, _init: function () { BI.SingleSelectSearchPane.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tooltipClick = BI.createWidget({ type: "bi.label", invisible: true, text: BI.i18nText("BI-Click_Blank_To_Select"), cls: "single-select-toolbar", height: this.constants.height }); this.loader = BI.createWidget({ type: "bi.single_select_search_loader", keywordGetter: o.keywordGetter, valueFormatter: o.valueFormatter, itemsCreator: function (op, callback) { o.itemsCreator.apply(self, [op, function (res) { callback(res); self.setKeyword(o.keywordGetter()); }]); } }); this.loader.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.resizer = BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.tooltipClick, height: 0 }, { el: this.loader }] }); this.tooltipClick.setVisible(false); }, setKeyword: function (keyword) { var btn; var isVisible = this.loader.getAllButtons().length > 0 && (btn = this.loader.getAllButtons()[0]) && (keyword === btn.getValue()); if (isVisible !== this.tooltipClick.isVisible()) { this.tooltipClick.setVisible(isVisible); this.resizer.attr("items")[0].height = (isVisible ? this.constants.height : 0); this.resizer.resize(); } }, hasMatched: function () { return this.tooltipClick.isVisible(); }, setValue: function (v) { this.loader.setValue(v); }, getValue: function () { return this.loader.getValue(); }, empty: function () { this.loader.empty(); }, populate: function (items) { this.loader.populate.apply(this.loader, arguments); } }); BI.SingleSelectSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_select_search_pane", BI.SingleSelectSearchPane);/** * * @class BI.SingleSelectCombo * @extends BI.Single */ BI.SingleSelectCombo = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.SingleSelectCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-combo", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, height: 28 }); }, _init: function () { BI.SingleSelectCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; var assertShowValue = function () { BI.isKey(self._startValue) && (self.storeValue = self._startValue); self.trigger.getSearcher().setState(self.storeValue); }; this.storeValue = ""; // 标记正在请求数据 this.requesting = false; this.trigger = BI.createWidget({ type: "bi.single_select_trigger", height: o.height, // adapter: this.popup, masker: { offset: { left: 1, top: 1, right: 2, bottom: 33 } }, valueFormatter: o.valueFormatter, itemsCreator: function (op, callback) { o.itemsCreator(op, function (res) { if (op.times === 1 && BI.isNotNull(op.keywords)) { // 预防trigger内部把当前的storeValue改掉 self.trigger.setValue(self.getValue()); } callback.apply(self, arguments); }); } }); this.trigger.on(BI.SingleSelectTrigger.EVENT_START, function () { self._setStartValue(""); this.getSearcher().setValue(self.storeValue); }); this.trigger.on(BI.SingleSelectTrigger.EVENT_STOP, function () { self._setStartValue(""); }); this.trigger.on(BI.SingleSelectTrigger.EVENT_PAUSE, function () { if (this.getSearcher().hasMatched()) { var keyword = this.getSearcher().getKeyword(); self._join({ type: BI.Selection.Multi, value: [keyword] }, function () { self.combo.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); self.populate(); self._setStartValue(""); }); } }); this.trigger.on(BI.SingleSelectTrigger.EVENT_SEARCHING, function (keywords) { var last = BI.last(keywords); keywords = BI.initial(keywords || []); if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { self.combo.setValue(self.storeValue); assertShowValue(); self.combo.populate(); self._setStartValue(""); } else { self.combo.setValue(self.storeValue); assertShowValue(); } }); } }); this.trigger.on(BI.SingleSelectTrigger.EVENT_CHANGE, function (value, obj) { self.storeValue = this.getValue(); assertShowValue(); }); this.trigger.on(BI.SingleSelectTrigger.EVENT_COUNTER_CLICK, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, el: this.trigger, adjustLength: 1, popup: { type: "bi.single_select_popup_view", ref: function () { self.popup = this; self.trigger.setAdapter(this); }, listeners: [{ eventName: BI.SingleSelectPopupView.EVENT_CHANGE, action: function () { self.storeValue = this.getValue(); self._adjust(function () { assertShowValue(); }); } }, { eventName: BI.SingleSelectPopupView.EVENT_CLICK_CONFIRM, action: function () { self._defaultState(); } }, { eventName: BI.SingleSelectPopupView.EVENT_CLICK_CLEAR, action: function () { self.setValue(); self._defaultState(); } }], itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, onLoaded: function () { BI.nextTick(function () { self.combo.adjustWidth(); self.combo.adjustHeight(); self.trigger.getSearcher().adjustView(); }); } }, hideChecker: function (e) { return triggerBtn.element.find(e.target).length === 0; } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { this.setValue(self.storeValue); BI.nextTick(function () { self.populate(); }); }); // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 this.wants2Quit = false; this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { // important:关闭弹出时又可能没有退出编辑状态 self.trigger.stopEditing(); if (self.requesting === true) { self.wants2Quit = true; } else { self.fireEvent(BI.SingleSelectCombo.EVENT_CONFIRM); } }); var triggerBtn = BI.createWidget({ type: "bi.trigger_icon_button", width: o.height, height: o.height, cls: "single-select-trigger-icon-button bi-border-left" }); triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { if (self.combo.isViewVisible()) { self.combo.hideView(); } else { self.combo.showView(); } }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.combo, left: 0, right: 0, top: 0, bottom: 0 }, { el: triggerBtn, right: 0, top: 0, bottom: 0 }] }); }, _defaultState: function () { this.trigger.stopEditing(); this.combo.hideView(); }, _assertValue: function (val) { val || (val = ""); }, _makeMap: function (values) { return BI.makeObject(values || []); }, _joinKeywords: function (keywords, callback) { var self = this, o = this.options; this._assertValue(this.storeValue); this.requesting = true; o.itemsCreator({ type: BI.SingleSelectCombo.REQ_GET_ALL_DATA, keywords: keywords }, function (ob) { var values = BI.pluck(ob.items, "value"); digest(values); }); function digest (items) { var selectedMap = self._makeMap(items); BI.each(keywords, function (i, val) { if (BI.isNotNull(selectedMap[val])) { self.storeValue.value["remove"](val); } }); self._adjust(callback); } }, _joinAll: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this.requesting = true; o.itemsCreator({ type: BI.SingleSelectCombo.REQ_GET_ALL_DATA, keywords: [this.trigger.getKey()] }, function (ob) { var items = BI.pluck(ob.items, "value"); if (self.storeValue.type === res.type) { var change = false; var map = self._makeMap(self.storeValue.value); BI.each(items, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (self.storeValue.value = BI.values(map)); self._adjust(callback); return; } var selectedMap = self._makeMap(self.storeValue.value); var notSelectedMap = self._makeMap(res.value); var newItems = []; BI.each(items, function (i, item) { if (BI.isNotNull(selectedMap[items[i]])) { delete selectedMap[items[i]]; } if (BI.isNull(notSelectedMap[items[i]])) { newItems.push(item); } }); self.storeValue.value = newItems.concat(BI.values(selectedMap)); self._adjust(callback); }); }, _adjust: function (callback) { var self = this, o = this.options; if (!this._count) { o.itemsCreator({ type: BI.SingleSelectCombo.REQ_GET_DATA_LENGTH }, function (res) { self._count = res.count; adjust(); callback(); }); } else { adjust(); callback(); } function adjust () { if (self.wants2Quit === true) { self.fireEvent(BI.SingleSelectCombo.EVENT_CONFIRM); self.wants2Quit = false; } self.requesting = false; } }, _join: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this._assertValue(this.storeValue); if (this.storeValue.type === res.type) { var map = this._makeMap(this.storeValue.value); BI.each(res.value, function (i, v) { if (!map[v]) { self.storeValue.value.push(v); map[v] = v; } }); var change = false; BI.each(res.assist, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (this.storeValue.value = BI.values(map)); self._adjust(callback); return; } this._joinAll(res, callback); }, _setStartValue: function (value) { this._startValue = value; this.popup.setStartValue(value); }, setValue: function (v) { this.storeValue = v || ""; this._assertValue(this.storeValue); this.combo.setValue(this.storeValue); }, getValue: function () { return this.storeValue; }, populate: function () { this._count = null; this.combo.populate.apply(this.combo, arguments); } }); BI.extend(BI.SingleSelectCombo, { REQ_GET_DATA_LENGTH: 0, REQ_GET_ALL_DATA: -1 }); BI.SingleSelectCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.shortcut("bi.single_select_combo", BI.SingleSelectCombo);/** * 选择列表 * * Created by GUY on 2015/11/1. * @class BI.SingleSelectList * @extends BI.Widget */ BI.SingleSelectList = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleSelectList.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-select-list", direction: BI.Direction.Top, // toolbar的位置 logic: { dynamic: true }, items: [], itemsCreator: BI.emptyFn, hasNext: BI.emptyFn, onLoaded: BI.emptyFn, el: { type: "bi.list_pane" } }); }, _init: function () { BI.SingleSelectList.superclass._init.apply(this, arguments); var self = this, o = this.options; this.list = BI.createWidget(o.el, { type: "bi.list_pane", items: o.items, itemsCreator: function (op, callback) { o.itemsCreator(op, function (items) { callback.apply(self, arguments); }); }, onLoaded: o.onLoaded, hasNext: o.hasNext }); this.list.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { if (type === BI.Events.CLICK) { self.fireEvent(BI.SingleSelectList.EVENT_CHANGE, value, obj); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); BI.createWidget(BI.extend({ element: this }, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({ scrolly: true }, o.logic, { items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.list) })))); }, hasPrev: function () { return this.list.hasPrev(); }, hasNext: function () { return this.list.hasNext(); }, prependItems: function (items) { this.list.prependItems.apply(this.list, arguments); }, addItems: function (items) { this.list.addItems.apply(this.list, arguments); }, setValue: function (v) { this.list.setValue([v]); }, getValue: function () { return this.list.getValue()[0]; }, empty: function () { this.list.empty(); }, populate: function (items) { this.list.populate.apply(this.list, arguments); }, resetHeight: function (h) { this.list.resetHeight ? this.list.resetHeight(h) : this.list.element.css({"max-height": h + "px"}); }, setNotSelectedValue: function () { this.list.setNotSelectedValue.apply(this.list, arguments); }, getNotSelectedValue: function () { return this.list.getNotSelectedValue(); }, getAllButtons: function () { return this.list.getAllButtons(); }, getAllLeaves: function () { return this.list.getAllLeaves(); }, getSelectedButtons: function () { return this.list.getSelectedButtons(); }, getNotSelectedButtons: function () { return this.list.getNotSelectedButtons(); }, getIndexByValue: function (value) { return this.list.getIndexByValue(value); }, getNodeById: function (id) { return this.list.getNodeById(id); }, getNodeByValue: function (value) { return this.list.getNodeByValue(value); } }); BI.SingleSelectList.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_select_list", BI.SingleSelectList);/** * 单选加载数据面板 * Created by guy on 15/11/2. * @class BI.SingleSelectLoader * @extends Widget */ BI.SingleSelectLoader = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleSelectLoader.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-loader", logic: { dynamic: true }, el: { height: 400 }, valueFormatter: BI.emptyFn, itemsCreator: BI.emptyFn, onLoaded: BI.emptyFn }); }, _init: function () { BI.SingleSelectLoader.superclass._init.apply(this, arguments); var self = this, opts = this.options; var hasNext = false; this.button_group = BI.createWidget({ type: "bi.single_select_list", element: this, logic: opts.logic, el: BI.extend({ onLoaded: opts.onLoaded, el: { type: "bi.loader", isDefaultInit: false, logic: { dynamic: true, scrolly: true }, el: { chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, behaviors: { redmark: function () { return true; } }, layouts: [{ type: "bi.vertical" }] } } }, opts.el), itemsCreator: function (op, callback) { var startValue = self._startValue; self.storeValue && (op = BI.extend(op || {}, { selectedValues: [self.storeValue] })); opts.itemsCreator(op, function (ob) { hasNext = ob.hasNext; var firstItems = []; if (op.times === 1 && self.storeValue) { var json = BI.map([self.storeValue], function (i, v) { var txt = opts.valueFormatter(v) || v; return { text: txt, value: v, title: txt, selected: false }; }); firstItems = self._createItems(json); } callback(firstItems.concat(self._createItems(ob.items)), ob.keyword || ""); if (op.times === 1 && self.storeValue) { BI.isKey(startValue) && (self.storeValue = startValue); self.setValue(self.storeValue); } (op.times === 1) && self._scrollToTop(); }); }, hasNext: function () { return hasNext; } }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button_group.on(BI.SingleSelectList.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectLoader.EVENT_CHANGE, arguments); }); }, _createItems: function (items) { return BI.createItems(items, { type: "bi.single_select_radio_item", logic: this.options.logic, height: 25, selected: false }); }, _scrollToTop: function () { var self = this; BI.delay(function () { self.button_group.element.scrollTop(0); }, 30); }, _assertValue: function (val) { val || (val = ""); }, setStartValue: function (v) { this._startValue = v; }, setValue: function (v) { this.storeValue = v || ""; this._assertValue(this.storeValue); this.button_group.setValue(this.storeValue); }, getValue: function () { return this.button_group.getValue(); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, empty: function () { this.button_group.empty(); }, populate: function (items) { this.button_group.populate.apply(this.button_group, arguments); }, resetHeight: function (h) { this.button_group.resetHeight(h); }, resetWidth: function (w) { this.button_group.resetWidth(w); } }); BI.SingleSelectLoader.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_select_loader", BI.SingleSelectLoader);/** * 带加载的单选下拉面板 * @class BI.SingleSelectPopupView * @extends Widget */ BI.SingleSelectPopupView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleSelectPopupView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-popup-view", maxWidth: "auto", minWidth: 135, maxHeight: 400, valueFormatter: BI.emptyFn, itemsCreator: BI.emptyFn, onLoaded: BI.emptyFn }); }, _init: function () { BI.SingleSelectPopupView.superclass._init.apply(this, arguments); var self = this, opts = this.options; this.loader = BI.createWidget({ type: "bi.single_select_loader", itemsCreator: opts.itemsCreator, valueFormatter: opts.valueFormatter, onLoaded: opts.onLoaded }); this.popupView = BI.createWidget({ type: "bi.multi_popup_view", stopPropagation: false, maxWidth: opts.maxWidth, minWidth: opts.minWidth, maxHeight: opts.maxHeight, element: this, buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_Sure")], el: this.loader }); this.popupView.on(BI.MultiPopupView.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectPopupView.EVENT_CHANGE); }); this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { switch (index) { case 0: self.fireEvent(BI.SingleSelectPopupView.EVENT_CLICK_CLEAR); break; case 1: self.fireEvent(BI.SingleSelectPopupView.EVENT_CLICK_CONFIRM); break; } }); }, setStartValue: function (v) { this.loader.setStartValue(v); }, setValue: function (v) { this.popupView.setValue(v); }, getValue: function () { return this.popupView.getValue(); }, populate: function (items) { this.popupView.populate.apply(this.popupView, arguments); }, resetHeight: function (h) { this.popupView.resetHeight(h); }, resetWidth: function (w) { this.popupView.resetWidth(w); } }); BI.SingleSelectPopupView.EVENT_CHANGE = "EVENT_CHANGE"; BI.SingleSelectPopupView.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; BI.SingleSelectPopupView.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.shortcut("bi.single_select_popup_view", BI.SingleSelectPopupView);/** * * 单选下拉框 * @class BI.SingleSelectTrigger * @extends BI.Trigger */ BI.SingleSelectTrigger = BI.inherit(BI.Trigger, { constants: { height: 14, rgap: 4, lgap: 4 }, _defaultConfig: function () { return BI.extend(BI.SingleSelectTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-trigger bi-border", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, searcher: {}, switcher: {}, adapter: null, masker: {} }); }, _init: function () { BI.SingleSelectTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options; if (o.height) { this.setHeight(o.height - 2); } this.searcher = BI.createWidget(o.searcher, { type: "bi.single_select_searcher", height: o.height, itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, popup: {}, adapter: o.adapter, masker: o.masker }); this.searcher.on(BI.SingleSelectSearcher.EVENT_START, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_START); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_PAUSE, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_PAUSE); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_SEARCHING, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_SEARCHING, arguments); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_STOP, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_STOP); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_CHANGE, arguments); }); var wrapper = BI.createWidget({ type: "bi.htape", element: this, items: [ { el: this.searcher, width: "fill" }, { el: BI.createWidget(), width: 30 }] }); }, getSearcher: function () { return this.searcher; }, stopEditing: function () { this.searcher.stopSearch(); }, setAdapter: function (adapter) { this.searcher.setAdapter(adapter); }, setValue: function (v) { this.searcher.setValue(v); }, getKey: function () { return this.searcher.getKey(); }, getValue: function () { return this.searcher.getValue(); } }); BI.SingleSelectTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; BI.SingleSelectTrigger.EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; BI.SingleSelectTrigger.EVENT_CHANGE = "EVENT_CHANGE"; BI.SingleSelectTrigger.EVENT_START = "EVENT_START"; BI.SingleSelectTrigger.EVENT_STOP = "EVENT_STOP"; BI.SingleSelectTrigger.EVENT_PAUSE = "EVENT_PAUSE"; BI.SingleSelectTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; BI.SingleSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; BI.shortcut("bi.single_select_trigger", BI.SingleSelectTrigger);/** * 单选输入框 * Created by guy on 15/11/3. * @class BI.SingleSelectEditor * @extends Widget */ BI.SingleSelectEditor = BI.inherit(BI.Widget, { _const: { checkSelected: BI.i18nText("BI-Check_Selected") }, _defaultConfig: function () { return BI.extend(BI.SingleSelectEditor.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-editor", el: {} }); }, _init: function () { BI.SingleSelectEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget(o.el, { type: "bi.state_editor", element: this, height: o.height, watermark: BI.i18nText("BI-Basic_Search"), allowBlank: true }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.StateEditor.EVENT_PAUSE, function () { self.fireEvent(BI.SingleSelectEditor.EVENT_PAUSE); }); this.editor.on(BI.StateEditor.EVENT_CLICK_LABEL, function () { }); }, focus: function () { this.editor.focus(); }, blur: function () { this.editor.blur(); }, setState: function (state) { this.editor.setState(state); }, setValue: function (v) { this.editor.setValue(v); }, getValue: function () { var v = this.editor.getState(); if (BI.isArray(v) && v.length > 0) { return v[v.length - 1]; } return ""; }, getKeywords: function () { var val = this.editor.getLastValidValue(); var keywords = val.match(/[\S]+/g); if (BI.isEndWithBlank(val)) { return keywords.concat([" "]); } return keywords; }, populate: function (items) { } }); BI.SingleSelectEditor.EVENT_PAUSE = "SingleSelectEditor.EVENT_PAUSE"; BI.shortcut("bi.single_select_editor", BI.SingleSelectEditor);/** * searcher * Created by guy on 15/11/3. * @class BI.SingleSelectSearcher * @extends Widget */ BI.SingleSelectSearcher = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleSelectSearcher.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-searcher", itemsCreator: BI.emptyFn, el: {}, popup: {}, valueFormatter: BI.emptyFn, adapter: null, masker: {} }); }, _init: function () { BI.SingleSelectSearcher.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget(o.el, { type: "bi.single_select_editor", height: o.height }); this.searcher = BI.createWidget({ type: "bi.searcher", element: this, height: o.height, isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback(); }, el: this.editor, popup: BI.extend({ type: "bi.single_select_search_pane", valueFormatter: o.valueFormatter, keywordGetter: function () { return self.editor.getValue(); }, itemsCreator: function (op, callback) { op.keyword = self.editor.getValue(); this.setKeyword(op.keyword); o.itemsCreator(op, callback); } }, o.popup), adapter: o.adapter, masker: o.masker }); this.searcher.on(BI.Searcher.EVENT_START, function () { self.fireEvent(BI.SingleSelectSearcher.EVENT_START); }); this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { if (this.hasMatched()) { } self.fireEvent(BI.SingleSelectSearcher.EVENT_PAUSE); }); this.searcher.on(BI.Searcher.EVENT_STOP, function () { self.fireEvent(BI.SingleSelectSearcher.EVENT_STOP); }); this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectSearcher.EVENT_CHANGE, arguments); }); this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { var keywords = this.getKeywords(); self.fireEvent(BI.SingleSelectSearcher.EVENT_SEARCHING, keywords); }); }, adjustView: function () { this.searcher.adjustView(); }, isSearching: function () { return this.searcher.isSearching(); }, stopSearch: function () { this.searcher.stopSearch(); }, getKeyword: function () { return this.editor.getValue(); }, hasMatched: function () { return this.searcher.hasMatched(); }, hasChecked: function () { return this.searcher.getView() && this.searcher.getView().hasChecked(); }, setAdapter: function (adapter) { this.searcher.setAdapter(adapter); }, setState: function (v) { var o = this.options; v || (v = ""); if (v === "") { this.editor.setState(BI.Selection.None); } else { this.editor.setState(o.valueFormatter(v + "") || (v + "")); } }, setValue: function (ob) { this.setState(ob); this.searcher.setValue(ob); }, getKey: function () { return this.editor.getValue(); }, getValue: function () { return this.searcher.getValue(); }, populate: function (items) { this.searcher.populate.apply(this.searcher, arguments); } }); BI.SingleSelectSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.SingleSelectSearcher.EVENT_CHANGE = "EVENT_CHANGE"; BI.SingleSelectSearcher.EVENT_START = "EVENT_START"; BI.SingleSelectSearcher.EVENT_STOP = "EVENT_STOP"; BI.SingleSelectSearcher.EVENT_PAUSE = "EVENT_PAUSE"; BI.SingleSelectSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; BI.shortcut("bi.single_select_searcher", BI.SingleSelectSearcher);/** * 单选加载数据搜索loader面板 * Created by guy on 15/11/4. * @class BI.SingleSelectSearchLoader * @extends Widget */ BI.SingleSelectSearchLoader = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleSelectSearchLoader.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-search-loader", itemsCreator: BI.emptyFn, keywordGetter: BI.emptyFn, valueFormatter: BI.emptyFn }); }, _init: function () { BI.SingleSelectSearchLoader.superclass._init.apply(this, arguments); var self = this, opts = this.options; var hasNext = false; this.button_group = BI.createWidget({ type: "bi.single_select_list", element: this, logic: { dynamic: false }, el: { tipText: BI.i18nText("BI-No_Select"), el: { type: "bi.loader", isDefaultInit: false, logic: { dynamic: true, scrolly: true }, el: { chooseType: BI.ButtonGroup.CHOOSE_TYPE_SINGLE, behaviors: { redmark: function () { return true; } }, layouts: [{ type: "bi.vertical" }] } } }, itemsCreator: function (op, callback) { self.storeValue && (op = BI.extend(op || {}, { selectedValues: [self.storeValue] })); opts.itemsCreator(op, function (ob) { var keyword = ob.keyword = opts.keywordGetter(); hasNext = ob.hasNext; var firstItems = []; if (op.times === 1 && self.storeValue) { var json = BI.map([self.storeValue], function (i, v) { var txt = opts.valueFormatter(v) || v; return { text: txt, value: v, title: txt, selected: false }; }); firstItems = self._createItems(json); } if(keyword) { var flag = false; for(var i = 0; i < ob.items.length; i++) { if(BI.contains(ob.items[i], keyword)) { flag = true; } } if(!flag) { var preItems = self._createItems([{ text: keyword, value: keyword, title: keyword, selected: false }]); firstItems = firstItems.concat(preItems); } } callback(firstItems.concat(self._createItems(ob.items)), keyword); if (op.times === 1 && self.storeValue) { self.setValue(self.storeValue); } }); }, hasNext: function () { return hasNext; } }); this.button_group.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.button_group.on(BI.SingleSelectList.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectSearchLoader.EVENT_CHANGE, arguments); }); }, _createItems: function (items) { return BI.createItems(items, { type: "bi.single_select_radio_item", logic: { dynamic: false }, height: 25, selected: false }); }, _filterValues: function (src) { var o = this.options; var keyword = o.keywordGetter(); var values = BI.deepClone(src.value) || []; var newValues = BI.map(values, function (i, v) { return { text: o.valueFormatter(v) || v, value: v }; }); if (BI.isKey(keyword)) { var search = BI.Func.getSearchResult(newValues, keyword); values = search.matched.concat(search.finded); } return BI.map(values, function (i, v) { return { text: v.text, title: v.text, value: v.value, selected: false }; }); }, setValue: function (v) { // 暂存的值一定是新的值,不然v改掉后,storeValue也跟着改了 this.storeValue = v; this.button_group.setValue(v); }, getValue: function () { return this.button_group.getValue(); }, getAllButtons: function () { return this.button_group.getAllButtons(); }, empty: function () { this.button_group.empty(); }, populate: function (items) { this.button_group.populate.apply(this.button_group, arguments); }, resetHeight: function (h) { this.button_group.resetHeight(h); }, resetWidth: function (w) { this.button_group.resetWidth(w); } }); BI.SingleSelectSearchLoader.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_select_search_add_loader", BI.SingleSelectSearchLoader);/** * * 在搜索框中输入文本弹出的面板 * @class BI.SingleSelectSearchPane * @extends Widget */ BI.SingleSelectSearchPane = BI.inherit(BI.Widget, { constants: { height: 25, lgap: 10, tgap: 5 }, _defaultConfig: function () { return BI.extend(BI.SingleSelectSearchPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-search-pane bi-card", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, keywordGetter: BI.emptyFn }); }, _init: function () { BI.SingleSelectSearchPane.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tooltipClick = BI.createWidget({ type: "bi.label", invisible: true, text: BI.i18nText("BI-Click_Blank_To_Select"), cls: "single-select-toolbar", height: this.constants.height }); this.loader = BI.createWidget({ type: "bi.single_select_search_add_loader", keywordGetter: o.keywordGetter, valueFormatter: o.valueFormatter, itemsCreator: function (op, callback) { o.itemsCreator.apply(self, [op, function (res) { callback(res); self.setKeyword(o.keywordGetter()); }]); } }); this.loader.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.resizer = BI.createWidget({ type: "bi.vtape", element: this, items: [{ el: this.tooltipClick, height: 0 }, { el: this.loader }] }); this.tooltipClick.setVisible(false); }, setKeyword: function (keyword) { var btn; var isVisible = this.loader.getAllButtons().length > 0 && (btn = this.loader.getAllButtons()[0]) && (keyword === btn.getValue()); if (isVisible !== this.tooltipClick.isVisible()) { this.tooltipClick.setVisible(isVisible); this.resizer.attr("items")[0].height = (isVisible ? this.constants.height : 0); this.resizer.resize(); } }, hasMatched: function () { return this.tooltipClick.isVisible(); }, setValue: function (v) { this.loader.setValue(v); }, getValue: function () { return this.loader.getValue(); }, empty: function () { this.loader.empty(); }, populate: function (items) { this.loader.populate.apply(this.loader, arguments); } }); BI.SingleSelectSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_select_search_add_pane", BI.SingleSelectSearchPane);/** * * @class BI.SingleSelectCombo * @extends BI.Single */ BI.SingleSelectCombo = BI.inherit(BI.Single, { _defaultConfig: function () { return BI.extend(BI.SingleSelectCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-combo", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, height: 28 }); }, _init: function () { BI.SingleSelectCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; var assertShowValue = function () { BI.isKey(self._startValue) && (self.storeValue = self._startValue); self.trigger.getSearcher().setState(self.storeValue); }; this.storeValue = ""; // 标记正在请求数据 this.requesting = false; this.trigger = BI.createWidget({ type: "bi.single_select_add_trigger", height: o.height, // adapter: this.popup, masker: { offset: { left: 1, top: 1, right: 2, bottom: 33 } }, valueFormatter: o.valueFormatter, itemsCreator: function (op, callback) { o.itemsCreator(op, function (res) { if (op.times === 1 && BI.isNotNull(op.keywords)) { // 预防trigger内部把当前的storeValue改掉 self.trigger.setValue(self.getValue()); } callback.apply(self, arguments); }); } }); this.trigger.on(BI.SingleSelectTrigger.EVENT_START, function () { self._setStartValue(""); this.getSearcher().setValue(self.storeValue); }); this.trigger.on(BI.SingleSelectTrigger.EVENT_STOP, function () { self._setStartValue(""); }); this.trigger.on(BI.SingleSelectTrigger.EVENT_PAUSE, function () { if (this.getSearcher().hasMatched()) { var keyword = this.getSearcher().getKeyword(); self._join({ type: BI.Selection.Multi, value: [keyword] }, function () { self.combo.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); self.populate(); self._setStartValue(""); }); } }); this.trigger.on(BI.SingleSelectTrigger.EVENT_SEARCHING, function (keywords) { var last = BI.last(keywords); keywords = BI.initial(keywords || []); if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { self.combo.setValue(self.storeValue); assertShowValue(); self.combo.populate(); self._setStartValue(""); } else { self.combo.setValue(self.storeValue); assertShowValue(); } }); } }); this.trigger.on(BI.SingleSelectTrigger.EVENT_CHANGE, function (value, obj) { self.storeValue = this.getValue(); assertShowValue(); }); this.trigger.on(BI.SingleSelectTrigger.EVENT_COUNTER_CLICK, function () { if (!self.combo.isViewVisible()) { self.combo.showView(); } }); this.combo = BI.createWidget({ type: "bi.combo", toggle: false, el: this.trigger, adjustLength: 1, popup: { type: "bi.single_select_popup_view", ref: function () { self.popup = this; self.trigger.setAdapter(this); }, listeners: [{ eventName: BI.SingleSelectPopupView.EVENT_CHANGE, action: function () { self.storeValue = this.getValue(); self._adjust(function () { assertShowValue(); }); } }, { eventName: BI.SingleSelectPopupView.EVENT_CLICK_CONFIRM, action: function () { self._defaultState(); } }, { eventName: BI.SingleSelectPopupView.EVENT_CLICK_CLEAR, action: function () { self.setValue(); self._defaultState(); } }], itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, onLoaded: function () { BI.nextTick(function () { self.combo.adjustWidth(); self.combo.adjustHeight(); self.trigger.getSearcher().adjustView(); }); } }, hideChecker: function (e) { return triggerBtn.element.find(e.target).length === 0; } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { this.setValue(self.storeValue); BI.nextTick(function () { self.populate(); }); }); // 当退出的时候如果还在处理请求,则等请求结束后再对外发确定事件 this.wants2Quit = false; this.combo.on(BI.Combo.EVENT_AFTER_HIDEVIEW, function () { // important:关闭弹出时又可能没有退出编辑状态 self.trigger.stopEditing(); if (self.requesting === true) { self.wants2Quit = true; } else { self.fireEvent(BI.SingleSelectCombo.EVENT_CONFIRM); } }); var triggerBtn = BI.createWidget({ type: "bi.trigger_icon_button", width: o.height, height: o.height, cls: "single-select-trigger-icon-button bi-border-left" }); triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { if (self.combo.isViewVisible()) { self.combo.hideView(); } else { self.combo.showView(); } }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.combo, left: 0, right: 0, top: 0, bottom: 0 }, { el: triggerBtn, right: 0, top: 0, bottom: 0 }] }); }, _defaultState: function () { this.trigger.stopEditing(); this.combo.hideView(); }, _assertValue: function (val) { val || (val = ""); }, _makeMap: function (values) { return BI.makeObject(values || []); }, _joinKeywords: function (keywords, callback) { var self = this, o = this.options; this._assertValue(this.storeValue); this.requesting = true; o.itemsCreator({ type: BI.SingleSelectCombo.REQ_GET_ALL_DATA, keywords: keywords }, function (ob) { var values = BI.pluck(ob.items, "value"); digest(values); }); function digest (items) { var selectedMap = self._makeMap(items); BI.each(keywords, function (i, val) { if (BI.isNotNull(selectedMap[val])) { self.storeValue.value["remove"](val); } }); self._adjust(callback); } }, _joinAll: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this.requesting = true; o.itemsCreator({ type: BI.SingleSelectCombo.REQ_GET_ALL_DATA, keywords: [this.trigger.getKey()] }, function (ob) { var items = BI.pluck(ob.items, "value"); if (self.storeValue.type === res.type) { var change = false; var map = self._makeMap(self.storeValue.value); BI.each(items, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (self.storeValue.value = BI.values(map)); self._adjust(callback); return; } var selectedMap = self._makeMap(self.storeValue.value); var notSelectedMap = self._makeMap(res.value); var newItems = []; BI.each(items, function (i, item) { if (BI.isNotNull(selectedMap[items[i]])) { delete selectedMap[items[i]]; } if (BI.isNull(notSelectedMap[items[i]])) { newItems.push(item); } }); self.storeValue.value = newItems.concat(BI.values(selectedMap)); self._adjust(callback); }); }, _adjust: function (callback) { var self = this, o = this.options; if (!this._count) { o.itemsCreator({ type: BI.SingleSelectCombo.REQ_GET_DATA_LENGTH }, function (res) { self._count = res.count; adjust(); callback(); }); } else { adjust(); callback(); } function adjust () { if (self.wants2Quit === true) { self.fireEvent(BI.SingleSelectCombo.EVENT_CONFIRM); self.wants2Quit = false; } self.requesting = false; } }, _join: function (res, callback) { var self = this, o = this.options; this._assertValue(res); this._assertValue(this.storeValue); if (this.storeValue.type === res.type) { var map = this._makeMap(this.storeValue.value); BI.each(res.value, function (i, v) { if (!map[v]) { self.storeValue.value.push(v); map[v] = v; } }); var change = false; BI.each(res.assist, function (i, v) { if (BI.isNotNull(map[v])) { change = true; delete map[v]; } }); change && (this.storeValue.value = BI.values(map)); self._adjust(callback); return; } this._joinAll(res, callback); }, _setStartValue: function (value) { this._startValue = value; this.popup.setStartValue(value); }, setValue: function (v) { this.storeValue = v || ""; this._assertValue(this.storeValue); this.combo.setValue(this.storeValue); }, getValue: function () { return this.storeValue; }, populate: function () { this._count = null; this.combo.populate.apply(this.combo, arguments); } }); BI.extend(BI.SingleSelectCombo, { REQ_GET_DATA_LENGTH: 0, REQ_GET_ALL_DATA: -1 }); BI.SingleSelectCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.shortcut("bi.single_select_add_combo", BI.SingleSelectCombo);/** * * 单选下拉框 * @class BI.SingleSelectTrigger * @extends BI.Trigger */ BI.SingleSelectTrigger = BI.inherit(BI.Trigger, { constants: { height: 14, rgap: 4, lgap: 4 }, _defaultConfig: function () { return BI.extend(BI.SingleSelectTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-trigger bi-border", itemsCreator: BI.emptyFn, valueFormatter: BI.emptyFn, searcher: {}, switcher: {}, adapter: null, masker: {} }); }, _init: function () { BI.SingleSelectTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options; if (o.height) { this.setHeight(o.height - 2); } this.searcher = BI.createWidget(o.searcher, { type: "bi.single_select_add_searcher", height: o.height, itemsCreator: o.itemsCreator, valueFormatter: o.valueFormatter, popup: {}, adapter: o.adapter, masker: o.masker }); this.searcher.on(BI.SingleSelectSearcher.EVENT_START, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_START); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_PAUSE, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_PAUSE); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_SEARCHING, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_SEARCHING, arguments); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_STOP, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_STOP); }); this.searcher.on(BI.SingleSelectSearcher.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectTrigger.EVENT_CHANGE, arguments); }); var wrapper = BI.createWidget({ type: "bi.htape", element: this, items: [ { el: this.searcher, width: "fill" }, { el: BI.createWidget(), width: 30 }] }); }, getSearcher: function () { return this.searcher; }, stopEditing: function () { this.searcher.stopSearch(); }, setAdapter: function (adapter) { this.searcher.setAdapter(adapter); }, setValue: function (v) { this.searcher.setValue(v); }, getKey: function () { return this.searcher.getKey(); }, getValue: function () { return this.searcher.getValue(); } }); BI.SingleSelectTrigger.EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"; BI.SingleSelectTrigger.EVENT_COUNTER_CLICK = "EVENT_COUNTER_CLICK"; BI.SingleSelectTrigger.EVENT_CHANGE = "EVENT_CHANGE"; BI.SingleSelectTrigger.EVENT_START = "EVENT_START"; BI.SingleSelectTrigger.EVENT_STOP = "EVENT_STOP"; BI.SingleSelectTrigger.EVENT_PAUSE = "EVENT_PAUSE"; BI.SingleSelectTrigger.EVENT_SEARCHING = "EVENT_SEARCHING"; BI.SingleSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW = "EVENT_BEFORE_COUNTER_POPUPVIEW"; BI.shortcut("bi.single_select_add_trigger", BI.SingleSelectTrigger);/** * searcher * Created by guy on 15/11/3. * @class BI.SingleSelectSearcher * @extends Widget */ BI.SingleSelectSearcher = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleSelectSearcher.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-select-searcher", itemsCreator: BI.emptyFn, el: {}, popup: {}, valueFormatter: BI.emptyFn, adapter: null, masker: {} }); }, _init: function () { BI.SingleSelectSearcher.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget(o.el, { type: "bi.single_select_editor", height: o.height }); this.searcher = BI.createWidget({ type: "bi.searcher", element: this, height: o.height, isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback(); }, el: this.editor, popup: BI.extend({ type: "bi.single_select_search_add_pane", valueFormatter: o.valueFormatter, keywordGetter: function () { return self.editor.getValue(); }, itemsCreator: function (op, callback) { op.keyword = self.editor.getValue(); this.setKeyword(op.keyword); o.itemsCreator(op, callback); } }, o.popup), adapter: o.adapter, masker: o.masker }); this.searcher.on(BI.Searcher.EVENT_START, function () { self.fireEvent(BI.SingleSelectSearcher.EVENT_START); }); this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { if (this.hasMatched()) { } self.fireEvent(BI.SingleSelectSearcher.EVENT_PAUSE); }); this.searcher.on(BI.Searcher.EVENT_STOP, function () { self.fireEvent(BI.SingleSelectSearcher.EVENT_STOP); }); this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { self.fireEvent(BI.SingleSelectSearcher.EVENT_CHANGE, arguments); }); this.searcher.on(BI.Searcher.EVENT_SEARCHING, function () { var keywords = this.getKeywords(); self.fireEvent(BI.SingleSelectSearcher.EVENT_SEARCHING, keywords); }); }, adjustView: function () { this.searcher.adjustView(); }, isSearching: function () { return this.searcher.isSearching(); }, stopSearch: function () { this.searcher.stopSearch(); }, getKeyword: function () { return this.editor.getValue(); }, hasMatched: function () { return this.searcher.hasMatched(); }, hasChecked: function () { return this.searcher.getView() && this.searcher.getView().hasChecked(); }, setAdapter: function (adapter) { this.searcher.setAdapter(adapter); }, setState: function (v) { var o = this.options; v || (v = ""); if (v === "") { this.editor.setState(BI.Selection.None); } else { this.editor.setState(o.valueFormatter(v + "") || (v + "")); } }, setValue: function (ob) { this.setState(ob); this.searcher.setValue(ob); }, getKey: function () { return this.editor.getValue(); }, getValue: function () { return this.searcher.getValue(); }, populate: function (items) { this.searcher.populate.apply(this.searcher, arguments); } }); BI.SingleSelectSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.SingleSelectSearcher.EVENT_CHANGE = "EVENT_CHANGE"; BI.SingleSelectSearcher.EVENT_START = "EVENT_START"; BI.SingleSelectSearcher.EVENT_STOP = "EVENT_STOP"; BI.SingleSelectSearcher.EVENT_PAUSE = "EVENT_PAUSE"; BI.SingleSelectSearcher.EVENT_SEARCHING = "EVENT_SEARCHING"; BI.shortcut("bi.single_select_add_searcher", BI.SingleSelectSearcher);/** * Created by User on 2017/11/16. */ BI.SignTextEditor = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.SignTextEditor.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-sign-initial-editor", hgap: 4, vgap: 2, lgap: 0, rgap: 0, tgap: 0, bgap: 0, validationChecker: BI.emptyFn, quitChecker: BI.emptyFn, allowBlank: true, watermark: "", errorText: "", text: "", height: 24 }); }, _init: function () { BI.SignTextEditor.superclass._init.apply(this, arguments); var self = this, o = this.options; this.editor = BI.createWidget({ type: "bi.editor", height: o.height, hgap: o.hgap, vgap: o.vgap, lgap: o.lgap, rgap: o.rgap, tgap: o.tgap, bgap: o.bgap, value: o.value, validationChecker: o.validationChecker, quitChecker: o.quitChecker, allowBlank: o.allowBlank, watermark: o.watermark, errorText: o.errorText }); this.text = BI.createWidget({ type: "bi.text_button", cls: "sign-editor-text", title: o.title, warningTitle: o.warningTitle, tipType: o.tipType, textAlign: "left", height: o.height, hgap: 4, handler: function () { self._showInput(); self.editor.focus(); self.editor.selectAll(); } }); this.text.on(BI.TextButton.EVENT_CHANGE, function () { BI.nextTick(function () { self.fireEvent(BI.SignTextEditor.EVENT_CLICK_LABEL); }); }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.text, left: 0, right: 0, top: 0, bottom: 0 }] }); this.editor.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.editor.on(BI.Editor.EVENT_CONFIRM, function () { self._showHint(); self._checkText(); self.fireEvent(BI.SignTextEditor.EVENT_CONFIRM, arguments); }); this.editor.on(BI.Editor.EVENT_ERROR, function () { self._checkText(); }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [this.editor] }); this._showHint(); self._checkText(); }, _checkText: function () { var o = this.options; BI.nextTick(BI.bind(function () { if (this.editor.getValue() === "") { this.text.setValue(o.watermark || ""); this.text.element.addClass("bi-water-mark"); } else { var v = this.editor.getValue(); v = (BI.isEmpty(v) || v == o.text) ? o.text : v + o.text; this.text.setValue(v); this.text.element.removeClass("bi-water-mark"); } }, this)); }, _showInput: function () { this.editor.visible(); this.text.invisible(); }, _showHint: function () { this.editor.invisible(); this.text.visible(); }, setTitle: function (title) { this.text.setTitle(title); }, setWarningTitle: function (title) { this.text.setWarningTitle(title); }, focus: function () { this._showInput(); this.editor.focus(); }, blur: function () { this.editor.blur(); this._showHint(); this._checkText(); }, doRedMark: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doRedMark.apply(this.text, arguments); }, unRedMark: function () { this.text.unRedMark.apply(this.text, arguments); }, doHighLight: function () { if (this.editor.getValue() === "" && BI.isKey(this.options.watermark)) { return; } this.text.doHighLight.apply(this.text, arguments); }, unHighLight: function () { this.text.unHighLight.apply(this.text, arguments); }, isValid: function () { return this.editor.isValid(); }, setErrorText: function (text) { this.editor.setErrorText(text); }, getErrorText: function () { return this.editor.getErrorText(); }, isEditing: function () { return this.editor.isEditing(); }, getLastValidValue: function () { return this.editor.getLastValidValue(); }, setValue: function (v) { this.editor.setValue(v); this._checkText(); }, getValue: function () { return this.editor.getValue(); }, getState: function () { return this.text.getValue(); }, setState: function (v) { var o = this.options; this._showHint(); v = (BI.isEmpty(v) || v == o.text) ? o.text : v + o.text; this.text.setValue(v); } }); BI.SignTextEditor.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.SignTextEditor.EVENT_CLICK_LABEL = "EVENT_CLICK_LABEL"; BI.shortcut("bi.sign_text_editor", BI.SignTextEditor);/** * Created by zcf on 2016/9/22. */ BI.SliderIconButton = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SliderIconButton.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-slider-button" }); }, _init: function () { BI.extend(BI.SliderIconButton.superclass._init.apply(this, arguments)); this.slider = BI.createWidget({ type: "bi.icon_button", cls: "slider-icon slider-button", iconWidth: 14, iconHeight: 14, height: 14, width: 14 }); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: this.slider, top: 7, left: -7 }], width: 0, height: 14 }); } }); BI.shortcut("bi.single_slider_button", BI.SliderIconButton);/** * Created by zcf on 2016/9/22. */ BI.SingleSlider = BI.inherit(BI.Widget, { _constant: { EDITOR_WIDTH: 90, EDITOR_HEIGHT: 30, SLIDER_WIDTH_HALF: 15, SLIDER_WIDTH: 30, SLIDER_HEIGHT: 30, TRACK_HEIGHT: 24 }, _defaultConfig: function () { return BI.extend(BI.SingleSlider.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-slider bi-slider-track", digit: false, unit: "" }); }, _init: function () { BI.SingleSlider.superclass._init.apply(this, arguments); var self = this, o = this.options; var c = this._constant; this.enable = false; this.value = ""; this.grayTrack = BI.createWidget({ type: "bi.layout", cls: "gray-track", height: 6 }); this.blueTrack = BI.createWidget({ type: "bi.layout", cls: "blue-track bi-high-light-background", height: 6 }); this.track = this._createTrackWrapper(); this.slider = BI.createWidget({ type: "bi.single_slider_button" }); this._draggable(this.slider); var sliderVertical = BI.createWidget({ type: "bi.vertical", items: [{ type: "bi.absolute", items: [this.slider] }], hgap: c.SLIDER_WIDTH_HALF, height: c.SLIDER_HEIGHT }); sliderVertical.element.click(function (e) { if (self.enable) { var offset = e.clientX - self.element.offset().left - c.SLIDER_WIDTH_HALF; var trackLength = self.track.element[0].scrollWidth; var percent = 0; if (offset < 0) { percent = 0; } if (offset > 0 && offset < (trackLength - c.SLIDER_WIDTH)) { percent = offset * 100 / self._getGrayTrackLength(); } if (offset > (trackLength - c.SLIDER_WIDTH)) { percent = 100; } var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setAllPosition(significantPercent); var v = self._getValueByPercent(significantPercent); v = o.digit === false ? v : v.toFixed(o.digit); self.label.setValue(v); self.value = v; self.fireEvent(BI.SingleSlider.EVENT_CHANGE); } }); this.label = BI.createWidget({ type: "bi.sign_text_editor", cls: "slider-editor-button", errorText: "", text: o.unit, width: c.EDITOR_WIDTH - 2, allowBlank: false, validationChecker: function (v) { return self._checkValidation(v); } }); this.label.element.hover(function () { self.label.element.removeClass("bi-border").addClass("bi-border"); }, function () { self.label.element.removeClass("bi-border"); }); this.label.on(BI.SignEditor.EVENT_CONFIRM, function () { var v = BI.parseFloat(this.getValue()); var percent = self._getPercentByValue(v); var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setAllPosition(significantPercent); this.setValue(v); self.value = v; self.fireEvent(BI.SingleSlider.EVENT_CHANGE); }); this._setVisible(false); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.track, width: "100%", height: c.TRACK_HEIGHT }] }], hgap: 7, height: c.TRACK_HEIGHT }, top: 23, left: 0, width: "100%" }, { el: sliderVertical, top: 20, left: 0, width: "100%" }, { el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [this.label] }], rgap: c.EDITOR_WIDTH, height: c.EDITOR_HEIGHT }, top: 0, left: 0, width: "100%" }] }); }, _draggable: function (widget) { var self = this, o = this.options; var startDrag = false; var size = 0, offset = 0, defaultSize = 0; var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { if (mouseMoveTracker.isDragging()) { startDrag = true; offset += deltaX; size = optimizeSize(defaultSize + offset); widget.element.addClass("dragging"); var percent = size * 100 / (self._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1));// 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 self._setBlueTrack(significantPercent); self._setLabelPosition(significantPercent); self._setSliderPosition(significantPercent); var v = self._getValueByPercent(significantPercent); v = o.digit === false ? v : v.toFixed(o.digit); self.label.setValue(v); self.value = v; self.fireEvent(BI.SingleSlider.EVENT_CHANGE); } }, function () { if (startDrag === true) { size = optimizeSize(size); var percent = size * 100 / (self._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setSliderPosition(significantPercent); size = 0; offset = 0; defaultSize = size; startDrag = false; } widget.element.removeClass("dragging"); mouseMoveTracker.releaseMouseMoves(); self.fireEvent(BI.SingleSlider.EVENT_CHANGE); }, document); widget.element.on("mousedown", function (event) { if(!widget.isEnabled()) { return; } defaultSize = this.offsetLeft; optimizeSize(defaultSize); mouseMoveTracker.captureMouseMoves(event); }); function optimizeSize (s) { return BI.clamp(s, 0, self._getGrayTrackLength()); } }, _createTrackWrapper: function () { return BI.createWidget({ type: "bi.absolute", items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.grayTrack, top: 0, left: 0, width: "100%" }, { el: this.blueTrack, top: 0, left: 0, width: "0%" }] }], hgap: 8, height: 8 }, top: 8, left: 0, width: "100%" }] }); }, _checkValidation: function (v) { var o = this.options; var valid = false; if (BI.isNumeric(v) && !(BI.isNull(v) || v < this.min || v > this.max)) { if(o.digit === false) { valid = true; }else{ var dotText = (v + "").split(".")[1] || ""; valid = (dotText.length === o.digit); } } return valid; }, _setBlueTrack: function (percent) { this.blueTrack.element.css({width: percent + "%"}); }, _setLabelPosition: function (percent) { this.label.element.css({left: percent + "%"}); }, _setSliderPosition: function (percent) { this.slider.element.css({left: percent + "%"}); }, _setAllPosition: function (percent) { this._setSliderPosition(percent); this._setLabelPosition(percent); this._setBlueTrack(percent); }, _setVisible: function (visible) { this.slider.setVisible(visible); this.label.setVisible(visible); }, _getGrayTrackLength: function () { return this.grayTrack.element[0].scrollWidth; }, _getValueByPercent: function (percent) { var thousandth = BI.parseInt(percent * 10); return (((this.max - this.min) * thousandth) / 1000 + this.min); }, _getPercentByValue: function (v) { return (v - this.min) * 100 / (this.max - this.min); }, getValue: function () { return this.value; }, setValue: function (v) { var o = this.options; v = BI.parseFloat(v); v = o.digit === false ? v : v.toFixed(o.digit); if ((!isNaN(v))) { if (this._checkValidation(v)) { this.value = v; } if (v > this.max) { this.value = this.max; } if (v < this.min) { this.value = this.min; } } }, setMinAndMax: function (v) { var minNumber = BI.parseFloat(v.min); var maxNumber = BI.parseFloat(v.max); if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber > minNumber )) { this.min = minNumber; this.max = maxNumber; } }, reset: function () { this._setVisible(false); this.enable = false; this.value = ""; this.min = 0; this.max = 0; this._setBlueTrack(0); }, populate: function () { if (!isNaN(this.min) && !isNaN(this.max)) { this._setVisible(true); this.enable = true; this.label.setErrorText(BI.i18nText("BI-Please_Enter") + this.min + "-" + this.max + BI.i18nText("BI-Basic_De") + BI.i18nText("BI-Basic_Number")); if (BI.isNumeric(this.value) || BI.isNotEmptyString(this.value)) { this.label.setValue(this.value); this._setAllPosition(this._getPercentByValue(this.value)); } else { this.label.setValue(this.max); this._setAllPosition(100); } } } }); BI.SingleSlider.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_slider", BI.SingleSlider);/** * Created by Urthur on 2017/9/12. */ BI.SingleSliderLabel = BI.inherit(BI.Widget, { _constant: { EDITOR_WIDTH: 90, EDITOR_HEIGHT: 20, HEIGHT: 20, SLIDER_WIDTH_HALF: 15, SLIDER_WIDTH: 30, SLIDER_HEIGHT: 30, TRACK_HEIGHT: 24 }, _defaultConfig: function () { return BI.extend(BI.SingleSliderLabel.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-slider-label bi-slider-track", digit: false, unit: "" }); }, _init: function () { BI.SingleSliderLabel.superclass._init.apply(this, arguments); var self = this, o = this.options; var c = this._constant; this.enable = false; this.value = ""; this.grayTrack = BI.createWidget({ type: "bi.layout", cls: "gray-track", height: 6 }); this.blueTrack = BI.createWidget({ type: "bi.layout", cls: "blue-track bi-high-light-background", height: 6 }); this.track = this._createTrackWrapper(); this.slider = BI.createWidget({ type: "bi.single_slider_button" }); this._draggable(this.slider); var sliderVertical = BI.createWidget({ type: "bi.vertical", items: [{ type: "bi.absolute", items: [this.slider] }], hgap: c.SLIDER_WIDTH_HALF, height: c.SLIDER_HEIGHT }); sliderVertical.element.click(function (e) { if (self.enable) { var offset = e.clientX - self.element.offset().left - c.SLIDER_WIDTH_HALF; var trackLength = self.track.element[0].scrollWidth; var percent = 0; if (offset < 0) { percent = 0; } if (offset > 0 && offset < (trackLength - c.SLIDER_WIDTH)) { percent = offset * 100 / self._getGrayTrackLength(); } if (offset > (trackLength - c.SLIDER_WIDTH)) { percent = 100; } var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setAllPosition(significantPercent); var v = self._getValueByPercent(significantPercent); v = o.digit === false ? v : v.toFixed(o.digit); self.label.setText(v + o.unit); self.value = v; self.fireEvent(BI.SingleSliderLabel.EVENT_CHANGE); } }); this.label = BI.createWidget({ type: "bi.label", height: c.HEIGHT, width: c.EDITOR_WIDTH - 2 }); this._setVisible(false); BI.createWidget({ type: "bi.absolute", element: this, items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.track, width: "100%", height: c.TRACK_HEIGHT }] }], hgap: 7, height: c.TRACK_HEIGHT }, top: 13, left: 0, width: "100%" }, { el: sliderVertical, top: 10, left: 0, width: "100%" }, { el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [this.label] }], rgap: c.EDITOR_WIDTH, height: c.EDITOR_HEIGHT }, top: 0, left: 0, width: "100%" }] }); }, _draggable: function (widget) { var self = this, o = this.options; var startDrag = false; var size = 0, offset = 0, defaultSize = 0; var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { if (mouseMoveTracker.isDragging()) { startDrag = true; offset += deltaX; size = optimizeSize(defaultSize + offset); widget.element.addClass("dragging"); var percent = size * 100 / (self._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1));// 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 self._setBlueTrack(significantPercent); self._setLabelPosition(significantPercent); self._setSliderPosition(significantPercent); var v = self._getValueByPercent(significantPercent); v = o.digit === false ? v : v.toFixed(o.digit); self.label.setValue(v); self.value = v; self.fireEvent(BI.SingleSliderLabel.EVENT_CHANGE); } }, function () { if (startDrag === true) { size = optimizeSize(size); var percent = size * 100 / (self._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setSliderPosition(significantPercent); size = 0; offset = 0; defaultSize = size; startDrag = false; } widget.element.removeClass("dragging"); mouseMoveTracker.releaseMouseMoves(); self.fireEvent(BI.SingleSliderLabel.EVENT_CHANGE); }, document); widget.element.on("mousedown", function (event) { if(!widget.isEnabled()) { return; } defaultSize = this.offsetLeft; optimizeSize(defaultSize); mouseMoveTracker.captureMouseMoves(event); }); function optimizeSize (s) { return BI.clamp(s, 0, self._getGrayTrackLength()); } }, _createTrackWrapper: function () { return BI.createWidget({ type: "bi.absolute", items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.grayTrack, top: 0, left: 0, width: "100%" }, { el: this.blueTrack, top: 0, left: 0, width: "0%" }] }], hgap: 8, height: 8 }, top: 8, left: 0, width: "100%" }] }); }, _checkValidation: function (v) { return BI.isNumeric(v) && !(BI.isNull(v) || v < this.min || v > this.max); }, _setBlueTrack: function (percent) { this.blueTrack.element.css({width: percent + "%"}); }, _setLabelPosition: function (percent) { this.label.element.css({left: percent + "%"}); }, _setSliderPosition: function (percent) { this.slider.element.css({left: percent + "%"}); }, _setAllPosition: function (percent) { this._setSliderPosition(percent); this._setLabelPosition(percent); this._setBlueTrack(percent); }, _setVisible: function (visible) { this.slider.setVisible(visible); this.label.setVisible(visible); }, _getGrayTrackLength: function () { return this.grayTrack.element[0].scrollWidth; }, _getValueByPercent: function (percent) { var thousandth = BI.parseInt(percent * 10); return (((this.max - this.min) * thousandth) / 1000 + this.min); }, _getPercentByValue: function (v) { return (v - this.min) * 100 / (this.max - this.min); }, getValue: function () { return this.value; }, setValue: function (v) { var o = this.options; v = BI.parseFloat(v); v = o.digit === false ? v : v.toFixed(o.digit); if ((!isNaN(v))) { if (this._checkValidation(v)) { this.value = v; } if (v > this.max) { this.value = this.max; } if (v < this.min) { this.value = this.min; } } }, setMinAndMax: function (v) { var minNumber = BI.parseFloat(v.min); var maxNumber = BI.parseFloat(v.max); if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber > minNumber )) { this.min = minNumber; this.max = maxNumber; } }, reset: function () { this._setVisible(false); this.enable = false; this.value = ""; this.min = 0; this.max = 0; this._setBlueTrack(0); }, populate: function () { var o = this.options; if (!isNaN(this.min) && !isNaN(this.max)) { this._setVisible(true); this.enable = true; if (BI.isNumeric(this.value) || BI.isNotEmptyString(this.value)) { this.label.setValue(this.value + o.unit); this._setAllPosition(this._getPercentByValue(this.value)); } else { this.label.setValue(this.max + o.unit); this._setAllPosition(100); } } } }); BI.SingleSliderLabel.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_slider_label", BI.SingleSliderLabel);/** * normal single slider * Created by Young on 2017/6/21. */ BI.SingleSliderNormal = BI.inherit(BI.Widget, { _constant: { HEIGHT: 28, SLIDER_WIDTH_HALF: 15, SLIDER_WIDTH: 30, SLIDER_HEIGHT: 30, TRACK_HEIGHT: 24 }, props: { baseCls: "bi-single-slider-normal bi-slider-track", minMax: { min: 0, max: 100 } // color: "#3f8ce8" }, render: function () { var self = this; var c = this._constant; var track = this._createTrack(); this.slider = BI.createWidget({ type: "bi.single_slider_button" }); this._draggable(this.slider); var sliderVertical = BI.createWidget({ type: "bi.vertical", items: [{ type: "bi.absolute", items: [this.slider] }], hgap: c.SLIDER_WIDTH_HALF, height: c.SLIDER_HEIGHT }); sliderVertical.element.click(function (e) { if (self.enable) { var offset = e.clientX - self.element.offset().left - c.SLIDER_WIDTH_HALF; var trackLength = self.track.element[0].scrollWidth; var percent = 0; if (offset < 0) { percent = 0; } if (offset > 0 && offset < (trackLength - c.SLIDER_WIDTH)) { percent = offset * 100 / self._getGrayTrackLength(); } if (offset > (trackLength - c.SLIDER_WIDTH)) { percent = 100; } var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setAllPosition(significantPercent); var v = self._getValueByPercent(significantPercent); self.value = v; self.fireEvent(BI.SingleSlider.EVENT_CHANGE); } }); return { type: "bi.absolute", element: this, items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: track, width: "100%", height: c.TRACK_HEIGHT }] }], hgap: 7, height: c.TRACK_HEIGHT }, top: 3, left: 0, width: "100%" }, { el: sliderVertical, top: 0, left: 0, width: "100%" }] }; }, _draggable: function (widget) { var self = this, o = this.options; var startDrag = false; var size = 0, offset = 0, defaultSize = 0; var mouseMoveTracker = new BI.MouseMoveTracker(function (deltaX) { if (mouseMoveTracker.isDragging()) { startDrag = true; offset += deltaX; size = optimizeSize(defaultSize + offset); widget.element.addClass("dragging"); var percent = size * 100 / (self._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1));// 直接对计算出来的百分数保留到小数点后一位,相当于分成了1000份。 self._setBlueTrack(significantPercent); self._setSliderPosition(significantPercent); var v = self._getValueByPercent(significantPercent); v = o.digit === false ? v : v.toFixed(o.digit); self.value = v; self.fireEvent(BI.SingleSliderNormal.EVENT_DRAG, v); } }, function () { if (startDrag === true) { size = optimizeSize(size); var percent = size * 100 / (self._getGrayTrackLength()); var significantPercent = BI.parseFloat(percent.toFixed(1)); self._setSliderPosition(significantPercent); size = 0; offset = 0; defaultSize = size; startDrag = false; } widget.element.removeClass("dragging"); mouseMoveTracker.releaseMouseMoves(); self.fireEvent(BI.SingleSlider.EVENT_CHANGE); }, document); widget.element.on("mousedown", function (event) { if(!widget.isEnabled()) { return; } defaultSize = this.offsetLeft; optimizeSize(defaultSize); mouseMoveTracker.captureMouseMoves(event); }); function optimizeSize (s) { return BI.clamp(s, 0, self._getGrayTrackLength()); } }, _createTrack: function () { var self = this; var c = this._constant; this.grayTrack = BI.createWidget({ type: "bi.layout", cls: "gray-track", height: 6 }); this.blueTrack = BI.createWidget({ type: "bi.layout", cls: "blue-track bi-high-light-background", height: 6 }); if (this.options.color) { this.blueTrack.element.css({"background-color": this.options.color}); } return { type: "bi.absolute", items: [{ el: { type: "bi.vertical", items: [{ type: "bi.absolute", items: [{ el: this.grayTrack, top: 0, left: 0, width: "100%" }, { el: this.blueTrack, top: 0, left: 0, width: "0%" }] }], hgap: 8, height: 8 }, top: 8, left: 0, width: "100%" }], ref: function (ref) { self.track = ref; } }; }, _checkValidation: function (v) { return !(BI.isNull(v) || v < this.min || v > this.max); }, _setBlueTrack: function (percent) { this.blueTrack.element.css({width: percent + "%"}); }, _setSliderPosition: function (percent) { this.slider.element.css({left: percent + "%"}); }, _setAllPosition: function (percent) { this._setSliderPosition(percent); this._setBlueTrack(percent); }, _setVisible: function (visible) { this.slider.setVisible(visible); }, _getGrayTrackLength: function () { return this.grayTrack.element[0].scrollWidth; }, _getValueByPercent: function (percent) { var thousandth = BI.parseInt(percent * 10); return (((this.max - this.min) * thousandth) / 1000 + this.min); }, _getPercentByValue: function (v) { return (v - this.min) * 100 / (this.max - this.min); }, getValue: function () { return this.value; }, setValue: function (v) { var value = BI.parseFloat(v); if ((!isNaN(value))) { if (this._checkValidation(value)) { this.value = value; } if (value > this.max) { this.value = this.max; } if (value < this.min) { this.value = this.min; } } }, setMinAndMax: function (v) { var minNumber = BI.parseFloat(v.min); var maxNumber = BI.parseFloat(v.max); if ((!isNaN(minNumber)) && (!isNaN(maxNumber)) && (maxNumber > minNumber )) { this.min = minNumber; this.max = maxNumber; } }, reset: function () { this._setVisible(false); this.enable = false; this.value = ""; this.min = 0; this.max = 0; this._setBlueTrack(0); }, populate: function () { if (!isNaN(this.min) && !isNaN(this.max)) { this._setVisible(true); this.enable = true; if (BI.isNumeric(this.value) || BI.isNotEmptyString(this.value)) { this._setAllPosition(this._getPercentByValue(this.value)); } else { this._setAllPosition(100); } } } }); BI.SingleSliderNormal.EVENT_DRAG = "EVENT_DRAG"; BI.shortcut("bi.single_slider_normal", BI.SingleSliderNormal);/** * @class BI.SingleTreeCombo * @extends BI.Widget */ BI.SingleTreeCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SingleTreeCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-tree-combo", trigger: {}, height: 24, text: "", items: [] }); }, _init: function () { BI.SingleTreeCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget(BI.extend({ type: "bi.single_tree_trigger", text: o.text, height: o.height, items: o.items }, o.trigger)); this.popup = BI.createWidget({ type: "bi.single_level_tree", items: o.items }); this.combo = BI.createWidget({ type: "bi.combo", element: this, adjustLength: 2, el: this.trigger, popup: { el: this.popup } }); this.combo.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.SingleTreeCombo.EVENT_BEFORE_POPUPVIEW, arguments); }); this.popup.on(BI.SingleTreePopup.EVENT_CHANGE, function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.SingleTreeCombo.EVENT_CHANGE); }); }, populate: function (items) { this.combo.populate(items); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.trigger.setValue(v); this.popup.setValue(v); }, getValue: function () { return this.popup.getValue(); } }); BI.SingleTreeCombo.EVENT_CHANGE = "SingleTreeCombo.EVENT_CHANGE"; BI.SingleTreeCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.single_tree_combo", BI.SingleTreeCombo);/** * @class BI.SingleTreePopup * @extends BI.Pane */ BI.SingleTreePopup = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.SingleTreePopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-level-tree", tipText: BI.i18nText("BI-No_Selected_Item"), items: [] }); }, _init: function () { BI.SingleTreePopup.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tree = BI.createWidget({ type: "bi.level_tree", expander: { isDefaultInit: true }, items: o.items, chooseType: BI.Selection.Single }); BI.createWidget({ type: "bi.vertical", element: this, items: [this.tree] }); this.tree.on(BI.Controller.EVENT_CHANGE, function () { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.tree.on(BI.LevelTree.EVENT_CHANGE, function () { self.fireEvent(BI.SingleTreePopup.EVENT_CHANGE); }); this.check(); }, getValue: function () { return this.tree.getValue(); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.tree.setValue(v); }, populate: function (items) { BI.SingleTreePopup.superclass.populate.apply(this, arguments); this.tree.populate(items); } }); BI.SingleTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.single_level_tree", BI.SingleTreePopup);/** * @class BI.SingleTreeTrigger * @extends BI.Trigger */ BI.SingleTreeTrigger = BI.inherit(BI.Trigger, { _defaultConfig: function () { return BI.extend(BI.SingleTreeTrigger.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-single-tree-trigger", height: 24, text: "", items: [] }); }, _init: function () { BI.SingleTreeTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options; this.trigger = BI.createWidget({ type: "bi.select_text_trigger", element: this, text: o.text, items: o.items, height: o.height }); }, _checkTitle: function () { var self = this, val = this.getValue(); BI.any(this.options.items, function (i, item) { if (val.contains(item.value)) { self.trigger.setTitle(item.text || item.value); return true; } }); }, setValue: function (v) { v = BI.isArray(v) ? v : [v]; this.options.value = v; this.trigger.setValue(v); this._checkTitle(); }, getValue: function () { return this.options.value || []; }, populate: function (items) { BI.SingleTreeTrigger.superclass.populate.apply(this, arguments); this.trigger.populate(items); } }); BI.shortcut("bi.single_tree_trigger", BI.SingleTreeTrigger);/** * 可以单选多选切换的树 * * Created by GUY on 2015/12/21. * @class BI.SwitchTree * @extends BI.Widget */ BI.SwitchTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.SwitchTree.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-switch-tree", items: [] }); }, _init: function () { BI.SwitchTree.superclass._init.apply(this, arguments); var self = this, o = this.options; this.tab = BI.createWidget({ type: "bi.tab", element: this, tab: null, defaultShowIndex: BI.SwitchTree.SelectType.SingleSelect, cardCreator: BI.bind(this._createTree, this) }); }, _createTree: function (type) { var self = this, o = this.options; switch (type) { case BI.SwitchTree.SelectType.SingleSelect: this.levelTree = BI.createWidget({ type: "bi.multilayer_single_level_tree", isDefaultInit: true, items: BI.deepClone(o.items) }); this.levelTree.on(BI.LevelTree.EVENT_CHANGE, function () { self.fireEvent(BI.SwitchTree.EVENT_CHANGE, arguments); }); return this.levelTree; case BI.SwitchTree.SelectType.MultiSelect: this.tree = BI.createWidget({ type: "bi.simple_tree", items: this._removeIsParent(BI.deepClone(o.items)) }); this.tree.on(BI.SimpleTreeView.EVENT_CHANGE, function () { self.fireEvent(BI.SwitchTree.EVENT_CHANGE, arguments); }); return this.tree; } }, _removeIsParent: function (items) { BI.each(items, function (i, item) { BI.isNotNull(item.isParent) && delete item.isParent; }); return items; }, switchSelect: function () { switch (this.getSelect()) { case BI.SwitchTree.SelectType.SingleSelect: this.setSelect(BI.SwitchTree.SelectType.MultiSelect); break; case BI.SwitchTree.SelectType.MultiSelect: this.setSelect(BI.SwitchTree.SelectType.SingleSelect); break; } }, setSelect: function (v) { this.tab.setSelect(v); }, getSelect: function () { return this.tab.getSelect(); }, setValue: function (v) { this.storeValue = v; switch (this.getSelect()) { case BI.SwitchTree.SelectType.SingleSelect: this.levelTree.setValue(v); break; case BI.SwitchTree.SelectType.MultiSelect: this.tree.setValue(v); break; } }, getValue: function () { return this.tab.getValue(); }, populate: function (items) { this.options.items = items; if (BI.isNotNull(this.levelTree)) { this.levelTree.populate(BI.deepClone(items)); } if (BI.isNotNull(this.tree)) { this.tree.populate(this._removeIsParent(BI.deepClone(items))); } } }); BI.SwitchTree.EVENT_CHANGE = "SwitchTree.EVENT_CHANGE"; BI.SwitchTree.SelectType = { SingleSelect: BI.Selection.Single, MultiSelect: BI.Selection.Multi }; BI.shortcut("bi.switch_tree", BI.SwitchTree); /** * Created by Baron on 2015/10/19. */ BI.TimeInterval = BI.inherit(BI.Single, { constants: { height: 25, width: 25, lgap: 15, offset: -15, timeErrorCls: "time-error", DATE_MIN_VALUE: "1900-01-01", DATE_MAX_VALUE: "2099-12-31" }, _defaultConfig: function () { var conf = BI.TimeInterval.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { extraCls: "bi-time-interval" }); }, _init: function () { var self = this; BI.TimeInterval.superclass._init.apply(this, arguments); this.left = this._createCombo(); this.right = this._createCombo(); this.label = BI.createWidget({ type: "bi.label", height: this.constants.height, width: this.constants.width, text: "-" }); BI.createWidget({ element: self, type: "bi.center", hgap: 15, height: this.constants.height, items: [{ type: "bi.absolute", items: [{ el: self.left, left: this.constants.offset, right: 0, top: 0, bottom: 0 }] }, { type: "bi.absolute", items: [{ el: self.right, left: 0, right: this.constants.offset, top: 0, bottom: 0 }] }] }); BI.createWidget({ type: "bi.horizontal_auto", element: this, items: [ self.label ] }); }, _createCombo: function () { var self = this; var combo = BI.createWidget({ type: "bi.multidate_combo" }); combo.on(BI.MultiDateCombo.EVENT_ERROR, function () { self._clearTitle(); self.element.removeClass(self.constants.timeErrorCls); self.fireEvent(BI.TimeInterval.EVENT_ERROR); }); combo.on(BI.MultiDateCombo.EVENT_VALID, function () { BI.Bubbles.hide("error"); var smallDate = self.left.getKey(), bigDate = self.right.getKey(); if (self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); self.element.addClass(self.constants.timeErrorCls); BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { offsetStyle: "center" }); self.fireEvent(BI.TimeInterval.EVENT_ERROR); } else { self._clearTitle(); self.element.removeClass(self.constants.timeErrorCls); } }); combo.on(BI.MultiDateCombo.EVENT_FOCUS, function () { BI.Bubbles.hide("error"); var smallDate = self.left.getKey(), bigDate = self.right.getKey(); if (self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); self.element.addClass(self.constants.timeErrorCls); BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { offsetStyle: "center" }); self.fireEvent(BI.TimeInterval.EVENT_ERROR); } else { self._clearTitle(); self.element.removeClass(self.constants.timeErrorCls); } }); combo.on(BI.MultiDateCombo.EVENT_BEFORE_POPUPVIEW, function () { self.left.hidePopupView(); self.right.hidePopupView(); }); // combo.on(BI.MultiDateCombo.EVENT_CHANGE, function () { // BI.Bubbles.hide("error"); // var smallDate = self.left.getKey(), bigDate = self.right.getKey(); // if (self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { // self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); // self.element.addClass(self.constants.timeErrorCls); // BI.Bubbles.show("error", BI.i18nText("BI-Time_Interval_Error_Text"), self, { // offsetStyle: "center" // }); // self.fireEvent(BI.TimeInterval.EVENT_ERROR); // } else { // self._clearTitle(); // self.element.removeClass(self.constants.timeErrorCls); // } // }); combo.on(BI.MultiDateCombo.EVENT_CONFIRM, function () { BI.Bubbles.hide("error"); var smallDate = self.left.getKey(), bigDate = self.right.getKey(); if (self._check(smallDate, bigDate) && self._compare(smallDate, bigDate)) { self._setTitle(BI.i18nText("BI-Time_Interval_Error_Text")); self.element.addClass(self.constants.timeErrorCls); self.fireEvent(BI.TimeInterval.EVENT_ERROR); }else{ self._clearTitle(); self.element.removeClass(self.constants.timeErrorCls); self.fireEvent(BI.TimeInterval.EVENT_CHANGE); } }); return combo; }, _dateCheck: function (date) { return Date.parseDateTime(date, "%Y-%x-%d").print("%Y-%x-%d") == date || Date.parseDateTime(date, "%Y-%X-%d").print("%Y-%X-%d") == date || Date.parseDateTime(date, "%Y-%x-%e").print("%Y-%x-%e") == date || Date.parseDateTime(date, "%Y-%X-%e").print("%Y-%X-%e") == date; }, _checkVoid: function (obj) { return !Date.checkVoid(obj.year, obj.month, obj.day, this.constants.DATE_MIN_VALUE, this.constants.DATE_MAX_VALUE)[0]; }, _check: function (smallDate, bigDate) { var smallObj = smallDate.match(/\d+/g), bigObj = bigDate.match(/\d+/g); return this._dateCheck(smallDate) && Date.checkLegal(smallDate) && this._checkVoid({ year: smallObj[0], month: smallObj[1], day: smallObj[2] }) && this._dateCheck(bigDate) && Date.checkLegal(bigDate) && this._checkVoid({ year: bigObj[0], month: bigObj[1], day: bigObj[2] }); }, _compare: function (smallDate, bigDate) { smallDate = Date.parseDateTime(smallDate, "%Y-%X-%d").print("%Y-%X-%d"); bigDate = Date.parseDateTime(bigDate, "%Y-%X-%d").print("%Y-%X-%d"); return BI.isNotNull(smallDate) && BI.isNotNull(bigDate) && smallDate > bigDate; }, _setTitle: function (v) { this.left.setTitle(v); this.right.setTitle(v); this.label.setTitle(v); }, _clearTitle: function () { this.left.setTitle(""); this.right.setTitle(""); this.label.setTitle(""); }, setValue: function (date) { date = date || {}; this.left.setValue(date.start); this.right.setValue(date.end); }, getValue: function () { return {start: this.left.getValue(), end: this.right.getValue()}; } }); BI.TimeInterval.EVENT_VALID = "EVENT_VALID"; BI.TimeInterval.EVENT_ERROR = "EVENT_ERROR"; BI.TimeInterval.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.time_interval", BI.TimeInterval);/** * 年份下拉框 * * Created by GUY on 2015/8/28. * @class BI.YearCombo * @extends BI.Widget */ BI.YearCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.YearCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-year-combo", behaviors: {}, min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 height: 25 }); }, _init: function () { BI.YearCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.storeValue = ""; this.trigger = BI.createWidget({ type: "bi.year_trigger", min: o.min, max: o.max }); this.trigger.on(BI.YearTrigger.EVENT_FOCUS, function () { self.storeValue = this.getKey(); }); this.trigger.on(BI.YearTrigger.EVENT_START, function () { self.combo.isViewVisible() && self.combo.hideView(); }); this.trigger.on(BI.YearTrigger.EVENT_STOP, function () { self.combo.showView(); }); this.trigger.on(BI.YearTrigger.EVENT_ERROR, function () { self.combo.isViewVisible() && self.combo.hideView(); }); this.trigger.on(BI.YearTrigger.EVENT_CONFIRM, function () { if (self.combo.isViewVisible()) { return; } if (this.getKey() && this.getKey() !== self.storeValue) { self.setValue(this.getKey()); } else if (!this.getKey()) { self.setValue(); } self.fireEvent(BI.YearCombo.EVENT_CONFIRM); }); this.combo = BI.createWidget({ type: "bi.combo", element: this, destroyWhenHide: true, isNeedAdjustHeight: false, isNeedAdjustWidth: false, el: this.trigger, popup: { minWidth: 85, stopPropagation: false, el: { type: "bi.year_popup", ref: function () { self.popup = this; }, listeners: [{ eventName: BI.YearPopup.EVENT_CHANGE, action: function () { self.setValue(self.popup.getValue()); self.combo.hideView(); self.fireEvent(BI.YearCombo.EVENT_CONFIRM); } }], behaviors: o.behaviors, min: o.min, max: o.max } } }); this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { var value = self.trigger.getKey(); if (BI.isNotNull(value)) { self.popup.setValue(value); } else if (!value && value !== self.storeValue) { self.popup.setValue(self.storeValue); } else { self.setValue(); } self.fireEvent(BI.YearCombo.EVENT_BEFORE_POPUPVIEW); }); }, setValue: function (v) { this.combo.setValue(v || ""); }, getValue: function () { return this.popup.getValue(); } }); BI.YearCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.YearCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.year_combo", BI.YearCombo);/** * 年份展示面板 * * Created by GUY on 2015/9/2. * @class BI.YearPopup * @extends BI.Trigger */ BI.YearPopup = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.YearPopup.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-year-popup", behaviors: {}, min: "1900-01-01", // 最小日期 max: "2099-12-31" // 最大日期 }); }, _createYearCalendar: function (v) { var o = this.options, y = this._year; var calendar = BI.createWidget({ type: "bi.year_calendar", behaviors: o.behaviors, min: o.min, max: o.max, logic: { dynamic: true }, year: y + v * 12 }); calendar.setValue(this._year); return calendar; }, _init: function () { BI.YearPopup.superclass._init.apply(this, arguments); var self = this; this.selectedYear = this._year = Date.getDate().getFullYear(); var backBtn = BI.createWidget({ type: "bi.icon_button", cls: "pre-page-h-font", width: 25, height: 25, value: -1 }); var preBtn = BI.createWidget({ type: "bi.icon_button", cls: "next-page-h-font", width: 25, height: 25, value: 1 }); this.navigation = BI.createWidget({ type: "bi.navigation", element: this, single: true, logic: { dynamic: true }, tab: { cls: "year-popup-navigation bi-high-light bi-border-top", height: 25, items: [backBtn, preBtn] }, cardCreator: BI.bind(this._createYearCalendar, this), afterCardShow: function () { this.setValue(self.selectedYear); var calendar = this.getSelectedCard(); backBtn.setEnable(!calendar.isFrontYear()); preBtn.setEnable(!calendar.isFinalYear()); } }); this.navigation.on(BI.Navigation.EVENT_CHANGE, function () { self.selectedYear = this.getValue(); self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); self.fireEvent(BI.YearPopup.EVENT_CHANGE, self.selectedYear); }); }, getValue: function () { return this.selectedYear; }, setValue: function (v) { var o = this.options; if (Date.checkVoid(v, 1, 1, o.min, o.max)[0]) { v = Date.getDate().getFullYear(); this.selectedYear = ""; this.navigation.setSelect(BI.YearCalendar.getPageByYear(v)); this.navigation.setValue(""); } else { this.selectedYear = v; this.navigation.setSelect(BI.YearCalendar.getPageByYear(v)); this.navigation.setValue(v); } } }); BI.YearPopup.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.year_popup", BI.YearPopup);/** * 年份trigger * * Created by GUY on 2015/8/21. * @class BI.YearTrigger * @extends BI.Trigger */ BI.YearTrigger = BI.inherit(BI.Trigger, { _const: { hgap: 4, vgap: 2, errorText: BI.i18nText("BI-Please_Input_Positive_Integer"), errorTextInvalid: BI.i18nText("BI-Year_Trigger_Invalid_Text") }, _defaultConfig: function () { return BI.extend(BI.YearTrigger.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-year-trigger bi-border", min: "1900-01-01", // 最小日期 max: "2099-12-31", // 最大日期 height: 24 }); }, _init: function () { BI.YearTrigger.superclass._init.apply(this, arguments); var self = this, o = this.options, c = this._const; this.editor = BI.createWidget({ type: "bi.sign_editor", height: o.height, validationChecker: function (v) { self.editor.setErrorText(!BI.isPositiveInteger(v) ? c.errorText : c.errorTextInvalid); return v === "" || (BI.isPositiveInteger(v) && !Date.checkVoid(v, 1, 1, o.min, o.max)[0]); }, quitChecker: function (v) { return false; }, hgap: c.hgap, vgap: c.vgap, allowBlank: true, errorText: c.errorText }); this.editor.on(BI.SignEditor.EVENT_FOCUS, function () { self.fireEvent(BI.YearTrigger.EVENT_FOCUS); }); this.editor.on(BI.SignEditor.EVENT_STOP, function () { self.fireEvent(BI.YearTrigger.EVENT_STOP); }); this.editor.on(BI.SignEditor.EVENT_CONFIRM, function () { var value = self.editor.getValue(); if (BI.isNotNull(value)) { self.editor.setValue(value); self.editor.setTitle(value); } self.fireEvent(BI.YearTrigger.EVENT_CONFIRM); }); this.editor.on(BI.SignEditor.EVENT_SPACE, function () { if (self.editor.isValid()) { self.editor.blur(); } }); this.editor.on(BI.SignEditor.EVENT_START, function () { self.fireEvent(BI.YearTrigger.EVENT_START); }); this.editor.on(BI.SignEditor.EVENT_ERROR, function () { self.fireEvent(BI.YearTrigger.EVENT_ERROR); }); BI.createWidget({ element: this, type: "bi.htape", items: [ { el: this.editor }, { el: { type: "bi.text_button", baseCls: "bi-trigger-year-text", text: BI.i18nText("BI-Multi_Date_Year"), width: o.height }, width: o.height }, { el: { type: "bi.trigger_icon_button", width: o.height }, width: o.height } ] }); }, setValue: function (v) { this.editor.setState(v); this.editor.setValue(v); this.editor.setTitle(v); }, getKey: function () { return this.editor.getValue() | 0; } }); BI.YearTrigger.EVENT_FOCUS = "EVENT_FOCUS"; BI.YearTrigger.EVENT_ERROR = "EVENT_ERROR"; BI.YearTrigger.EVENT_START = "EVENT_START"; BI.YearTrigger.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.YearTrigger.EVENT_STOP = "EVENT_STOP"; BI.shortcut("bi.year_trigger", BI.YearTrigger);/** * 年份 + 月份下拉框 * * @class BI.YearMonthCombo * @extends BI.Widget */ BI.YearMonthCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.YearMonthCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-year-month-combo", yearBehaviors: {}, monthBehaviors: {}, height: 25 }); }, _init: function () { BI.YearMonthCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.year = BI.createWidget({ type: "bi.year_combo", behaviors: o.yearBehaviors }); this.month = BI.createWidget({ type: "bi.month_combo", behaviors: o.monthBehaviors }); this.year.on(BI.YearCombo.EVENT_CONFIRM, function () { self.fireEvent(BI.YearMonthCombo.EVENT_CONFIRM); }); this.year.on(BI.YearCombo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.YearMonthCombo.EVENT_BEFORE_POPUPVIEW); }); this.month.on(BI.MonthCombo.EVENT_CONFIRM, function () { self.fireEvent(BI.YearMonthCombo.EVENT_CONFIRM); }); this.month.on(BI.MonthCombo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.YearMonthCombo.EVENT_BEFORE_POPUPVIEW); }); BI.createWidget({ type: "bi.center", element: this, hgap: 5, items: [this.year, this.month] }); }, setValue: function (v) { v = v || {}; this.month.setValue(v.month); this.year.setValue(v.year); }, getValue: function () { return { year: this.year.getValue(), month: this.month.getValue() }; } }); BI.YearMonthCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.YearMonthCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.year_month_combo", BI.YearMonthCombo);/** * 年份 + 月份下拉框 * * @class BI.YearQuarterCombo * @extends BI.Widget */ BI.YearQuarterCombo = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.YearQuarterCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-year-quarter-combo", yearBehaviors: {}, quarterBehaviors: {}, height: 25 }); }, _init: function () { BI.YearQuarterCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; this.year = BI.createWidget({ type: "bi.year_combo", behaviors: o.yearBehaviors }); this.quarter = BI.createWidget({ type: "bi.quarter_combo", behaviors: o.quarterBehaviors }); this.year.on(BI.YearCombo.EVENT_CONFIRM, function () { self.fireEvent(BI.YearQuarterCombo.EVENT_CONFIRM); }); this.year.on(BI.YearCombo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.YearQuarterCombo.EVENT_BEFORE_POPUPVIEW); }); this.quarter.on(BI.QuarterCombo.EVENT_CONFIRM, function () { self.fireEvent(BI.YearQuarterCombo.EVENT_CONFIRM); }); this.quarter.on(BI.QuarterCombo.EVENT_BEFORE_POPUPVIEW, function () { self.fireEvent(BI.YearQuarterCombo.EVENT_BEFORE_POPUPVIEW); }); BI.createWidget({ type: "bi.center", element: this, hgap: 5, items: [this.year, this.quarter] }); }, setValue: function (v) { v = v || {}; this.quarter.setValue(v.quarter); this.year.setValue(v.year); }, getValue: function () { return { year: this.year.getValue(), quarter: this.quarter.getValue() }; } }); BI.YearQuarterCombo.EVENT_CONFIRM = "EVENT_CONFIRM"; BI.YearQuarterCombo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.shortcut("bi.year_quarter_combo", BI.YearQuarterCombo);/** * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. * @class BI.AbstractAllValueChooser * @extends BI.Widget */ BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { _const: { perPage: 100 }, _defaultConfig: function () { return BI.extend(BI.AbstractAllValueChooser.superclass._defaultConfig.apply(this, arguments), { width: 200, height: 30, items: null, itemsCreator: BI.emptyFn, cache: true }); }, _valueFormatter: function (v) { var text = v; if (BI.isNotNull(this.items)) { BI.some(this.items, function (i, item) { if (item.value === v) { text = item.text; return true; } }); } return text; }, _itemsCreator: function (options, callback) { var self = this, o = this.options; if (!o.cache || !this.items) { o.itemsCreator({}, function (items) { self.items = items; call(items); }); } else { call(this.items); } function call (items) { var keywords = (options.keywords || []).slice(); if (options.keyword) { keywords.push(options.keyword); } BI.each(keywords, function (i, kw) { var search = BI.Func.getSearchResult(items, kw); items = search.matched.concat(search.finded); }); if (options.selectedValues) {// 过滤 var filter = BI.makeObject(options.selectedValues, true); items = BI.filter(items, function (i, ob) { return !filter[ob.value]; }); } if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { callback({ items: items }); return; } if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { callback({count: items.length}); return; } callback({ items: items, hasNext: false }); } } });/** * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. * @class BI.AllValueChooserCombo * @extends BI.AbstractAllValueChooser */ BI.AllValueChooserCombo = BI.inherit(BI.AbstractAllValueChooser, { _defaultConfig: function () { return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-all-value-chooser-combo", width: 200, height: 30, items: null, itemsCreator: BI.emptyFn, cache: true }); }, _init: function () { BI.AllValueChooserCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; if (BI.isNotNull(o.items)) { this.items = o.items; } this.combo = BI.createWidget({ type: "bi.multi_select_combo", element: this, itemsCreator: BI.bind(this._itemsCreator, this), valueFormatter: BI.bind(this._valueFormatter, this), width: o.width, height: o.height }); this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { self.fireEvent(BI.AllValueChooserCombo.EVENT_CONFIRM); }); }, setValue: function (v) { this.combo.setValue({ type: BI.Selection.Multi, value: v || [] }); }, getValue: function () { var val = this.combo.getValue() || {}; if (val.type === BI.Selection.All) { return val.assist; } return val.value || []; }, populate: function () { this.combo.populate.apply(this, arguments); } }); BI.AllValueChooserCombo.EVENT_CONFIRM = "AllValueChooserCombo.EVENT_CONFIRM"; BI.shortcut("bi.all_value_chooser_combo", BI.AllValueChooserCombo);/** * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. * @class BI.AllValueChooserPane * @extends BI.AbstractAllValueChooser */ BI.AllValueChooserPane = BI.inherit(BI.AbstractAllValueChooser, { _defaultConfig: function () { return BI.extend(BI.AllValueChooserPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-all-value-chooser-pane", width: 200, height: 30, items: null, itemsCreator: BI.emptyFn, cache: true }); }, _init: function () { BI.AllValueChooserPane.superclass._init.apply(this, arguments); var self = this, o = this.options; if (BI.isNotNull(o.items)) { this.items = o.items; } this.list = BI.createWidget({ type: "bi.multi_select_list", element: this, itemsCreator: BI.bind(this._itemsCreator, this), valueFormatter: BI.bind(this._valueFormatter, this), width: o.width, height: o.height }); this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { self.fireEvent(BI.AllValueChooserPane.EVENT_CHANGE); }); }, setValue: function (v) { this.list.setValue({ type: BI.Selection.Multi, value: v || [] }); }, getValue: function () { var val = this.list.getValue() || {}; if (val.type === BI.Selection.All) { return val.assist; } return val.value || []; }, populate: function () { this.list.populate.apply(this.list, arguments); } }); BI.AllValueChooserPane.EVENT_CHANGE = "AllValueChooserPane.EVENT_CHANGE"; BI.shortcut("bi.all_value_chooser_pane", BI.AllValueChooserPane);BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _const: { perPage: 100 }, _defaultConfig: function () { return BI.extend(BI.AbstractTreeValueChooser.superclass._defaultConfig.apply(this, arguments), { items: null, itemsCreator: BI.emptyFn }); }, _initData: function (items) { this.items = items; var nodes = BI.Tree.treeFormat(items); this.tree = new BI.Tree(); this.tree.initTree(nodes); }, _itemsCreator: function (options, callback) { var self = this, o = this.options; if (!this.items) { o.itemsCreator({}, function (items) { self._initData(items); call(); }); } else { call(); } function call () { switch (options.type) { case BI.TreeView.REQ_TYPE_INIT_DATA: self._reqInitTreeNode(options, callback); break; case BI.TreeView.REQ_TYPE_ADJUST_DATA: self._reqAdjustTreeNode(options, callback); break; case BI.TreeView.REQ_TYPE_SELECT_DATA: self._reqSelectedTreeNode(options, callback); break; case BI.TreeView.REQ_TYPE_GET_SELECTED_DATA: self._reqDisplayTreeNode(options, callback); break; default : self._reqTreeNode(options, callback); break; } } }, _reqDisplayTreeNode: function (op, callback) { var self = this; var result = []; var selectedValues = op.selectedValues; if (selectedValues == null || BI.isEmpty(selectedValues)) { callback({}); return; } doCheck([], this.tree.getRoot(), selectedValues); callback({ items: result }); function doCheck (parentValues, node, selected) { if (selected == null || BI.isEmpty(selected)) { BI.each(node.getChildren(), function (i, child) { var newParents = BI.clone(parentValues); newParents.push(child.value); var llen = self._getChildCount(newParents); createOneJson(child, node.id, llen); doCheck(newParents, child, {}); }); return; } BI.each(selected, function (k) { var node = self._getTreeNode(parentValues, k); var newParents = BI.clone(parentValues); newParents.push(node.value); createOneJson(node, node.parent && node.parent.id, getCount(selected[k], newParents)); doCheck(newParents, node, selected[k]); }); } function getCount (jo, parentValues) { if (jo == null) { return 0; } if (BI.isEmpty(jo)) { return self._getChildCount(parentValues); } return BI.size(jo); } function createOneJson (node, pId, llen) { result.push({ id: node.id, pId: pId, text: node.text + (llen > 0 ? ("(" + BI.i18nText("BI-Basic_Altogether") + llen + BI.i18nText("BI-Basic_Count") + ")") : ""), value: node.value, open: true }); } }, _reqSelectedTreeNode: function (op, callback) { var self = this; var selectedValues = BI.deepClone(op.selectedValues); var notSelectedValue = op.notSelectedValue || {}; var keyword = op.keyword || ""; var parentValues = op.parentValues || []; if (selectedValues == null || BI.isEmpty(selectedValues)) { callback({}); return; } dealWithSelectedValues(selectedValues); callback(selectedValues); function dealWithSelectedValues (selectedValues) { var p = parentValues.concat(notSelectedValue); // 存储的值中存在这个值就把它删掉 // 例如选中了中国-江苏-南京, 取消中国或江苏或南京 if (canFindKey(selectedValues, p)) { // 如果搜索的值在父亲链中 if (isSearchValueInParent(p)) { // 例如选中了 中国-江苏, 搜索江苏, 取消江苏 // 例如选中了 中国-江苏, 搜索江苏, 取消中国 self._deleteNode(selectedValues, p); } else { var searched = []; var finded = search(parentValues, notSelectedValue, [], searched); if (finded && BI.isNotEmptyArray(searched)) { BI.each(searched, function (i, arr) { var node = self._getNode(selectedValues, arr); if (node) { // 例如选中了 中国-江苏-南京,搜索南京,取消中国 self._deleteNode(selectedValues, arr); } else { // 例如选中了 中国-江苏,搜索南京,取消中国 expandSelectedValue(selectedValues, arr, BI.last(arr)); } }); } } } // 存储的值中不存在这个值,但父亲节点是全选的情况 // 例如选中了中国-江苏,取消南京 // important 选中了中国-江苏,取消了江苏,但是搜索的是南京 if (isChild(selectedValues, p)) { var result = [], finded = false; // 如果parentValues中有匹配的值,说明搜索结果不在当前值下 if (isSearchValueInParent(p)) { finded = true; } else { // 从当前值开始搜 finded = search(parentValues, notSelectedValue, result); p = parentValues; } if (finded === true) { // 去掉点击的节点之后的结果集 expandSelectedValue(selectedValues, p, notSelectedValue); // 添加去掉搜索的结果集 if (result.length > 0) { BI.each(result, function (i, strs) { self._buildTree(selectedValues, strs); }); } } } } function expandSelectedValue (selectedValues, parents, notSelectedValue) { var next = selectedValues; var childrenCount = []; var path = []; // 去掉点击的节点之后的结果集 BI.some(parents, function (i, v) { var t = next[v]; if (t == null) { if (i === 0) { return true; } if (BI.isEmpty(next)) { var split = parents.slice(0, i); var expanded = self._getChildren(split); path.push(split); childrenCount.push(expanded.length); // 如果只有一个值且取消的就是这个值 if (i === parents.length - 1 && expanded.length === 1 && expanded[0] === notSelectedValue) { for (var j = childrenCount.length - 1; j >= 0; j--) { if (childrenCount[j] === 1) { self._deleteNode(selectedValues, path[j]); } else { break; } } } else { BI.each(expanded, function (m, child) { if (i === parents.length - 1 && child.value === notSelectedValue) { return true; } next[child.value] = {}; }); } next = next[v]; } else { return true; // next = {}; // next[v] = {}; } } else { next = t; } }); } function search (parents, current, result, searched) { var newParents = BI.clone(parents); newParents.push(current); if (self._isMatch(parents, current, keyword)) { searched && searched.push(newParents); return true; } var children = self._getChildren(newParents); var notSearch = []; var can = false; BI.each(children, function (i, child) { if (search(newParents, child.value, result, searched)) { can = true; } else { notSearch.push(child.value); } }); if (can === true) { BI.each(notSearch, function (i, v) { var next = BI.clone(newParents); next.push(v); result.push(next); }); } return can; } function isSearchValueInParent (parentValues) { for (var i = 0, len = parentValues.length; i < len; i++) { if (self._isMatch(parentValues.slice(0, parentValues.length - 1), parentValues[i], keyword)) { return true; } } return false; } function canFindKey (selectedValues, parents) { var t = selectedValues; for (var i = 0; i < parents.length; i++) { var v = parents[i]; t = t[v]; if (t == null) { return false; } } return true; } function isChild (selectedValues, parents) { var t = selectedValues; for (var i = 0; i < parents.length; i++) { var v = parents[i]; if (!BI.has(t, v)) { return false; } t = t[v]; if (BI.isEmpty(t)) { return true; } } return false; } }, _reqAdjustTreeNode: function (op, callback) { var self = this; var result = []; var selectedValues = op.selectedValues; if (selectedValues == null || BI.isEmpty(selectedValues)) { callback({}); return; } BI.each(selectedValues, function (k, v) { result.push([k]); }); dealWithSelectedValues(selectedValues, []); var jo = {}; BI.each(result, function (i, strs) { self._buildTree(jo, strs); }); callback(jo); function dealWithSelectedValues (selected, parents) { if (selected == null || BI.isEmpty(selected)) { return true; } var can = true; BI.each(selected, function (k, v) { var p = BI.clone(parents); p.push(k); if (!dealWithSelectedValues(selected[k], p)) { BI.each(selected[k], function (nk, nv) { var t = BI.clone(p); t.push(nk); result.push(t); }); can = false; } }); return can && isAllSelected(selected, parents); } function isAllSelected (selected, parents) { return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); } }, _reqInitTreeNode: function (op, callback) { var self = this; var result = []; var keyword = op.keyword || ""; var selectedValues = op.selectedValues; var lastSearchValue = op.lastSearchValue || ""; var output = search(); BI.nextTick(function () { callback({ hasNext: output.length > self._const.perPage, items: result, lastSearchValue: BI.last(output) }); }); function search () { var children = self._getChildren([]); var start = children.length; if (lastSearchValue !== "") { for (var j = 0, len = start; j < len; j++) { if (children[j].value === lastSearchValue) { start = j + 1; break; } } } else { start = 0; } var output = []; for (var i = start, len = children.length; i < len; i++) { if (output.length < self._const.perPage) { var find = nodeSearch(1, [], children[i].value, false, result); } else if (output.length === self._const.perPage) { var find = nodeSearch(1, [], children[i].value, false, []); } if (find[0] === true) { output.push(children[i].value); } if (output.length > self._const.perPage) { break; } } return output; } function nodeSearch (deep, parentValues, current, isAllSelect, result) { if (self._isMatch(parentValues, current, keyword)) { var checked = isAllSelect || isSelected(parentValues, current); createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); return [true, checked]; } var newParents = BI.clone(parentValues); newParents.push(current); var children = self._getChildren(newParents); var can = false, checked = false; var isCurAllSelected = isAllSelect || isAllSelected(parentValues, current); BI.each(children, function (i, child) { var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); if (state[1] === true) { checked = true; } if (state[0] === true) { can = true; } }); if (can === true) { checked = isCurAllSelected || (isSelected(parentValues, current) && checked); createOneJson(parentValues, current, true, checked, false, false, result); } return [can, checked]; } function createOneJson (parentValues, value, isOpen, checked, half, flag, result) { var node = self._getTreeNode(parentValues, value); result.push({ id: node.id, pId: node.pId, text: node.text, value: node.value, title: node.title, isParent: node.getChildrenLength() > 0, open: isOpen, checked: checked, halfCheck: half, flag: flag }); } function isHalf (parentValues, value) { var find = findSelectedObj(parentValues); if (find == null) { return null; } return BI.any(find, function (v, ob) { if (v === value) { if (ob != null && !BI.isEmpty(ob)) { return true; } } }); } function isAllSelected (parentValues, value) { var find = findSelectedObj(parentValues); if (find == null) { return null; } return BI.any(find, function (v, ob) { if (v === value) { if (ob != null && BI.isEmpty(ob)) { return true; } } }); } function isSelected (parentValues, value) { var find = findSelectedObj(parentValues); if (find == null) { return false; } return BI.any(find, function (v) { if (v === value) { return true; } }); } function findSelectedObj (parentValues) { var find = selectedValues; if (find == null) { return null; } BI.every(parentValues, function (i, v) { find = find[v]; if (find == null) { return false; } return true; }); return find; } }, _reqTreeNode: function (op, callback) { var self = this; var result = []; var times = op.times; var checkState = op.checkState || {}; var parentValues = op.parentValues || []; var selectedValues = op.selectedValues || {}; var valueMap = {}; // if (judgeState(parentValues, selectedValues, checkState)) { valueMap = dealWidthSelectedValue(parentValues, selectedValues); // } var nodes = this._getChildren(parentValues); for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { var state = getCheckState(nodes[i].value, parentValues, valueMap, checkState); result.push({ id: nodes[i].id, pId: nodes[i].pId, value: nodes[i].value, text: nodes[i].text, times: 1, isParent: nodes[i].getChildrenLength() > 0, checked: state[0], halfCheck: state[1] }); } BI.nextTick(function () { callback({ items: result, hasNext: nodes.length > times * self._const.perPage }); }); function judgeState (parentValues, selected_value, checkState) { var checked = checkState.checked, half = checkState.half; if (parentValues.length > 0 && !checked) { return false; } return (parentValues.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); } function dealWidthSelectedValue (parentValues, selectedValues) { var valueMap = {}; BI.each(parentValues, function (i, v) { selectedValues = selectedValues[v] || {}; }); BI.each(selectedValues, function (value, obj) { if (BI.isNull(obj)) { valueMap[value] = [0, 0]; return; } if (BI.isEmpty(obj)) { valueMap[value] = [2, 0]; return; } var nextNames = {}; BI.each(obj, function (t, o) { if (BI.isNull(o) || BI.isEmpty(o)) { nextNames[t] = true; } }); valueMap[value] = [1, BI.size(nextNames)]; }); return valueMap; } function getCheckState (current, parentValues, valueMap, checkState) { var checked = checkState.checked, half = checkState.half; var tempCheck = false, halfCheck = false; if (BI.has(valueMap, current)) { // 可能是半选 if (valueMap[current][0] === 1) { var values = BI.clone(parentValues); values.push(current); var childCount = self._getChildCount(values); if (childCount > 0 && childCount !== valueMap[current][1]) { halfCheck = true; } } else if (valueMap[current][0] === 2) { tempCheck = true; } } var check; if (!checked && !halfCheck && !tempCheck) { check = BI.has(valueMap, current); } else { check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); } return [check, halfCheck]; } }, _getNode: function (selectedValues, parentValues) { var pNode = selectedValues; for (var i = 0, len = parentValues.length; i < len; i++) { if (pNode == null) { return null; } pNode = pNode[parentValues[i]]; } return pNode; }, _deleteNode: function (selectedValues, values) { var name = values[values.length - 1]; var p = values.slice(0, values.length - 1); var pNode = this._getNode(selectedValues, p); if (pNode != null && pNode[name]) { delete pNode[name]; // 递归删掉空父节点 while (p.length > 0 && BI.isEmpty(pNode)) { name = p[p.length - 1]; p = p.slice(0, p.length - 1); pNode = this._getNode(selectedValues, p); if (pNode != null) { delete pNode[name]; } } } }, _buildTree: function (jo, values) { var t = jo; BI.each(values, function (i, v) { if (!BI.has(t, v)) { t[v] = {}; } t = t[v]; }); }, _isMatch: function (parentValues, value, keyword) { var node = this._getTreeNode(parentValues, value); var finded = BI.Func.getSearchResult([node.text || node.value], keyword); return finded.finded.length > 0 || finded.matched.length > 0; }, _getTreeNode: function (parentValues, v) { var self = this; var findedParentNode; var index = 0; this.tree.traverse(function (node) { if (self.tree.isRoot(node)) { return; } if (index > parentValues.length) { return false; } if (index === parentValues.length && node.value === v) { findedParentNode = node; return false; } if (node.value === parentValues[index]) { index++; return; } return true; }); return findedParentNode; }, _getChildren: function (parentValues) { if (parentValues.length > 0) { var value = BI.last(parentValues); var parent = this._getTreeNode(parentValues.slice(0, parentValues.length - 1), value); } else { var parent = this.tree.getRoot(); } return parent.getChildren(); }, _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; } });/** * 简单的复选下拉树控件, 适用于数据量少的情况 * * Created by GUY on 2015/10/29. * @class BI.TreeValueChooserCombo * @extends BI.Widget */ BI.TreeValueChooserCombo = BI.inherit(BI.AbstractTreeValueChooser, { _defaultConfig: function () { return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-tree-value-chooser-combo", width: 200, height: 30, items: null, itemsCreator: BI.emptyFn }); }, _init: function () { BI.TreeValueChooserCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; if (BI.isNotNull(o.items)) { this._initData(o.items); } this.combo = BI.createWidget({ type: "bi.multi_tree_combo", element: this, itemsCreator: BI.bind(this._itemsCreator, this), width: o.width, height: o.height }); this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { self.fireEvent(BI.TreeValueChooserCombo.EVENT_CONFIRM); }); }, setValue: function (v) { this.combo.setValue(v); }, getValue: function () { return this.combo.getValue(); }, populate: function () { this.combo.populate.apply(this.combo, arguments); } }); BI.TreeValueChooserCombo.EVENT_CONFIRM = "TreeValueChooserCombo.EVENT_CONFIRM"; BI.shortcut("bi.tree_value_chooser_combo", BI.TreeValueChooserCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况 * * Created by GUY on 2015/10/29. * @class BI.TreeValueChooserPane * @extends BI.AbstractTreeValueChooser */ BI.TreeValueChooserPane = BI.inherit(BI.AbstractTreeValueChooser, { _defaultConfig: function () { return BI.extend(BI.TreeValueChooserPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-tree-value-chooser-pane", items: null, itemsCreator: BI.emptyFn }); }, _init: function () { BI.TreeValueChooserPane.superclass._init.apply(this, arguments); var self = this, o = this.options; this.pane = BI.createWidget({ type: "bi.multi_select_tree", element: this, itemsCreator: BI.bind(this._itemsCreator, this) }); this.pane.on(BI.MultiSelectTree.EVENT_CHANGE, function () { self.fireEvent(BI.TreeValueChooserPane.EVENT_CHANGE); }); if (BI.isNotNull(o.items)) { this._initData(o.items); this.populate(); } }, setSelectedValue: function (v) { this.pane.setSelectedValue(v); }, setValue: function (v) { this.pane.setValue(v); }, getValue: function () { return this.pane.getValue(); }, populate: function () { this.pane.populate.apply(this.pane, arguments); } }); BI.TreeValueChooserPane.EVENT_CHANGE = "TreeValueChooserPane.EVENT_CHANGE"; BI.shortcut("bi.tree_value_chooser_pane", BI.TreeValueChooserPane);/** * 简单的复选下拉框控件, 适用于数据量少的情况 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. * @class BI.AbstractValueChooser * @extends BI.Widget */ BI.AbstractValueChooser = BI.inherit(BI.Widget, { _const: { perPage: 100 }, _defaultConfig: function () { return BI.extend(BI.AbstractValueChooser.superclass._defaultConfig.apply(this, arguments), { items: null, itemsCreator: BI.emptyFn, cache: true }); }, _valueFormatter: function (v) { var text = v; if (BI.isNotNull(this.items)) { BI.some(this.items, function (i, item) { if (item.value === v) { text = item.text; return true; } }); } return text; }, _getItemsByTimes: function (items, times) { var res = []; for (var i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { res.push(items[i]); } return res; }, _hasNextByTimes: function (items, times) { return times * this._const.perPage < items.length; }, _itemsCreator: function (options, callback) { var self = this, o = this.options; if (!o.cache || !this.items) { o.itemsCreator({}, function (items) { self.items = items; call(items); }); } else { call(this.items); } function call (items) { var keywords = (options.keywords || []).slice(); if (options.keyword) { keywords.push(options.keyword); } BI.each(keywords, function (i, kw) { var search = BI.Func.getSearchResult(items, kw); items = search.matched.concat(search.finded); }); if (options.selectedValues) {// 过滤 var filter = BI.makeObject(options.selectedValues, true); items = BI.filter(items, function (i, ob) { return !filter[ob.value]; }); } if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { callback({ items: items }); return; } if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { callback({count: items.length}); return; } callback({ items: self._getItemsByTimes(items, options.times), hasNext: self._hasNextByTimes(items, options.times) }); } } });/** * 简单的复选下拉框控件, 适用于数据量少的情况 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. * @class BI.ValueChooserCombo * @extends BI.Widget */ BI.ValueChooserCombo = BI.inherit(BI.AbstractValueChooser, { _defaultConfig: function () { return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-value-chooser-combo", width: 200, height: 30, items: null, itemsCreator: BI.emptyFn, cache: true }); }, _init: function () { BI.ValueChooserCombo.superclass._init.apply(this, arguments); var self = this, o = this.options; if (BI.isNotNull(o.items)) { this.items = o.items; } this.combo = BI.createWidget({ type: "bi.multi_select_combo", element: this, itemsCreator: BI.bind(this._itemsCreator, this), valueFormatter: BI.bind(this._valueFormatter, this), width: o.width, height: o.height }); this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); }); }, setValue: function (v) { this.combo.setValue(v); }, getValue: function () { var val = this.combo.getValue() || {}; return { type: val.type, value: val.value }; }, populate: function () { this.combo.populate.apply(this, arguments); } }); BI.ValueChooserCombo.EVENT_CONFIRM = "ValueChooserCombo.EVENT_CONFIRM"; BI.shortcut("bi.value_chooser_combo", BI.ValueChooserCombo);/** * 简单的复选下拉框控件, 适用于数据量少的情况 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. * @class BI.ValueChooserPane * @extends BI.Widget */ BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { _defaultConfig: function () { return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-value-chooser-pane", items: null, itemsCreator: BI.emptyFn, cache: true }); }, _init: function () { BI.ValueChooserPane.superclass._init.apply(this, arguments); var self = this, o = this.options; this.list = BI.createWidget({ type: "bi.multi_select_list", element: this, itemsCreator: BI.bind(this._itemsCreator, this), valueFormatter: BI.bind(this._valueFormatter, this) }); this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { self.fireEvent(BI.ValueChooserPane.EVENT_CHANGE); }); if (BI.isNotNull(o.items)) { this.items = o.items; this.populate(); } }, setValue: function (v) { this.list.setValue(v); }, getValue: function () { var val = this.list.getValue() || {}; return { type: val.type, value: val.value }; }, populate: function () { this.list.populate.apply(this.list, arguments); } }); BI.ValueChooserPane.EVENT_CHANGE = "ValueChooserPane.EVENT_CHANGE"; BI.shortcut("bi.value_chooser_pane", BI.ValueChooserPane);