3465 lines
118 KiB
JavaScript
3465 lines
118 KiB
JavaScript
/*
|
||
http://www.JSON.org/json2.js
|
||
2011-02-23
|
||
|
||
Public Domain.
|
||
|
||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||
|
||
See http://www.JSON.org/js.html
|
||
|
||
|
||
This code should be minified before deployment.
|
||
See http://javascript.crockford.com/jsmin.html
|
||
|
||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||
NOT CONTROL.
|
||
|
||
|
||
This file creates a global JSON object containing two methods: stringify
|
||
and parse.
|
||
|
||
JSON.stringify(value, replacer, space)
|
||
value any JavaScript value, usually an object or array.
|
||
|
||
replacer an optional parameter that determines how object
|
||
values are stringified for objects. It can be a
|
||
function or an array of strings.
|
||
|
||
space an optional parameter that specifies the indentation
|
||
of nested structures. If it is omitted, the text will
|
||
be packed without extra whitespace. If it is a number,
|
||
it will specify the number of spaces to indent at each
|
||
level. If it is a string (such as '\t' or ' '),
|
||
it contains the characters used to indent at each level.
|
||
|
||
This method produces a JSON text from a JavaScript value.
|
||
|
||
When an object value is found, if the object contains a toJSON
|
||
method, its toJSON method will be called and the result will be
|
||
stringified. A toJSON method does not serialize: it returns the
|
||
value represented by the name/value pair that should be serialized,
|
||
or undefined if nothing should be serialized. The toJSON method
|
||
will be passed the key associated with the value, and this will be
|
||
bound to the value
|
||
|
||
For example, this would serialize Dates as ISO strings.
|
||
|
||
Date.prototype.toJSON = function (key) {
|
||
function f(n) {
|
||
// Format integers to have at least two digits.
|
||
return n < 10 ? '0' + n : n;
|
||
}
|
||
|
||
return this.getUTCFullYear() + '-' +
|
||
f(this.getUTCMonth() + 1) + '-' +
|
||
f(this.getUTCDate()) + 'T' +
|
||
f(this.getUTCHours()) + ':' +
|
||
f(this.getUTCMinutes()) + ':' +
|
||
f(this.getUTCSeconds()) + 'Z';
|
||
};
|
||
|
||
You can provide an optional replacer method. It will be passed the
|
||
key and value of each member, with this bound to the containing
|
||
object. The value that is returned from your method will be
|
||
serialized. If your method returns undefined, then the member will
|
||
be excluded from the serialization.
|
||
|
||
If the replacer parameter is an array of strings, then it will be
|
||
used to select the members to be serialized. It filters the results
|
||
such that only members with keys listed in the replacer array are
|
||
stringified.
|
||
|
||
Values that do not have JSON representations, such as undefined or
|
||
functions, will not be serialized. Such values in objects will be
|
||
dropped; in arrays they will be replaced with null. You can use
|
||
a replacer function to replace those with JSON values.
|
||
JSON.stringify(undefined) returns undefined.
|
||
|
||
The optional space parameter produces a stringification of the
|
||
value that is filled with line breaks and indentation to make it
|
||
easier to read.
|
||
|
||
If the space parameter is a non-empty string, then that string will
|
||
be used for indentation. If the space parameter is a number, then
|
||
the indentation will be that many spaces.
|
||
|
||
Example:
|
||
|
||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||
// text is '["e",{"pluribus":"unum"}]'
|
||
|
||
|
||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||
|
||
text = JSON.stringify([new Date()], function (key, value) {
|
||
return this[key] instanceof Date ?
|
||
'Date(' + this[key] + ')' : value;
|
||
});
|
||
// text is '["Date(---current time---)"]'
|
||
|
||
|
||
JSON.parse(text, reviver)
|
||
This method parses a JSON text to produce an object or array.
|
||
It can throw a SyntaxError exception.
|
||
|
||
The optional reviver parameter is a function that can filter and
|
||
transform the results. It receives each of the keys and values,
|
||
and its return value is used instead of the original value.
|
||
If it returns what it received, then the structure is not modified.
|
||
If it returns undefined then the member is deleted.
|
||
|
||
Example:
|
||
|
||
// Parse the text. Values that look like ISO date strings will
|
||
// be converted to Date objects.
|
||
|
||
myData = JSON.parse(text, function (key, value) {
|
||
var a;
|
||
if (typeof value === 'string') {
|
||
a =
|
||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||
if (a) {
|
||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||
+a[5], +a[6]));
|
||
}
|
||
}
|
||
return value;
|
||
});
|
||
|
||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||
var d;
|
||
if (typeof value === 'string' &&
|
||
value.slice(0, 5) === 'Date(' &&
|
||
value.slice(-1) === ')') {
|
||
d = new Date(value.slice(5, -1));
|
||
if (d) {
|
||
return d;
|
||
}
|
||
}
|
||
return value;
|
||
});
|
||
|
||
|
||
This is a reference implementation. You are free to copy, modify, or
|
||
redistribute.
|
||
*/
|
||
|
||
/*jslint evil: true, strict: false, regexp: false */
|
||
|
||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||
test, toJSON, toString, valueOf
|
||
*/
|
||
|
||
|
||
// Create a JSON object only if one does not already exist. We create the
|
||
// methods in a closure to avoid creating global variables.
|
||
|
||
var JSON;
|
||
if (!JSON) {
|
||
JSON = {};
|
||
}
|
||
|
||
(function () {
|
||
"use strict";
|
||
|
||
function f(n) {
|
||
// Format integers to have at least two digits.
|
||
return n < 10 ? '0' + n : n;
|
||
}
|
||
|
||
if (typeof Date.prototype.toJSON !== 'function') {
|
||
|
||
Date.prototype.toJSON = function (key) {
|
||
|
||
return isFinite(this.valueOf()) ?
|
||
this.getUTCFullYear() + '-' +
|
||
f(this.getUTCMonth() + 1) + '-' +
|
||
f(this.getUTCDate()) + 'T' +
|
||
f(this.getUTCHours()) + ':' +
|
||
f(this.getUTCMinutes()) + ':' +
|
||
f(this.getUTCSeconds()) + 'Z' : null;
|
||
};
|
||
|
||
String.prototype.toJSON =
|
||
Number.prototype.toJSON =
|
||
Boolean.prototype.toJSON = function (key) {
|
||
return this.valueOf();
|
||
};
|
||
}
|
||
|
||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||
gap,
|
||
indent,
|
||
meta = { // table of character substitutions
|
||
'\b': '\\b',
|
||
'\t': '\\t',
|
||
'\n': '\\n',
|
||
'\f': '\\f',
|
||
'\r': '\\r',
|
||
'"' : '\\"',
|
||
'\\': '\\\\'
|
||
},
|
||
rep;
|
||
|
||
|
||
function quote(string) {
|
||
|
||
// If the string contains no control characters, no quote characters, and no
|
||
// backslash characters, then we can safely slap some quotes around it.
|
||
// Otherwise we must also replace the offending characters with safe escape
|
||
// sequences.
|
||
|
||
escapable.lastIndex = 0;
|
||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
|
||
var c = meta[a];
|
||
return typeof c === 'string' ? c :
|
||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||
}) + '"' : '"' + string + '"';
|
||
}
|
||
|
||
|
||
function str(key, holder) {
|
||
|
||
// Produce a string from holder[key].
|
||
|
||
var i, // The loop counter.
|
||
k, // The member key.
|
||
v, // The member value.
|
||
length,
|
||
mind = gap,
|
||
partial,
|
||
value = holder[key];
|
||
|
||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||
|
||
if (value && typeof value === 'object' &&
|
||
typeof value.toJSON === 'function') {
|
||
value = value.toJSON(key);
|
||
}
|
||
|
||
// If we were called with a replacer function, then call the replacer to
|
||
// obtain a replacement value.
|
||
|
||
if (typeof rep === 'function') {
|
||
value = rep.call(holder, key, value);
|
||
}
|
||
|
||
// What happens next depends on the value's type.
|
||
|
||
switch (typeof value) {
|
||
case 'string':
|
||
return quote(value);
|
||
|
||
case 'number':
|
||
|
||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||
|
||
return isFinite(value) ? String(value) : 'null';
|
||
|
||
case 'boolean':
|
||
case 'null':
|
||
|
||
// If the value is a boolean or null, convert it to a string. Note:
|
||
// typeof null does not produce 'null'. The case is included here in
|
||
// the remote chance that this gets fixed someday.
|
||
|
||
return String(value);
|
||
|
||
// If the type is 'object', we might be dealing with an object or an array or
|
||
// null.
|
||
|
||
case 'object':
|
||
|
||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||
// so watch out for that case.
|
||
|
||
if (!value) {
|
||
return 'null';
|
||
}
|
||
|
||
// Make an array to hold the partial results of stringifying this object value.
|
||
|
||
gap += indent;
|
||
partial = [];
|
||
|
||
// Is the value an array?
|
||
|
||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||
|
||
// The value is an array. Stringify every element. Use null as a placeholder
|
||
// for non-JSON values.
|
||
|
||
length = value.length;
|
||
for (i = 0; i < length; i += 1) {
|
||
partial[i] = str(i, value) || 'null';
|
||
}
|
||
|
||
// Join all of the elements together, separated with commas, and wrap them in
|
||
// brackets.
|
||
|
||
v = partial.length === 0 ? '[]' : gap ?
|
||
'[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
|
||
'[' + partial.join(',') + ']';
|
||
gap = mind;
|
||
return v;
|
||
}
|
||
|
||
// If the replacer is an array, use it to select the members to be stringified.
|
||
|
||
if (rep && typeof rep === 'object') {
|
||
length = rep.length;
|
||
for (i = 0; i < length; i += 1) {
|
||
if (typeof rep[i] === 'string') {
|
||
k = rep[i];
|
||
v = str(k, value);
|
||
if (v) {
|
||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
|
||
// Otherwise, iterate through all of the keys in the object.
|
||
|
||
for (k in value) {
|
||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||
v = str(k, value);
|
||
if (v) {
|
||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Join all of the member texts together, separated with commas,
|
||
// and wrap them in braces.
|
||
|
||
v = partial.length === 0 ? '{}' : gap ?
|
||
'{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
|
||
'{' + partial.join(',') + '}';
|
||
gap = mind;
|
||
return v;
|
||
}
|
||
}
|
||
|
||
// If the JSON object does not yet have a stringify method, give it one.
|
||
|
||
if (typeof JSON.stringify !== 'function') {
|
||
JSON.stringify = function (value, replacer, space) {
|
||
|
||
// The stringify method takes a value and an optional replacer, and an optional
|
||
// space parameter, and returns a JSON text. The replacer can be a function
|
||
// that can replace values, or an array of strings that will select the keys.
|
||
// A default replacer method can be provided. Use of the space parameter can
|
||
// produce text that is more easily readable.
|
||
|
||
var i;
|
||
gap = '';
|
||
indent = '';
|
||
|
||
// If the space parameter is a number, make an indent string containing that
|
||
// many spaces.
|
||
|
||
if (typeof space === 'number') {
|
||
for (i = 0; i < space; i += 1) {
|
||
indent += ' ';
|
||
}
|
||
|
||
// If the space parameter is a string, it will be used as the indent string.
|
||
|
||
} else if (typeof space === 'string') {
|
||
indent = space;
|
||
}
|
||
|
||
// If there is a replacer, it must be a function or an array.
|
||
// Otherwise, throw an error.
|
||
|
||
rep = replacer;
|
||
if (replacer && typeof replacer !== 'function' &&
|
||
(typeof replacer !== 'object' ||
|
||
typeof replacer.length !== 'number')) {
|
||
throw new Error('JSON.stringify');
|
||
}
|
||
|
||
// Make a fake root object containing our value under the key of ''.
|
||
// Return the result of stringifying the value.
|
||
|
||
return str('', {'': value});
|
||
};
|
||
}
|
||
|
||
|
||
// If the JSON object does not yet have a parse method, give it one.
|
||
|
||
if (typeof JSON.parse !== 'function') {
|
||
JSON.parse = function (text, reviver) {
|
||
|
||
// The parse method takes a text and an optional reviver function, and returns
|
||
// a JavaScript value if the text is a valid JSON text.
|
||
|
||
var j;
|
||
|
||
function walk(holder, key) {
|
||
|
||
// The walk method is used to recursively walk the resulting structure so
|
||
// that modifications can be made.
|
||
|
||
var k, v, value = holder[key];
|
||
if (value && typeof value === 'object') {
|
||
for (k in value) {
|
||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||
v = walk(value, k);
|
||
if (v !== undefined) {
|
||
value[k] = v;
|
||
} else {
|
||
delete value[k];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return reviver.call(holder, key, value);
|
||
}
|
||
|
||
|
||
// Parsing happens in four stages. In the first stage, we replace certain
|
||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||
|
||
text = String(text);
|
||
cx.lastIndex = 0;
|
||
if (cx.test(text)) {
|
||
text = text.replace(cx, function (a) {
|
||
return '\\u' +
|
||
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||
});
|
||
}
|
||
|
||
// In the second stage, we run the text against regular expressions that look
|
||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||
// because they can cause invocation, and '=' because it can cause mutation.
|
||
// But just to be safe, we want to reject all unexpected forms.
|
||
|
||
// We split the second stage into 4 regexp operations in order to work around
|
||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||
// we look to see that the remaining characters are only whitespace or ']' or
|
||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||
|
||
if (/^[\],:{}\s]*$/
|
||
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
|
||
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
||
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||
|
||
// In the third stage we use the eval function to compile the text into a
|
||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||
// in parens to eliminate the ambiguity.
|
||
|
||
j = eval('(' + text + ')');
|
||
|
||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||
// each name/value pair to a reviver function for possible transformation.
|
||
|
||
return typeof reviver === 'function' ?
|
||
walk({'': j}, '') : j;
|
||
}
|
||
|
||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||
|
||
throw new SyntaxError('JSON.parse');
|
||
};
|
||
}
|
||
}());
|
||
/**
|
||
*
|
||
* Base64 encode / decode
|
||
* http://www.webtoolkit.info/
|
||
*
|
||
**/
|
||
|
||
var Base64 = {
|
||
|
||
// private property
|
||
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||
|
||
// public method for encoding
|
||
encode: function(input) {
|
||
var output = "";
|
||
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
||
var i = 0;
|
||
|
||
input = Base64._utf8_encode(input);
|
||
|
||
while (i < input.length) {
|
||
|
||
chr1 = input.charCodeAt(i++);
|
||
chr2 = input.charCodeAt(i++);
|
||
chr3 = input.charCodeAt(i++);
|
||
|
||
enc1 = chr1 >> 2;
|
||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||
enc4 = chr3 & 63;
|
||
|
||
if (isNaN(chr2)) {
|
||
enc3 = enc4 = 64;
|
||
} else if (isNaN(chr3)) {
|
||
enc4 = 64;
|
||
}
|
||
|
||
output = output +
|
||
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
|
||
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
|
||
|
||
}
|
||
|
||
return output;
|
||
},
|
||
|
||
// public method for decoding
|
||
decode: function(input) {
|
||
var output = "";
|
||
var chr1, chr2, chr3;
|
||
var enc1, enc2, enc3, enc4;
|
||
var i = 0;
|
||
|
||
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
||
|
||
while (i < input.length) {
|
||
|
||
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
||
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
||
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
||
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
||
|
||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||
chr3 = ((enc3 & 3) << 6) | enc4;
|
||
|
||
output = output + String.fromCharCode(chr1);
|
||
|
||
if (enc3 != 64) {
|
||
output = output + String.fromCharCode(chr2);
|
||
}
|
||
if (enc4 != 64) {
|
||
output = output + String.fromCharCode(chr3);
|
||
}
|
||
|
||
}
|
||
|
||
output = Base64._utf8_decode(output);
|
||
|
||
return output;
|
||
|
||
},
|
||
|
||
// private method for UTF-8 encoding
|
||
_utf8_encode: function(string) {
|
||
string = string.replace(/\r\n/g, "\n");
|
||
var utftext = "";
|
||
|
||
for (var n = 0; n < string.length; n++) {
|
||
|
||
var c = string.charCodeAt(n);
|
||
|
||
if (c < 128) {
|
||
utftext += String.fromCharCode(c);
|
||
}
|
||
else if ((c > 127) && (c < 2048)) {
|
||
utftext += String.fromCharCode((c >> 6) | 192);
|
||
utftext += String.fromCharCode((c & 63) | 128);
|
||
}
|
||
else {
|
||
utftext += String.fromCharCode((c >> 12) | 224);
|
||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||
utftext += String.fromCharCode((c & 63) | 128);
|
||
}
|
||
|
||
}
|
||
|
||
return utftext;
|
||
},
|
||
|
||
// private method for UTF-8 decoding
|
||
_utf8_decode: function(utftext) {
|
||
var string = "";
|
||
var i = 0;
|
||
var c = c1 = c2 = 0;
|
||
|
||
while (i < utftext.length) {
|
||
|
||
c = utftext.charCodeAt(i);
|
||
|
||
if (c < 128) {
|
||
string += String.fromCharCode(c);
|
||
i++;
|
||
}
|
||
else if ((c > 191) && (c < 224)) {
|
||
c2 = utftext.charCodeAt(i + 1);
|
||
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
||
i += 2;
|
||
}
|
||
else {
|
||
c2 = utftext.charCodeAt(i + 1);
|
||
c3 = utftext.charCodeAt(i + 2);
|
||
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
||
i += 3;
|
||
}
|
||
|
||
}
|
||
|
||
return string;
|
||
}
|
||
|
||
};
|
||
// FineUI应用程序域
|
||
var X = function (cmpName) {
|
||
return Ext.getCmp(cmpName);
|
||
};
|
||
|
||
X.state = function (cmp, state) {
|
||
X.util.setXState(cmp, state);
|
||
};
|
||
|
||
X.enable = function (id) {
|
||
X.util.enableSubmitControl(id);
|
||
};
|
||
|
||
X.disable = function (id) {
|
||
X.util.disableSubmitControl(id);
|
||
};
|
||
|
||
X.target = function (target) {
|
||
return X.util.getTargetWindow(target);
|
||
};
|
||
|
||
X.alert = function () {
|
||
X.util.alert.apply(window, arguments);
|
||
};
|
||
|
||
X.init = function () {
|
||
if (typeof (onInit) == 'function') {
|
||
onInit();
|
||
}
|
||
};
|
||
|
||
X.ready = function () {
|
||
if (typeof (onReady) == 'function') {
|
||
onReady();
|
||
}
|
||
};
|
||
|
||
X.ajaxReady = function () {
|
||
if (typeof (onAjaxReady) == 'function') {
|
||
onAjaxReady();
|
||
}
|
||
};
|
||
|
||
(function () {
|
||
|
||
|
||
// FineUI常用函数域(Utility)
|
||
X.util = {
|
||
|
||
alertTitle: "Alert Dialog",
|
||
confirmTitle: "Confirm Dialog",
|
||
formAlertMsg: "Please provide valid value for {0}!",
|
||
formAlertTitle: "Form Invalid",
|
||
loading: "Loading...",
|
||
|
||
// 下拉列表的模板
|
||
ddlTPL: '<tpl for="."><div class="x-combo-list-item <tpl if="!enabled">x-combo-list-item-disable</tpl>">{prefix}{text}</div></tpl>',
|
||
|
||
|
||
// 生成加载过程中的时间信息
|
||
/*
|
||
getTimeInfo: function () {
|
||
var str = String.format("Total time:\t\t{0}\r\n", x_render_end_time - x_start_time);
|
||
str += String.format("-Download time:\t\t{0} [ExtJS:{1}]\r\n", x_end_time - x_start_time, x_end_javascript_time - x_start_javascript_time);
|
||
str += String.format("-Wait time:\t\t{0}\r\n", x_render_start_time - x_end_time);
|
||
str += String.format("-Render time:\t\t{0}", x_render_end_time - x_render_start_time);
|
||
return str;
|
||
},
|
||
*/
|
||
|
||
init: function (msgTarget, labelWidth, labelSeparator, enableBigFont,
|
||
blankImageUrl, enableAjaxLoading, ajaxLoadingType, enableAjax) {
|
||
// Ext.QuickTips.init(true); 在原生的IE7(非IE8下的IE7模式)会有问题
|
||
// 表现为iframe中的页面出现滚动条时,页面上的所有按钮都不能点击了。
|
||
// 测试例子在:aspnet/test.aspx
|
||
Ext.QuickTips.init(false);
|
||
|
||
X.ajax.hookPostBack();
|
||
//if (enableAspnetSubmitButtonAjax) {
|
||
// X.util.makeAspnetSubmitButtonAjax();
|
||
//}
|
||
|
||
X.global_enable_ajax = enableAjax;
|
||
|
||
X.global_enable_ajax_loading = enableAjaxLoading;
|
||
X.global_ajax_loading_type = ajaxLoadingType;
|
||
|
||
// 添加Ajax Loading提示节点
|
||
X.ajaxLoadingDefault = Ext.get(X.util.appendLoadingNode());
|
||
X.ajaxLoadingMask = new Ext.LoadMask(Ext.getBody(), { msg: X.util.loading });
|
||
|
||
|
||
X.form_upload_file = false;
|
||
X.global_disable_ajax = false;
|
||
X.window_default_group = new Ext.WindowGroup();
|
||
X.window_default_group.zseed = 6000;
|
||
X.util.setHiddenFieldValue('X_CHANGED', 'false');
|
||
document.forms[0].autocomplete = 'off';
|
||
|
||
if (Ext.form.Field) {
|
||
// Form cofiguration
|
||
var fieldPro = Ext.form.Field.prototype;
|
||
// editorPro = Ext.form.HtmlEditor.prototype;
|
||
fieldPro.msgTarget = msgTarget;
|
||
fieldPro.labelWidth = labelWidth;
|
||
fieldPro.labelSeparator = labelSeparator;
|
||
fieldPro.autoFitErrors = false;
|
||
}
|
||
|
||
if (enableBigFont) {
|
||
Ext.getBody().addClass('bigfont');
|
||
}
|
||
|
||
// Default empty image
|
||
if (Ext.isIE6 || Ext.isIE7) {
|
||
Ext.BLANK_IMAGE_URL = blankImageUrl;
|
||
}
|
||
|
||
// // 页面缩放时改变页面上所有Window控件的容器大小
|
||
// Ext.EventManager.onWindowResize(function(w, h){
|
||
// var viewSize = window.Ext.getBody().getViewSize();
|
||
// Ext.select('.x-window-wrapper').setWidth(viewSize.width).setHeight(viewSize.height);
|
||
// });
|
||
},
|
||
|
||
|
||
setXState: function (cmp, state) {
|
||
if (!cmp || !cmp['x_state']) {
|
||
return;
|
||
}
|
||
|
||
var oldValue, newValue, el;
|
||
// 如果state中包含CssClass,也就是在服务器端修改了CssClass属性,则需要首先删除原来的CssClass属性。
|
||
if (typeof (state['CssClass']) !== 'undefined') {
|
||
newValue = state['CssClass'];
|
||
oldValue = cmp['x_state']['CssClass'];
|
||
if (!oldValue) {
|
||
oldValue = cmp.initialConfig.cls;
|
||
}
|
||
el = cmp.el;
|
||
el.removeClass(oldValue);
|
||
el.addClass(newValue);
|
||
}
|
||
|
||
if (typeof (state['FormItemClass']) !== 'undefined') {
|
||
newValue = state['FormItemClass'];
|
||
oldValue = cmp['x_state']['FormItemClass'];
|
||
if (!oldValue) {
|
||
oldValue = cmp.initialConfig.itemCls;
|
||
}
|
||
// Search for max 10 depth.
|
||
el = cmp.el.findParent('.x-form-item', 10, true);
|
||
el.removeClass(oldValue);
|
||
el.addClass(newValue);
|
||
}
|
||
|
||
Ext.apply(cmp['x_state'], state);
|
||
|
||
},
|
||
|
||
stopEventPropagation: function (event) {
|
||
event = event || window.event;
|
||
if (typeof (event.cancelBubble) === 'boolean') {
|
||
event.cancelBubble = true;
|
||
} else {
|
||
event.stopPropagation();
|
||
}
|
||
},
|
||
|
||
// 绑定函数的上下文
|
||
bind: function (fn, scope) {
|
||
return function () {
|
||
return fn.apply(scope, arguments);
|
||
};
|
||
},
|
||
|
||
// 在页面上查找id为findId的节点,替换成replaceHtml
|
||
replace: function (findId, replaceHtml) {
|
||
// 在findId外面添加一个DIV层,然后更新此wrapper的InnerHTML
|
||
var findedControl = Ext.get(findId);
|
||
if (findedControl) {
|
||
var wrapper = findedControl.wrap().update(replaceHtml);
|
||
// 将新增的节点移到wrapper上面
|
||
wrapper.first().insertBefore(wrapper);
|
||
// 然后删除wrapper
|
||
wrapper.remove();
|
||
}
|
||
},
|
||
|
||
// 去除PageLoading节点
|
||
removePageLoading: function (fadeOut) {
|
||
if (fadeOut) {
|
||
Ext.get("loading").remove();
|
||
Ext.get("loading-mask").fadeOut({ remove: true });
|
||
}
|
||
else {
|
||
Ext.get("loading").remove();
|
||
Ext.get("loading-mask").remove();
|
||
}
|
||
},
|
||
|
||
|
||
// 去掉字符串中的html标签
|
||
stripHtmlTags: function (str) {
|
||
return str.replace(/<[^>]*>/g, "");
|
||
},
|
||
|
||
|
||
// 弹出Alert对话框
|
||
alert: function (msg, title, icon, okscript) {
|
||
title = title || X.util.alertTitle;
|
||
icon = icon || Ext.MessageBox.INFO;
|
||
Ext.MessageBox.show({
|
||
title: title,
|
||
msg: msg,
|
||
buttons: Ext.MessageBox.OK,
|
||
icon: icon,
|
||
fn: function (buttonId) {
|
||
if (buttonId === "ok") {
|
||
if (typeof (okscript) === "function") {
|
||
okscript.call(window);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
// 向页面添加Loading...节点
|
||
appendLoadingNode: function () {
|
||
return X.util.appendFormNode({ tag: "div", cls: "x-ajax-loading", html: X.util.loading });
|
||
},
|
||
|
||
// 向页面的 form 节点最后添加新的节点
|
||
appendFormNode: function (htmlOrObj) {
|
||
return Ext.DomHelper.append(document.forms[0], htmlOrObj);
|
||
},
|
||
|
||
// 向页面添加一个隐藏字段,如果已经存在则更新值
|
||
setHiddenFieldValue: function (fieldId, fieldValue) {
|
||
var itemNode = Ext.get(fieldId);
|
||
if (!itemNode) {
|
||
// Ext.DomHelper.append 有问题,例如下面这个例子得到的结果是错的;变通一下,先插入节点,在设置节点的值。
|
||
// Ext.DomHelper.append(document.forms[0], { tag: "input", type: "hidden", value: '{"X_Items":[["Value1","选项 1",1],["Value2","选项 2(不可选择)",0],["Value3","选项 3(不可选择)",0],["Value4","选项 4",1],["Value5","选项 5",1],["Value6","选项 6",1],["Value7","选项 7",1],["Value8","选项 8",1],["Value9","选项 9",1]],"SelectedValue":"Value1"}'});
|
||
// 上面的这个字符串,在IETest的IE8模式下会变成:
|
||
// {"DropDownList1":{"X_Items":[["Value1","\u9009\u9879 1",1],["Value2","\u9009\u9879 2\uff08\u4e0d\u53ef\u9009\u62e9\uff09",0],["Value3","\u9009\u9879 3\uff08\u4e0d\u53ef\u9009\u62e9\uff09",0],["Value4","\u9009\u9879 4",1],["Value5","\u9009\u9879 5",1],["Value6","\u9009\u9879 6",1],["Value7","\u9009\u9879 7",1],["Value8","\u9009\u9879 8",1],["Value9","\u9009\u9879 9",1]],"SelectedValue":"Value1"}}
|
||
|
||
X.util.appendFormNode({ tag: "input", type: "hidden", id: fieldId, name: fieldId });
|
||
Ext.get(fieldId).dom.value = fieldValue;
|
||
}
|
||
else {
|
||
itemNode.dom.value = fieldValue;
|
||
}
|
||
},
|
||
|
||
// 从表单中删除隐藏字段
|
||
removeHiddenField: function (fieldId) {
|
||
var itemNode = Ext.get(fieldId);
|
||
if (itemNode) {
|
||
itemNode.remove();
|
||
}
|
||
},
|
||
|
||
// 获取页面中一个隐藏字段的值
|
||
getHiddenFieldValue: function (fieldId) {
|
||
var itemNode = Ext.get(fieldId);
|
||
if (itemNode) {
|
||
return itemNode.getValue();
|
||
}
|
||
return null;
|
||
},
|
||
|
||
// 禁用提交按钮(在回发之前禁用以防止重复提交)
|
||
disableSubmitControl: function (controlClientID) {
|
||
X(controlClientID).disable();
|
||
X.util.setHiddenFieldValue('X_TARGET', controlClientID);
|
||
},
|
||
|
||
// 启用提交按钮(在回发之后启用提交按钮)
|
||
enableSubmitControl: function (controlClientID) {
|
||
X(controlClientID).enable();
|
||
X.util.setHiddenFieldValue('X_TARGET', '');
|
||
},
|
||
|
||
// 更新ViewState的值
|
||
updateViewState: function (newValue, startIndex) {
|
||
var oldValue = X.util.getHiddenFieldValue("__VIEWSTATE");
|
||
if (Ext.type(startIndex) == "number") {
|
||
if (startIndex < oldValue.length) {
|
||
oldValue = oldValue.substr(0, startIndex);
|
||
}
|
||
} else {
|
||
// Added on 2011-5-2, this is a horrible mistake.
|
||
oldValue = '';
|
||
}
|
||
X.util.setHiddenFieldValue("__VIEWSTATE", oldValue + newValue);
|
||
},
|
||
|
||
// 更新EventValidation的值
|
||
updateEventValidation: function (newValue) {
|
||
X.util.setHiddenFieldValue("__EVENTVALIDATION", newValue);
|
||
},
|
||
|
||
// 设置页面状态是否改变
|
||
setPageStateChanged: function () {
|
||
var pageState = Ext.get("X_CHANGED");
|
||
if (pageState && pageState.getValue() == "false") {
|
||
pageState.dom.value = "true";
|
||
}
|
||
},
|
||
|
||
// 页面状态是否改变
|
||
isPageStateChanged: function () {
|
||
var pageState = Ext.get("X_CHANGED");
|
||
if (pageState && pageState.getValue() == "true") {
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
|
||
// 验证多个表单,返回数组[是否验证通过,第一个不通过的表单字段]
|
||
validForms: function (forms, targetName, showBox) {
|
||
var target = X.util.getTargetWindow(targetName);
|
||
var valid = true;
|
||
var firstInvalidField = null;
|
||
for (var i = 0; i < forms.length; i++) {
|
||
var result = X(forms[i]).x_isValid();
|
||
if (!result[0]) {
|
||
valid = false;
|
||
if (firstInvalidField == null) {
|
||
firstInvalidField = result[1];
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!valid) {
|
||
if (showBox) {
|
||
var alertMsg = String.format(X.util.formAlertMsg, firstInvalidField.fieldLabel);
|
||
target.X.util.alert(alertMsg, X.util.formAlertTitle, Ext.MessageBox.INFO);
|
||
}
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
|
||
|
||
// 判断隐藏字段值(数组)是否包含value
|
||
isHiddenFieldContains: function (domId, testValue) {
|
||
testValue += "";
|
||
var domValue = Ext.get(domId).dom.value;
|
||
if (domValue === "") {
|
||
//console.log(domId);
|
||
return false;
|
||
}
|
||
else {
|
||
var sourceArray = domValue.split(",");
|
||
return sourceArray.indexOf(testValue) >= 0 ? true : false;
|
||
}
|
||
},
|
||
|
||
|
||
// 将一个字符添加到字符列表中,将2添加到[5,3,4]
|
||
addValueToHiddenField: function (domId, addValue) {
|
||
addValue += "";
|
||
var domValue = Ext.get(domId).dom.value;
|
||
if (domValue == "") {
|
||
Ext.get(domId).dom.value = addValue + "";
|
||
}
|
||
else {
|
||
var sourceArray = domValue.split(",");
|
||
if (sourceArray.indexOf(addValue) < 0) {
|
||
sourceArray.push(addValue);
|
||
Ext.get(domId).dom.value = sourceArray.join(",");
|
||
}
|
||
}
|
||
},
|
||
|
||
|
||
// 从字符列表中移除一个字符,将2从dom的值"5,3,4,2"移除
|
||
removeValueFromHiddenField: function (domId, addValue) {
|
||
addValue += "";
|
||
var domValue = Ext.get(domId).dom.value;
|
||
if (domValue != "") {
|
||
var sourceArray = domValue.split(",");
|
||
if (sourceArray.indexOf(addValue) >= 0) {
|
||
sourceArray = sourceArray.remove(addValue);
|
||
Ext.get(domId).dom.value = sourceArray.join(",");
|
||
}
|
||
}
|
||
},
|
||
|
||
|
||
// 取得隐藏字段的值
|
||
getHiddenFieldValue: function (fieldId) {
|
||
var itemNode = Ext.get(fieldId);
|
||
if (!itemNode) {
|
||
return "";
|
||
}
|
||
else {
|
||
return itemNode.dom.value;
|
||
}
|
||
},
|
||
|
||
|
||
// 取得表单字段的值,日期字段的值类似"2008-07-08"
|
||
getFormFieldValue: function (cmp) {
|
||
if (cmp.getXType() == "datefield") {
|
||
return cmp.value;
|
||
}
|
||
else {
|
||
return cmp.getValue();
|
||
}
|
||
},
|
||
|
||
// 由target获取window对象
|
||
getTargetWindow: function (target) {
|
||
var wnd = null;
|
||
if (target === '_self') {
|
||
wnd = window;
|
||
} else if (target === '_parent') {
|
||
wnd = parent;
|
||
} else if (target === '_top') {
|
||
wnd = top;
|
||
}
|
||
return wnd;
|
||
},
|
||
|
||
|
||
// 预加载图片
|
||
preloadImages: function (images) {
|
||
var imageInstance = [];
|
||
for (var i = 0; i < images.length; i++) {
|
||
imageInstance[i] = new Image();
|
||
imageInstance[i].src = images[i];
|
||
}
|
||
},
|
||
|
||
hasCSS: function (id) {
|
||
return !!Ext.get(id);
|
||
},
|
||
|
||
addCSS: function (id, content) {
|
||
|
||
// 如果此节点已经存在,则先删除此节点
|
||
var node = Ext.get(id);
|
||
if (node) {
|
||
Ext.removeNode(node.dom);
|
||
}
|
||
|
||
// Tricks From: http://www.phpied.com/dynamic-script-and-style-elements-in-ie/
|
||
var ss1 = document.createElement("style");
|
||
ss1.setAttribute("type", "text/css");
|
||
ss1.setAttribute("id", id);
|
||
if (ss1.styleSheet) { // IE
|
||
ss1.styleSheet.cssText = content;
|
||
} else { // the world
|
||
var tt1 = document.createTextNode(content);
|
||
ss1.appendChild(tt1);
|
||
}
|
||
var hh1 = document.getElementsByTagName("head")[0];
|
||
hh1.appendChild(ss1);
|
||
},
|
||
|
||
/*
|
||
// 在启用AJAX的情况下,使所有的Asp.net的提交按钮(type="submit")不要响应默认的submit行为,而是自定义的AJAX
|
||
makeAspnetSubmitButtonAjax: function (buttonId) {
|
||
|
||
// 低版本IE浏览器不允许使用JS修改input标签的type属性,导致此函数无效
|
||
function resetButton(button) {
|
||
button.set({ "type": "button" });
|
||
button.addListener("click", function (event, el) {
|
||
__doPostBack(el.getAttribute("name"), "");
|
||
event.stopEvent();
|
||
});
|
||
}
|
||
|
||
if (typeof (buttonId) === "undefined") {
|
||
Ext.each(Ext.DomQuery.select("input[type=submit]"), function (item, index) {
|
||
resetButton(Ext.get(item));
|
||
});
|
||
} else {
|
||
var button = Ext.get(buttonId);
|
||
if (button.getAttribute("type") === "submit") {
|
||
resetButton(button);
|
||
}
|
||
}
|
||
|
||
},
|
||
|
||
*/
|
||
|
||
// Whether a object is empty (With no property) or not.
|
||
isObjectEmpty: function (obj) {
|
||
for (var prop in obj) {
|
||
if (obj.hasOwnProperty(prop)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
},
|
||
|
||
// Convert an array to object.
|
||
// ['Text', 'Icon'] -> {'Text':true, 'Icon': true}
|
||
arrayToObject: function (arr) {
|
||
var obj = {};
|
||
Ext.each(arr, function (item, index) {
|
||
obj[item] = true;
|
||
});
|
||
return obj;
|
||
},
|
||
|
||
hideScrollbar: function () {
|
||
if (Ext.isIE) {
|
||
window.document.body.scroll = 'no';
|
||
} else {
|
||
window.document.body.style.overflow = 'hidden';
|
||
}
|
||
},
|
||
|
||
|
||
// 动态添加一个标签页
|
||
// addExampleTab(node) or addExampleTab(id, url, text)
|
||
addMainTab: function (mainTabStrip, id, url, text, icon, tbarCallback) {
|
||
var iconId, iconCss, tabId, currentTab, tabConfig;
|
||
if (typeof (id) !== 'string') {
|
||
tbarCallback = url;
|
||
url = id.attributes.href;
|
||
icon = id.attributes.icon;
|
||
text = id.text;
|
||
|
||
id = id.id;
|
||
}
|
||
//var href = node.attributes.href;
|
||
if (icon) {
|
||
iconId = icon.replace(/\W/ig, '_');
|
||
if (!X.util.hasCSS(iconId)) {
|
||
iconCss = [];
|
||
iconCss.push('.');
|
||
iconCss.push(iconId);
|
||
iconCss.push('{background-image:url("');
|
||
iconCss.push(icon);
|
||
iconCss.push('")}');
|
||
X.util.addCSS(iconId, iconCss.join(''));
|
||
}
|
||
}
|
||
// 动态添加一个带工具栏的标签页
|
||
tabId = 'dynamic_added_tab' + id.replace('__', '-');
|
||
currentTab = mainTabStrip.getTab(tabId);
|
||
if (!currentTab) {
|
||
tabConfig = {
|
||
'id': tabId,
|
||
'url': url,
|
||
'title': text,
|
||
'closable': true,
|
||
'bodyStyle': 'padding:0px;'
|
||
};
|
||
if (icon) {
|
||
tabConfig['iconCls'] = iconId;
|
||
}
|
||
if (tbarCallback) {
|
||
tabConfig['tbar'] = tbarCallback.call(window);
|
||
}
|
||
mainTabStrip.addTab(tabConfig);
|
||
} else {
|
||
mainTabStrip.setActiveTab(currentTab);
|
||
}
|
||
},
|
||
|
||
initTreeTabStrip: function (treeMenu, mainTabStrip, tbarCallback, updateLocationHash) {
|
||
|
||
// 注册树的节点点击事件
|
||
function registerTreeClickEvent(treeInstance) {
|
||
treeInstance.on('click', function (node, event) {
|
||
if (node.isLeaf()) {
|
||
// 阻止事件传播
|
||
event.stopEvent();
|
||
|
||
var href = node.attributes.href;
|
||
|
||
if (updateLocationHash) {
|
||
// 修改地址栏
|
||
window.location.hash = '#' + href;
|
||
}
|
||
|
||
// 新增Tab节点
|
||
X.util.addMainTab(mainTabStrip, node, tbarCallback);
|
||
}
|
||
});
|
||
}
|
||
|
||
// treeMenu可能是Accordion或者Tree
|
||
if (treeMenu.getXType() === 'panel') {
|
||
treeMenu.items.each(function (item) {
|
||
var tree = item.items.itemAt(0);
|
||
if (tree && tree.getXType() === 'treepanel') {
|
||
registerTreeClickEvent(tree);
|
||
}
|
||
});
|
||
} else if (treeMenu.getXType() === 'treepanel') {
|
||
registerTreeClickEvent(treeMenu);
|
||
}
|
||
|
||
|
||
if (updateLocationHash) {
|
||
// 切换主窗口的Tab
|
||
mainTabStrip.on('tabchange', function (tabStrip, tab) {
|
||
if (tab.url) {
|
||
//window.location.href = '#' + tab.url;
|
||
window.location.hash = '#' + tab.url;
|
||
} else {
|
||
window.location.hash = '#';
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
// 页面第一次加载时,根据URL地址在主窗口加载页面
|
||
var HASH = window.location.hash.substr(1);
|
||
if (HASH) {
|
||
var FOUND = false;
|
||
|
||
function initTreeMenu(treeInstance, node) {
|
||
var i, currentNode, nodes, node, path;
|
||
if (!FOUND && node.hasChildNodes()) {
|
||
nodes = node.childNodes;
|
||
for (i = 0; i < nodes.length; i++) {
|
||
currentNode = nodes[i];
|
||
if (currentNode.isLeaf()) {
|
||
if (currentNode.attributes.href === HASH) {
|
||
path = currentNode.getPath();
|
||
treeInstance.expandPath(path); //node.expand();
|
||
treeInstance.selectPath(path); // currentNode.select();
|
||
X.util.addMainTab(mainTabStrip, currentNode, tbarCallback);
|
||
FOUND = true;
|
||
return;
|
||
}
|
||
} else {
|
||
arguments.callee(treeInstance, currentNode);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (treeMenu.getXType() === 'panel') {
|
||
treeMenu.items.each(function (item) {
|
||
var tree = item.items.itemAt(0);
|
||
if (tree && tree.getXType() === 'treepanel') {
|
||
initTreeMenu(tree, tree.getRootNode());
|
||
|
||
// 找到树节点
|
||
if (FOUND) {
|
||
item.expand();
|
||
return false;
|
||
}
|
||
}
|
||
});
|
||
} else if (treeMenu.getXType() === 'treepanel') {
|
||
initTreeMenu(treeMenu, treeMenu.getRootNode());
|
||
}
|
||
}
|
||
|
||
},
|
||
|
||
|
||
resolveCheckBoxGroup: function (name, xstateContainer, isradiogroup) {
|
||
var items = [], i, count, xitem, xitemvalue, xitems, xselectedarray, xselected, xchecked, xitemname;
|
||
|
||
xitems = xstateContainer.X_Items;
|
||
xselectedarray = xstateContainer.SelectedValueArray;
|
||
xselected = xstateContainer.SelectedValue;
|
||
|
||
if (xitems && xitems.length > 0) {
|
||
for (i = 0, count = xitems.length; i < count; i++) {
|
||
xitem = xitems[i];
|
||
xitemvalue = xitem[1];
|
||
xchecked = false;
|
||
if (!isradiogroup) {
|
||
// xselectedarray 可能是undefined, [], ["value1", "value2"]
|
||
if (xselectedarray) {
|
||
xchecked = (xselectedarray.indexOf(xitemvalue) >= 0) ? true : false;
|
||
}
|
||
xitemname = name + '_' + i;
|
||
} else {
|
||
xchecked = (xselected === xitemvalue) ? true : false;
|
||
xitemname = name;
|
||
}
|
||
items.push({
|
||
'inputValue': xitemvalue,
|
||
'boxLabel': xitem[0],
|
||
'name': xitemname,
|
||
'checked': xchecked
|
||
});
|
||
}
|
||
} else {
|
||
items.push({
|
||
'inputValue': "tobedeleted",
|
||
'boxLabel': " ",
|
||
'name': "tobedeleted"
|
||
});
|
||
}
|
||
|
||
return items;
|
||
|
||
},
|
||
|
||
checkGroupLastTime: function (groupName) {
|
||
var checkName = groupName + '_lastupdatetime';
|
||
var checkValue = X.util[checkName];
|
||
X.util[checkName] = new Date();
|
||
if (typeof (checkValue) === 'undefined') {
|
||
return true;
|
||
} else {
|
||
if ((new Date() - checkValue) < 100) {
|
||
return false;
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
};
|
||
|
||
|
||
|
||
|
||
})();
|
||
(function () {
|
||
|
||
X.ajax = {
|
||
|
||
errorMsg: "Error! {0} ({1})",
|
||
|
||
hookPostBack: function () {
|
||
if (typeof (__doPostBack) != 'undefined') {
|
||
__doPostBack = x__doPostBack;
|
||
}
|
||
}
|
||
|
||
};
|
||
|
||
function enableAjax() {
|
||
if (typeof (X.control_enable_ajax) === 'undefined') {
|
||
return X.global_enable_ajax;
|
||
}
|
||
return X.control_enable_ajax;
|
||
}
|
||
|
||
function enableAjaxLoading() {
|
||
if (typeof (X.control_enable_ajax_loading) === 'undefined') {
|
||
return X.global_enable_ajax_loading;
|
||
}
|
||
return X.control_enable_ajax_loading;
|
||
}
|
||
|
||
function ajaxLoadingType() {
|
||
if (typeof (X.control_ajax_loading_type) === 'undefined') {
|
||
return X.global_ajax_loading_type;
|
||
}
|
||
return X.control_ajax_loading_type;
|
||
}
|
||
|
||
|
||
function x__doPostBack_internal() {
|
||
if (typeof (X.util.beforeAjaxPostBackScript) === 'function') {
|
||
X.util.beforeAjaxPostBackScript();
|
||
}
|
||
|
||
// Ext.encode will convert Chinese characters. Ext.encode({a:"你好"}) => '{"a":"\u4f60\u597d"}'
|
||
// We will include the official JSON object from http://json.org/
|
||
// 现在还是用的 Ext.encode,在 IETester的 IE8下 JSON.stringify 生成的中文是\u9009\u9879形式。
|
||
//X.util.setHiddenFieldValue('X_STATE', encodeURIComponent(JSON.stringify(getXState())));
|
||
|
||
var xstate = Ext.encode(getXState());
|
||
if (Ext.isIE6 || Ext.isIE7) {
|
||
X.util.setHiddenFieldValue('X_STATE_URI', 'true');
|
||
xstate = encodeURIComponent(xstate);
|
||
} else {
|
||
xstate = Base64.encode(xstate);
|
||
}
|
||
X.util.setHiddenFieldValue('X_STATE', xstate);
|
||
//X.util.setHiddenFieldValue('X_STATE', encodeURIComponent(Ext.encode(getXState())));
|
||
if (!enableAjax()) {
|
||
// 当前请求结束后必须重置 X.control_enable_ajax
|
||
X.control_enable_ajax = undefined;
|
||
X.util.setHiddenFieldValue('X_AJAX', 'false');
|
||
theForm.submit();
|
||
} else {
|
||
// 当前请求结束后必须重置 X.control_enable_ajax
|
||
X.control_enable_ajax = undefined;
|
||
X.util.setHiddenFieldValue('X_AJAX', 'true');
|
||
var url = document.location.href;
|
||
var urlHashIndex = url.indexOf('#');
|
||
if (urlHashIndex >= 0) {
|
||
url = url.substring(0, urlHashIndex);
|
||
}
|
||
Ext.Ajax.request({
|
||
form: theForm.id,
|
||
url: url,
|
||
isUpload: X.form_upload_file,
|
||
//params: serializeForm(theForm) + '&X_AJAX=true',
|
||
success: function (data) {
|
||
// see: http://extjs.com/forum/showthread.php?t=8129
|
||
// 如果页面中有FileUpload,responseObj.responseText会包含于 <pre>标签。
|
||
var scripts = data.responseText;
|
||
if (scripts) {
|
||
// 已经经过encodeURIComponent编码了,在ResponseFilter中的Close函数中
|
||
var prefix = scripts.substr(0, 4);
|
||
if (prefix.toLowerCase() === '<pre') {
|
||
//scripts = scripts.substr(5, scripts.length - 11);
|
||
//scripts = decodeURIComponent(scripts.replace(/<\/?pre>/ig, ''));
|
||
scripts = scripts.replace(/<\/?pre[^>]*>/ig, '');
|
||
scripts = decodeURIComponent(scripts);
|
||
}
|
||
//eval(scripts);
|
||
new Function(scripts)();
|
||
}
|
||
X.ajaxReady();
|
||
},
|
||
failure: function (data) {
|
||
var lastDisabledButtonId = X.util.getHiddenFieldValue('X_TARGET');
|
||
if (lastDisabledButtonId) {
|
||
X.enable(lastDisabledButtonId);
|
||
}
|
||
//X.util.alert(String.format(X.ajax.errorMsg, data.statusText, data.status));
|
||
|
||
if (!X.ajax.errorWindow) {
|
||
initErrorWindow();
|
||
}
|
||
X.ajax.errorWindow.show();
|
||
X.ajax.errorWindow.body.dom.innerHTML = X.wnd.createIFrameHtml('about:blank', 'FINEUI_ERROR');
|
||
X.ajax.errorWindow.setTitle(String.format(X.ajax.errorMsg, data.statusText, data.status));
|
||
writeContentToIFrame(X.ajax.errorWindow.body.query('iframe')[0], data.responseText);
|
||
//writeContentToIFrame(Ext.DomQuery.selectNode('iframe', X.ajax.errorWindow.body), data.responseText);
|
||
},
|
||
callback: function (options, success, response) {
|
||
// AJAX结束时需要清空此字段,否则下一次的type=submit提交(ASP.NET回发方式之一)会被误认为是AJAX提交
|
||
X.util.setHiddenFieldValue('X_AJAX', 'false');
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
// 如果启用 Ajax,则所有对 __doPostBack 的调用都会到这里来
|
||
function x__doPostBack(eventTarget, eventArgument) {
|
||
// 回发页面之前延时 100 毫秒,确保页面上的操作完成(比如选中复选框的动作)
|
||
window.setTimeout(function () {
|
||
// theForm variable will always exist, because we invoke the GetPostBackEventReference in PageManager.
|
||
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
|
||
theForm.__EVENTTARGET.value = eventTarget;
|
||
theForm.__EVENTARGUMENT.value = eventArgument;
|
||
|
||
x__doPostBack_internal();
|
||
}
|
||
}, 100);
|
||
}
|
||
|
||
|
||
function writeContentToIFrame(iframe, content) {
|
||
// http://stackoverflow.com/questions/1477547/getelementbyid-contentdocument-error-in-ie
|
||
// contentWindow is always there.
|
||
if (iframe) {
|
||
var doc = iframe.contentWindow.document;
|
||
// if (iframe.contentDocument) {
|
||
// doc = iframe.contentDocument;
|
||
// } else if (iframe.contentWindow) {
|
||
// doc = iframe.contentWindow.document;
|
||
// }
|
||
if (doc) {
|
||
doc.open();
|
||
doc.write(content);
|
||
doc.close();
|
||
}
|
||
}
|
||
}
|
||
|
||
function initErrorWindow() {
|
||
X.ajax.errorWindow = new Ext.Window({
|
||
id: "FINEUI_ERROR",
|
||
renderTo: window.body,
|
||
width: 550,
|
||
height: 350,
|
||
border: true,
|
||
animCollapse: true,
|
||
collapsible: false,
|
||
collapsed: false,
|
||
closeAction: "hide",
|
||
plain: false,
|
||
modal: true,
|
||
draggable: true,
|
||
minimizable: false,
|
||
minHeight: 100,
|
||
minWidth: 200,
|
||
resizable: false,
|
||
maximizable: false,
|
||
closable: true
|
||
});
|
||
}
|
||
|
||
// Ext.Ajax.serializeForm has a fault. The result will include type="submit" section, which is not always right.
|
||
/*
|
||
function serializeForm(form) {
|
||
var originalStr = Ext.Ajax.serializeForm(form);
|
||
for (var i = 0; i < form.elements.length; i++) {
|
||
el = form.elements[i];
|
||
if (el.type === 'submit') {
|
||
var submitStr = encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
|
||
if (originalStr.indexOf(submitStr) == 0) {
|
||
originalStr = originalStr.replace(submitStr, '');
|
||
} else {
|
||
originalStr = originalStr.replace('&' + submitStr, '');
|
||
}
|
||
}
|
||
}
|
||
return originalStr;
|
||
}
|
||
*/
|
||
|
||
// 序列化表单为 URL 编码字符串,除去 <input type="submit" /> 的按钮
|
||
var extjsSerializeForm = Ext.lib.Ajax.serializeForm;
|
||
Ext.lib.Ajax.serializeForm = function (form) {
|
||
var el, originalStr = extjsSerializeForm(form);
|
||
for (var i = 0; i < form.elements.length; i++) {
|
||
el = form.elements[i];
|
||
if (el.type === 'submit') {
|
||
var submitStr = encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
|
||
if (originalStr.indexOf(submitStr) == 0) {
|
||
originalStr = originalStr.replace(submitStr, '');
|
||
} else {
|
||
originalStr = originalStr.replace('&' + submitStr, '');
|
||
}
|
||
}
|
||
}
|
||
return originalStr;
|
||
};
|
||
|
||
|
||
function getXState() {
|
||
var state = {};
|
||
Ext.ComponentMgr.all.each(function (cmp, index) {
|
||
if (cmp.isXType) {
|
||
// x_props store the properties which has been changed on server-side or client-side.
|
||
// Every FineUI control should has this property.
|
||
var xstate = cmp['x_state'];
|
||
if (xstate && Ext.isObject(xstate)) {
|
||
var cmpState = getXStateViaCmp(cmp, xstate);
|
||
if (!X.util.isObjectEmpty(cmpState)) {
|
||
state[cmp.id] = cmpState;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
return state;
|
||
}
|
||
|
||
X.ajax.getXState = getXState;
|
||
|
||
function getXStateViaCmp(cmp, xstate) {
|
||
var state = {};
|
||
|
||
Ext.apply(state, xstate);
|
||
|
||
function saveInHiddenField(property, currentValue) {
|
||
// Save this client-changed property in a form hidden field.
|
||
X.util.setHiddenFieldValue(cmp.id + '_' + property, currentValue);
|
||
}
|
||
function removeHiddenField(property) {
|
||
X.util.removeHiddenField(cmp.id + '_' + property);
|
||
}
|
||
|
||
|
||
// 有些属性可以在客户端改变,因此需要在每个请求之前计算
|
||
if (cmp.isXType('menucheckitem')) {
|
||
saveInHiddenField('Checked', cmp.checked);
|
||
}
|
||
|
||
if (cmp.isXType('panel')) {
|
||
saveInHiddenField('Collapsed', cmp.collapsed);
|
||
}
|
||
|
||
if (cmp.isXType('datepicker')) {
|
||
saveInHiddenField('SelectedDate', cmp.getValue().format(cmp.initialConfig.format));
|
||
}
|
||
|
||
if (cmp.isXType('button')) {
|
||
if (cmp.initialConfig.enableToggle) {
|
||
saveInHiddenField('Pressed', cmp.pressed);
|
||
}
|
||
}
|
||
|
||
if (cmp.isXType('grid')) {
|
||
if (cmp.isXType('editorgrid')) {
|
||
saveInHiddenField('SelectedCell', cmp.x_getSelectedCell().join(','));
|
||
|
||
if (cmp.x_newAddedRows.length > 0) {
|
||
saveInHiddenField('NewAddedRows', cmp.x_newAddedRows.join(','));
|
||
} else {
|
||
removeHiddenField('NewAddedRows');
|
||
}
|
||
|
||
var gridEditorData = cmp.x_getEditorData();
|
||
if (gridEditorData.length > 0) {
|
||
saveInHiddenField('EditorData', Ext.encode(gridEditorData));
|
||
} else {
|
||
removeHiddenField('EditorData');
|
||
}
|
||
|
||
} else {
|
||
saveInHiddenField('SelectedRowIndexArray', cmp.x_getSelectedRows().join(','));
|
||
}
|
||
|
||
|
||
var gridHiddenColumns = cmp.x_getHiddenColumns();
|
||
if (gridHiddenColumns.length > 0) {
|
||
saveInHiddenField('HiddenColumnIndexArray', gridHiddenColumns.join(','));
|
||
} else {
|
||
removeHiddenField('HiddenColumnIndexArray');
|
||
}
|
||
|
||
|
||
var gridStates = cmp.x_getStates();
|
||
if (gridStates.length > 0) {
|
||
saveInHiddenField('States', Ext.encode(gridStates));
|
||
} else {
|
||
removeHiddenField('States');
|
||
}
|
||
|
||
}
|
||
|
||
if (cmp.isXType('treepanel')) {
|
||
saveInHiddenField('ExpandedNodes', cmp.x_getExpandedNodes(cmp.getRootNode().childNodes).join(','));
|
||
saveInHiddenField('CheckedNodes', cmp.x_getCheckedNodes().join(','));
|
||
saveInHiddenField('SelectedNodeIDArray', cmp.x_getSelectedNodes().join(','));
|
||
}
|
||
|
||
if (cmp.isXType('tabpanel')) {
|
||
saveInHiddenField('ActiveTabIndex', cmp.x_getActiveTabIndex());
|
||
}
|
||
|
||
if (cmp['x_type']) {
|
||
if (cmp['x_type'] === 'tab') {
|
||
saveInHiddenField('Hidden', cmp.tabEl.style.display === 'none');
|
||
}
|
||
}
|
||
|
||
// if (cmp.isXType('combo')) {
|
||
// saveInHiddenField('SelectedValue', cmp.getValue());
|
||
// }
|
||
|
||
return state;
|
||
}
|
||
|
||
|
||
|
||
// 显示“正在载入...”的提示信息
|
||
function _showAjaxLoading(ajaxLoadingType) {
|
||
if (_requestCount > 0) {
|
||
|
||
if (ajaxLoadingType === "default") {
|
||
X.ajaxLoadingDefault.setStyle('left', (Ext.getBody().getWidth() - X.ajaxLoadingDefault.getWidth()) / 2 + 'px');
|
||
X.ajaxLoadingDefault.show();
|
||
} else {
|
||
X.ajaxLoadingMask.show();
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
// 隐藏“正在载入...”的提示信息
|
||
function _hideAjaxLoading(ajaxLoadingType) {
|
||
if (_requestCount <= 0) {
|
||
_requestCount = 0;
|
||
|
||
if (ajaxLoadingType === "default") {
|
||
X.ajaxLoadingDefault.hide();
|
||
} else {
|
||
X.ajaxLoadingMask.hide();
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
// 当前 Ajax 的并发请求数
|
||
var _requestCount = 0;
|
||
|
||
// 发起 Ajax 请求之前事件处理
|
||
Ext.Ajax.on('beforerequest', function (conn, options) {
|
||
_requestCount++;
|
||
|
||
if (!enableAjaxLoading()) {
|
||
// Do nothing
|
||
} else {
|
||
Ext.defer(_showAjaxLoading, 100, window, [ajaxLoadingType()]);
|
||
}
|
||
});
|
||
|
||
// Ajax 请求结束
|
||
Ext.Ajax.on('requestcomplete', function (conn, options) {
|
||
_requestCount--;
|
||
|
||
if (!enableAjaxLoading()) {
|
||
// ...
|
||
} else {
|
||
Ext.defer(_hideAjaxLoading, 80, window, [ajaxLoadingType()]);
|
||
}
|
||
X.control_enable_ajax_loading = undefined;
|
||
X.control_ajax_loading_type = undefined;
|
||
});
|
||
|
||
// Ajax 请求发生异常
|
||
Ext.Ajax.on('requestexception', function (conn, options) {
|
||
_requestCount--;
|
||
|
||
if (!enableAjaxLoading()) {
|
||
// ...
|
||
} else {
|
||
Ext.defer(_hideAjaxLoading, 100);
|
||
}
|
||
X.control_enable_ajax_loading = undefined;
|
||
X.control_ajax_loading_type = undefined;
|
||
});
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// // 不适用于所有Extjs控件(比如Toolbar中放置按钮,这个按钮就没有ownerCt对象)
|
||
// // 更新一个Javascript对象
|
||
// updateObject: function(obj, newObjFunction, renderImmediately) {
|
||
// var id = obj.id;
|
||
// if (Ext.type(renderImmediately) == 'boolean' && !renderImmediately) {
|
||
|
||
// // 1.取得父容器
|
||
// var owner = obj.ownerCt;
|
||
// // 2.本控件在父容器的位置
|
||
// var insertIndex = owner.items.indexOf(obj);
|
||
// // 3.从父容器中销毁此控件
|
||
// owner.remove(obj);
|
||
// // 4.创建新的控件
|
||
// newObjFunction();
|
||
// // 5.将新的控件添加到删除的位置
|
||
// owner.insert(insertIndex, Ext.getCmp(id));
|
||
// // 6.父容器重新布局
|
||
// owner.doLayout();
|
||
|
||
// }
|
||
// else {
|
||
|
||
// // 1.销毁此控件
|
||
// obj.destroy();
|
||
// // 2.新建此控件
|
||
// newObjFunction();
|
||
// }
|
||
// }
|
||
|
||
})();
|
||
|
||
(function () {
|
||
|
||
// 计算黄金分割点的位置
|
||
// bodySize : 整个页面的Body的大小
|
||
// windowSize : 窗口的大小
|
||
function _calculateGoldenPosition(bodySize, windowSize) {
|
||
var top = (bodySize.height - (bodySize.height / 1.618)) - windowSize.height / 2;
|
||
if (top < 0) {
|
||
top = 0;
|
||
}
|
||
var left = (bodySize.width - windowSize.width) / 2;
|
||
if (left < 0) {
|
||
left = 0;
|
||
}
|
||
return { left: left, top: top };
|
||
}
|
||
|
||
// 计算中间的位置
|
||
// bodySize : 整个页面的Body的大小
|
||
// windowSize : 窗口的大小
|
||
function _calculateCenterPosition(bodySize, windowSize) {
|
||
var top = (bodySize.height - windowSize.height) / 2;
|
||
if (top < 0) {
|
||
top = 0;
|
||
}
|
||
var left = (bodySize.width - windowSize.width) / 2;
|
||
if (left < 0) {
|
||
left = 0;
|
||
}
|
||
return { left: left, top: top };
|
||
}
|
||
|
||
|
||
|
||
// 创建IFrame节点片段
|
||
function _createIFrameHtml(iframeUrl, iframeName) {
|
||
return '<iframe frameborder="0" style="overflow:auto;height:100%;width:100%;" name="' + iframeName + '" src="' + iframeUrl + '"></iframe>';
|
||
}
|
||
|
||
// 获取窗体的外部容器
|
||
function _getWrapperNode(panel) {
|
||
return Ext.get(panel.el.findParentNode('.x-window-wrapper'));
|
||
}
|
||
|
||
// FineUI窗口域(Window)
|
||
X.wnd = {
|
||
|
||
closeButtonTooltip: "Close this window",
|
||
formModifiedConfirmTitle: "Close Confrim",
|
||
formModifiedConfirmMsg: "Current form has been modified.<br/><br/>Abandon changes?",
|
||
|
||
createIFrameHtml: function (iframeUrl, iframeName) {
|
||
return _createIFrameHtml(iframeUrl, iframeName);
|
||
},
|
||
|
||
// 显示一个弹出窗体
|
||
// 在 panel 实例中,定义了几个自定义属性,用于标示此实例的状态(在PanelBase中定义)
|
||
// 属性 - x_iframe/x_iframe_url/x_iframe_name/x_iframe_loaded
|
||
// panel : 当前弹出的窗体(Ext-Window)
|
||
// iframeUrl : 弹出窗体中包含的IFrame的地址
|
||
// windowTitle : 弹出窗体的标题
|
||
// left/top : 弹出窗体的左上角坐标(如果为空字符串,则使用中间位置或黄金分隔位置)
|
||
// isGoldenSection : 弹出窗体位于页面的黄金分隔位置
|
||
// hiddenHiddenFieldID : 在页面中放置表单字段记录此窗体是否弹出,也页面回发时保持状态用
|
||
show: function (panel, iframeUrl, windowTitle, left, top, isGoldenSection, hiddenHiddenFieldID) {
|
||
var target = X.util.getTargetWindow(panel['x_property_target']);
|
||
var guid = panel['x_property_guid'];
|
||
if (window.frameElement && target !== window) {
|
||
// 当前页面在IFrame中(也即时 window.frameElement 存在)
|
||
// 此弹出窗体需要在父窗口中弹出
|
||
if (!target.X[guid]) {
|
||
// 父窗口中已经创建了这个Ext-Window对象
|
||
var wrapper = guid + '_wrapper';
|
||
if (!target.Ext.get(wrapper)) {
|
||
target.X.util.appendFormNode('<div class="x-window-wrapper" id="' + wrapper + '"></div>');
|
||
} else {
|
||
target.Ext.get(wrapper).dom.innerHTML = '';
|
||
}
|
||
// Ext.apply 的第三个参数是default obejct
|
||
var config = Ext.apply({}, {
|
||
'renderTo': wrapper,
|
||
'manager': target.X.window_default_group,
|
||
'id': guid,
|
||
//'box_hide': null,
|
||
//'box_hide_refresh': null,
|
||
//'box_hide_postback': null,
|
||
// 'x_show': null,
|
||
// 在 X.wnd.getActiveWindow 中需要用到这个参数
|
||
//'box_property_frame_element_name': window.frameElement.name,
|
||
//'box_property_client_id': panel.getId(),
|
||
'x_property_window': window,
|
||
'x_property_ext_window': panel
|
||
}, panel.initialConfig);
|
||
|
||
// 在父页面中创建一个Ext-Window的幻影(拷贝)
|
||
// 在这个幻影中,通过“x_property_frame_element_name”属性标示这是一个幻影
|
||
// x_property_frame_element_name: 并且真正的Ext-Window在当前页面中的哪个IFrame中
|
||
// x_property_client_id: 并且真正的Ext-Window在所在页面中的客户端ID
|
||
target.X[guid] = new target.Ext.Window(config);
|
||
}
|
||
panel = target.X[guid];
|
||
}
|
||
if (iframeUrl !== '') {
|
||
X.wnd.updateIFrameNode(panel, iframeUrl);
|
||
}
|
||
if (windowTitle != '') {
|
||
panel.setTitle(windowTitle);
|
||
}
|
||
|
||
var bodySize = target.window.Ext.getBody().getViewSize();
|
||
|
||
// // Update container's width and height
|
||
// var wrapperNode = _getWrapperNode(panel);
|
||
// wrapperNode.setWidth(bodySize.width).setHeight(bodySize.height);
|
||
//
|
||
// // 显示窗体之前,记着显示外部的容器
|
||
// wrapperNode.show();
|
||
|
||
Ext.get(hiddenHiddenFieldID).dom.value = 'false';
|
||
panel.show();
|
||
|
||
if (left !== '' && top !== '') {
|
||
panel.setPosition(parseInt(left, 10), parseInt(top, 10));
|
||
} else {
|
||
var panelSize = panel.getSize(), leftTop;
|
||
if (isGoldenSection) {
|
||
leftTop = _calculateGoldenPosition(bodySize, panelSize);
|
||
} else {
|
||
leftTop = _calculateCenterPosition(bodySize, panelSize);
|
||
//panel.alignTo(target.Ext.getBody(), "c-c");
|
||
}
|
||
panel.setPosition(leftTop.left, leftTop.top);
|
||
}
|
||
|
||
if (panel.maximizable) {
|
||
X.wnd.fixMaximize(panel);
|
||
|
||
|
||
// 改变浏览器大小可以自动调整窗体控件的大小(窗体控件最大化时)
|
||
target.Ext.EventManager.onWindowResize(function () {
|
||
X.wnd.fixMaximize(panel);
|
||
});
|
||
|
||
}
|
||
},
|
||
|
||
// 隐藏Ext-Window(比如用户点击了关闭按钮)
|
||
hide: function (panel, targetName, enableIFrame, hiddenHiddenFieldID, guid) {
|
||
var target = X.util.getTargetWindow(targetName);
|
||
// 修改当前页面中记录弹出窗口弹出状态的隐藏表单字段
|
||
Ext.get(hiddenHiddenFieldID).dom.value = 'true';
|
||
if (window.frameElement && target !== window) {
|
||
// 从父页面中查找幻影Ext-Window对象
|
||
panel = target.X[guid];
|
||
}
|
||
// 如果启用IFrame,则清空IFrame的内容,防止下次打开时显示残影
|
||
if (enableIFrame) {
|
||
panel.body.first().dom.src = 'about:blank';
|
||
panel['x_iframe_url'] = 'about:blank';
|
||
}
|
||
panel.hide();
|
||
},
|
||
|
||
// 这是 Extjs 的一个 bug,如果 Window 控件不是渲染在 document.body 中,则 maximize 函数并不能真正的最大化
|
||
// 现在的 Window 控件时渲染在 from 表单里面的一个 DIV 中的
|
||
fixMaximize: function (panel) {
|
||
if (panel.maximized) {
|
||
var target = X.util.getTargetWindow(panel['x_property_target']);
|
||
var bodySize = target.window.Ext.getBody().getViewSize();
|
||
panel.setSize(bodySize.width, bodySize.height);
|
||
// 不要忘记左上角坐标
|
||
panel.setPosition(0, 0);
|
||
}
|
||
},
|
||
|
||
// 创建或更新IFrame节点,同时更新panel实例中的自定义属性值
|
||
updateIFrameNode: function (panel, iframeUrl) {
|
||
var iframeUrlChanged = false;
|
||
// 如果此Panel中包含有IFrame
|
||
if (panel && panel['x_iframe']) {
|
||
if (iframeUrl && panel['x_iframe_url'] !== iframeUrl) {
|
||
panel['x_iframe_url'] = iframeUrl;
|
||
iframeUrlChanged = true;
|
||
}
|
||
// 如果此Panel中包含的IFrame还没有加载
|
||
if (!panel['x_iframe_loaded']) {
|
||
window.setTimeout(function () {
|
||
// 如果此Panel已经创建完毕,但有时Panel可能是延迟创建的(比如TabStrip中的Tab,只有点击这个Tab时才创建Tab的内容)
|
||
if (panel.body) {
|
||
panel['x_iframe_loaded'] = true;
|
||
panel.body.dom.innerHTML = _createIFrameHtml(panel['x_iframe_url'], panel['x_iframe_name']);
|
||
}
|
||
}, 0);
|
||
}
|
||
else {
|
||
if (iframeUrlChanged) {
|
||
panel.body.first().dom.src = panel['x_iframe_url'];
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
|
||
// 处理表单中有任何字段发生变化时,关闭当前窗口时的提示
|
||
confirmFormModified: function (closeFn) {
|
||
if (X.util.isPageStateChanged()) {
|
||
Ext.MessageBox.show({
|
||
title: X.wnd.formModifiedConfirmTitle,
|
||
msg: X.wnd.formModifiedConfirmMsg,
|
||
buttons: Ext.MessageBox.OKCANCEL,
|
||
icon: 'ext-mb-warning',
|
||
fn: function (btn) {
|
||
if (btn == 'cancel') {
|
||
return false;
|
||
} else {
|
||
closeFn.apply(window, arguments);
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
closeFn.apply(window, arguments);
|
||
}
|
||
},
|
||
|
||
|
||
// Ext-Window中IFrame里页面中的表单发生变化时弹出确认消息
|
||
extWindowIFrameFormModifiedConfirm: function (panel, closeFn) {
|
||
// 这个页面所在的Window对象
|
||
var pageWindow = X.wnd.getIFrameWindowObject(panel);
|
||
// 如果弹出的页面没能正常加载(比如说网络暂时连接中断)
|
||
// 则直接关闭弹出的Ext-Window,而不会去检查页面表单变化,因为页面对象不存在
|
||
if (pageWindow.X) {
|
||
pageWindow.X.wnd.confirmFormModified(closeFn);
|
||
}
|
||
else {
|
||
panel.x_hide();
|
||
}
|
||
},
|
||
|
||
// 取得panel的Iframe节点的window对象(可以是幻影Ext-Window中的页面window对象)
|
||
getIFrameWindowObject: function (panel) {
|
||
// 当前页面在IFrame中(也即时 window.frameElement 存在)
|
||
// 此Ext-Window需要在父窗口中弹出
|
||
if (window.frameElement && panel['x_property_show_in_parent']) {
|
||
panel = parent.X[panel['x_property_guid']];
|
||
}
|
||
var iframeNode = Ext.query('iframe', panel.body.dom);
|
||
if (iframeNode.length === 0) {
|
||
// 当前panel(Ext-Window)不包含iframe
|
||
return window;
|
||
}
|
||
else {
|
||
return iframeNode[0].contentWindow;
|
||
}
|
||
},
|
||
|
||
|
||
// 这是老方法,虽然也能正常工作,但是绕了一个弯 => 在幻影ExtWindow中提交当前IFrame的parent.window以及iframe name。
|
||
// 其实没必要,直接在幻影ExtWindow中提交真实的ExtWindow对象即可(只不过这个对象可能是在其他页面中)。
|
||
// 取得当前页面所在的Ext-Window实际的对象,返回[实际的Ext-Window对象,实际的Ext-Window对象所在的window对象]
|
||
// 注意
|
||
// 1. 如果是在当前页面弹出窗口的话,“实际的Ext-Window对象”存在于父页面(parent.box)中
|
||
// 2. 如果是在父页面弹出窗口的话,“实际的Ext-Window对象”存在于父页面(parent)下面的IFrame页面中
|
||
// 3. 通过判断当前的Ext-Window是否存在“box_property_frame_element_name”属性,可知当前的Ext-Window是否幻影(即时实际Ext-Window对象在父页面的一个拷贝),在X.wnd.show中设置的属性
|
||
/*
|
||
getActiveWindow: function () {
|
||
var activeWindow = parent.window;
|
||
var activeExtWindow = parent.X.window_default_group.getActive();
|
||
if (activeExtWindow['box_property_frame_element_name']) {
|
||
var iframeParentWindow = activeExtWindow['box_property_parent_window'];
|
||
activeWindow = iframeParentWindow.Ext.query('iframe[name=' + activeExtWindow['box_property_frame_element_name'] + ']')[0].contentWindow;
|
||
activeExtWindow = activeWindow.Ext.getCmp(activeExtWindow['box_property_client_id']);
|
||
}
|
||
|
||
return [activeExtWindow, activeWindow];
|
||
},
|
||
*/
|
||
|
||
getActiveWindow: function () {
|
||
var activeWindow = parent.window;
|
||
var activeExtWindow = parent.X.window_default_group.getActive();
|
||
if (activeExtWindow['x_property_window']) {
|
||
activeWindow = activeExtWindow['x_property_window'];
|
||
activeExtWindow = activeExtWindow['x_property_ext_window'];
|
||
}
|
||
|
||
return [activeExtWindow, activeWindow];
|
||
},
|
||
|
||
|
||
// // 从url中提取box_parent_client_id参数的值
|
||
// window.box_getParentClientIdFromUrl = function() {
|
||
// var result = '';
|
||
// var url = window.location.href;
|
||
// var startIndex = url.indexOf('box_parent_client_id');
|
||
// if (startIndex >= 0) {
|
||
// result = url.substr(startIndex + 'box_parent_client_id'.length + 1);
|
||
// }
|
||
|
||
// return result;
|
||
// };
|
||
|
||
// // 取得当前页面所在窗口,返回数组[当前窗口对象,当前窗口所在的window对象]
|
||
// window.box_getActiveWindow = function() {
|
||
// var aw = null;
|
||
// var window2 = null;
|
||
|
||
// var parentClientID = box_getParentClientIdFromUrl();
|
||
// if (parentClientID) {
|
||
// window2 = parent.window;
|
||
// aw = parent.window.Ext.getCmp(parentClientID);
|
||
// if (aw.box_property_frame_element_name) {
|
||
// window2 = parent.Ext.query('iframe[name=' + aw.box_property_frame_element_name + ']')[0].contentWindow;
|
||
// aw = eval('window2.X.' + aw.id);
|
||
// }
|
||
// }
|
||
|
||
// if (aw) {
|
||
// return [aw, window2];
|
||
// }
|
||
// else {
|
||
// return null;
|
||
// }
|
||
// };
|
||
|
||
// 向弹出此Ext-Window的页面写入值
|
||
writeBackValue: function () {
|
||
var aw = X.wnd.getActiveWindow();
|
||
var controlIds = aw[0]['x_property_save_state_control_client_ids'];
|
||
var controlCount = Math.min(controlIds.length, arguments.length);
|
||
for (var i = 0; i < controlCount; i++) {
|
||
aw[1].Ext.getCmp(controlIds[i]).setValue(arguments[i]);
|
||
}
|
||
// var controlClientIds = (function() {
|
||
// if (aw) {
|
||
// return eval('aw[1].X.' + aw[0].id + '.box_string_state');
|
||
// }
|
||
// })();
|
||
// if (typeof (controlClientIds) == 'string') {
|
||
// aw[1].Ext.getCmp(controlClientIds).setValue("哈哈");
|
||
// } else {
|
||
// aw[1].Ext.getCmp(controlClientIds[0]).setValue("哈哈");
|
||
// var controlValues = ['哈哈 的值', '哈哈 的值2'];
|
||
// var controlCount = Math.min(controlClientIds.length - 1, controlValues.length);
|
||
// for (var i = 0; i < controlCount; i++) {
|
||
// aw[1].Ext.getCmp(controlClientIds[i + 1]).setValue(controlValues[i]);
|
||
// }
|
||
// }
|
||
// var aw = X.wnd.getActiveWindow();
|
||
// if (aw) {
|
||
// aw[0].box_hide();
|
||
// }
|
||
}
|
||
|
||
};
|
||
|
||
})();
|
||
|
||
Ext.override(Ext.Component, {
|
||
|
||
x_setDisabled: function () {
|
||
this.setDisabled(!this.x_state['Enabled']);
|
||
},
|
||
|
||
x_setVisible: function () {
|
||
this.setVisible(!this.x_state['Hidden']);
|
||
}
|
||
|
||
});
|
||
|
||
// 验证一个表单是否有效,会递归查询表单中每个字段
|
||
// 如果表单隐藏或者字段隐藏,则不进行有效性校验
|
||
Ext.override(Ext.Panel, {
|
||
x_isValid: function () {
|
||
var valid = true;
|
||
var firstInvalidField = null;
|
||
if (!this.hidden) {
|
||
this.items.each(function (f) {
|
||
if (!f.hidden) {
|
||
if (f.isXType('field')) {
|
||
if (!f.validate()) {
|
||
valid = false;
|
||
if (firstInvalidField == null) {
|
||
firstInvalidField = f;
|
||
}
|
||
}
|
||
} else if (f.items) {
|
||
var validResult = f.x_isValid();
|
||
if (!validResult[0]) {
|
||
valid = false;
|
||
if (firstInvalidField == null) {
|
||
firstInvalidField = validResult[1];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
return [valid, firstInvalidField];
|
||
},
|
||
|
||
x_reset: function () {
|
||
this.items.each(function (f) {
|
||
if (f.isXType('field')) {
|
||
f.reset();
|
||
} else if (f.items) {
|
||
validResult = this.x_reset();
|
||
}
|
||
});
|
||
},
|
||
|
||
|
||
x_setCollapse: function () {
|
||
var collapsed = this.x_state['Collapsed'];
|
||
if (collapsed) {
|
||
this.collapse(true);
|
||
}
|
||
else {
|
||
this.expand(true);
|
||
}
|
||
},
|
||
|
||
x_setTitle: function () {
|
||
this.setTitle(this.x_state['Title']);
|
||
}
|
||
|
||
|
||
});
|
||
|
||
/*
|
||
Ext.override(Ext.form.field.HtmlEditor, {
|
||
|
||
// Add functionality to Field's initComponent to enable the change event to bubble
|
||
initComponent: Ext.Function.createSequence(Ext.form.field.Base.prototype.initComponent, function () {
|
||
this.enableBubble('change');
|
||
}),
|
||
|
||
x_setValue: function () {
|
||
this.setValue(this.x_state['Text']);
|
||
}
|
||
|
||
});
|
||
*/
|
||
|
||
if (Ext.form.Field) {
|
||
Ext.override(Ext.form.Field, {
|
||
|
||
// Add functionality to Field's initComponent to enable the change event to bubble
|
||
initComponent: Ext.form.Field.prototype.initComponent.createSequence(function () {
|
||
this.enableBubble('change');
|
||
}),
|
||
|
||
/* 这会导致在文本输入框中按回车键,无法触发type=submit的表单回发事件
|
||
listeners: {
|
||
specialkey: function (field, e) {
|
||
if (e.getKey() == e.ENTER) {
|
||
e.stopEvent();
|
||
}
|
||
}
|
||
},
|
||
*/
|
||
|
||
/*
|
||
// When show or hide the field, also hide the label.
|
||
hide: function () {
|
||
Ext.form.Field.superclass.hide.call(this);
|
||
//this.callOverridden();
|
||
|
||
//var label = Ext.get(this.el.findParent('div[class=x-form-item]')).first('label[for=' + this.id + ']');
|
||
var labelAndField = this.el.findParentNode('div[class*=x-form-item]', 10, true);
|
||
if (labelAndField) {
|
||
if (this.hideMode == 'display') {
|
||
labelAndField.setVisibilityMode(Ext.Element.DISPLAY);
|
||
} else {
|
||
labelAndField.setVisibilityMode(Ext.Element.VISIBILITY);
|
||
}
|
||
labelAndField.hide();
|
||
}
|
||
},
|
||
|
||
show: function () {
|
||
Ext.form.Field.superclass.show.call(this);
|
||
//this.callOverridden();
|
||
|
||
//var label = Ext.get(this.el.findParent('div[class=x-form-item]')).first('label[for=' + this.id + ']');
|
||
var labelAndField = this.el.findParentNode('div[class*=x-form-item]', 10, true);
|
||
if (labelAndField) {
|
||
if (this.hideMode == 'display') {
|
||
labelAndField.setVisibilityMode(Ext.Element.DISPLAY);
|
||
} else {
|
||
labelAndField.setVisibilityMode(Ext.Element.VISIBILITY);
|
||
}
|
||
labelAndField.show();
|
||
}
|
||
},
|
||
*/
|
||
|
||
x_setValue: function () {
|
||
this.setValue(this.x_state['Text']);
|
||
},
|
||
|
||
x_setLabel: function (text) {
|
||
if (this.label && this.label.update) {
|
||
this.label.update(text || this.x_state['Label']);
|
||
}
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
if (Ext.menu.CheckItem) {
|
||
Ext.override(Ext.menu.CheckItem, {
|
||
|
||
x_setChecked: function () {
|
||
this.setChecked(this.x_state['Checked'], true);
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
if (Ext.form.Checkbox) {
|
||
Ext.override(Ext.form.Checkbox, {
|
||
|
||
x_setValue: function () {
|
||
this.setValue(this.x_state['Checked']);
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
if (Ext.form.Radio) {
|
||
Ext.override(Ext.form.Radio, {
|
||
|
||
x_setValue: function () {
|
||
this.setValue(this.x_state['Checked']);
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.form.RadioGroup) {
|
||
Ext.override(Ext.form.RadioGroup, {
|
||
|
||
// 单选框列表的getValue函数,ExtJS没有实现
|
||
// Extjs3.4已经有相应的实现了
|
||
/*
|
||
getValue: function () {
|
||
var value = null;
|
||
Ext.each(this.items.items, function (item, index) {
|
||
if (item.checked) {
|
||
value = item.inputValue;
|
||
}
|
||
});
|
||
return value;
|
||
}
|
||
*/
|
||
|
||
x_setValue: function (value) {
|
||
if (typeof (value) === 'undefined') {
|
||
value = this.x_state['SelectedValue'];
|
||
}
|
||
this.setValue(value);
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.form.CheckboxGroup) {
|
||
Ext.override(Ext.form.CheckboxGroup, {
|
||
|
||
x_reloadData: function (name, isradiogroup) {
|
||
var container = this.ownerCt;
|
||
var newConfig = Ext.apply(this.initialConfig, {
|
||
"x_state": this.x_state,
|
||
"items": X.util.resolveCheckBoxGroup(name, this.x_state, isradiogroup)
|
||
});
|
||
|
||
if (container) {
|
||
var originalIndex = container.items.indexOf(this);
|
||
container.remove(this, true);
|
||
|
||
if (isradiogroup) {
|
||
container.insert(originalIndex, new Ext.form.RadioGroup(newConfig));
|
||
} else {
|
||
container.insert(originalIndex, new Ext.form.CheckboxGroup(newConfig));
|
||
}
|
||
container.doLayout();
|
||
} else {
|
||
this.destroy();
|
||
if (isradiogroup) {
|
||
new Ext.form.RadioGroup(newConfig);
|
||
} else {
|
||
new Ext.form.CheckboxGroup(newConfig);
|
||
}
|
||
|
||
}
|
||
},
|
||
|
||
x_toBeDeleted: function () {
|
||
var tobedeleted = this.items.items[0];
|
||
if (tobedeleted && tobedeleted.inputValue === 'tobedeleted') {
|
||
tobedeleted.destroy();
|
||
this.items.remove(tobedeleted);
|
||
}
|
||
},
|
||
|
||
x_setValue: function (value) {
|
||
var valueArray = value || this.x_state['SelectedValueArray'];
|
||
// 此时value的值类似于:["value1", "value2", "value3"]
|
||
|
||
var selectedArray = [];
|
||
this.eachItem(function (item) {
|
||
if (valueArray.indexOf(item.getRawValue()) === -1) {
|
||
selectedArray.push(false);
|
||
} else {
|
||
selectedArray.push(true);
|
||
}
|
||
});
|
||
|
||
this.setValue(selectedArray);
|
||
|
||
/*
|
||
var result = {}, i, currentSelectedCheckboxs;
|
||
currentSelectedCheckboxs = this.getValue();
|
||
for (i = 0; i < currentSelectedCheckboxs.length; i++) {
|
||
result[currentSelectedCheckboxs[i].getRawValue()] = false;
|
||
}
|
||
|
||
for (i = 0; i < valueArray.length; i++) {
|
||
result[valueArray[i]] = true;
|
||
}
|
||
this.setValue(result);
|
||
*/
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
if (Ext.form.ComboBox) {
|
||
Ext.override(Ext.form.ComboBox, {
|
||
// Load data from local cache.
|
||
// mode: "local",
|
||
// triggerAction: "all",
|
||
displayField: "text",
|
||
valueField: "value",
|
||
//tpl: "<tpl for=\".\"><div class=\"x-combo-list-item <tpl if=\"!enabled\">x-combo-list-item-disable</tpl>\">{prefix}{text}</div></tpl>",
|
||
|
||
// These variables are in the Ext.form.ComboBox.prototype, therefore all instance will refer to the same store instance.
|
||
//store: new Ext.data.ArrayStore({ fields: ['value', 'text', 'enabled', 'prefix'] }),
|
||
|
||
x_setValue: function (value) {
|
||
// value 可以是空字符串
|
||
if (typeof (value) === 'undefined') {
|
||
value = this.x_state['SelectedValue'];
|
||
}
|
||
this.setValue(value);
|
||
},
|
||
|
||
x_loadData: function (data) {
|
||
data = data || this.x_state['X_Items'];
|
||
if (data) {
|
||
this.store.loadData(X.simulateTree.transform(data));
|
||
}
|
||
},
|
||
|
||
|
||
x_getTextByValue: function (value, data) {
|
||
data = data || this.x_state['X_Items'];
|
||
value += ''; // 把Value转换为字符串
|
||
for (var i = 0, count = data.length; i < count; i++) {
|
||
var item = data[i];
|
||
if (item[0] === value) {
|
||
return item[1];
|
||
}
|
||
}
|
||
return '';
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.Button) {
|
||
Ext.override(Ext.Button, {
|
||
|
||
x_setTooltip: function () {
|
||
this.setTooltip(this.x_state['ToolTip']);
|
||
},
|
||
|
||
x_toggle: function () {
|
||
this.toggle(this.x_state['Pressed']);
|
||
},
|
||
|
||
x_setText: function () {
|
||
this.setText(this.x_state['Text']);
|
||
}
|
||
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.grid.RowNumberer) {
|
||
|
||
X.originalRowNumbererRenderer = Ext.grid.RowNumberer.prototype.renderer;
|
||
Ext.override(Ext.grid.RowNumberer, {
|
||
|
||
renderer: function (v, p, record, rowIndex) {
|
||
|
||
var number = X.originalRowNumbererRenderer.call(this, v, p, record, rowIndex);
|
||
|
||
if (this.x_paging_enabled && this.x_paging) {
|
||
number += this.x_paging.pageIndex * this.x_paging.pageSize;
|
||
}
|
||
|
||
return number;
|
||
}
|
||
|
||
});
|
||
|
||
}
|
||
|
||
|
||
if (Ext.grid.GridPanel) {
|
||
Ext.override(Ext.grid.GridPanel, {
|
||
|
||
x_getData: function () {
|
||
var data = this.x_state['X_Rows']['Values'];
|
||
|
||
//////////////////////////////////////////////////
|
||
var tpls = this.x_tpls;
|
||
//if (!tpls) {
|
||
if (typeof (tpls) === 'undefined') {
|
||
tpls = this.x_getTpls();
|
||
}
|
||
|
||
// 将Grid1_ctl37与对应的outHTML放在哈希表中
|
||
var tplsHash = {};
|
||
var e = document.createElement('div');
|
||
e.innerHTML = tpls;
|
||
Ext.each(e.childNodes, function (item, index) {
|
||
tplsHash[item.id] = item.outerHTML.replace(/\r?\n\s*/ig, '');
|
||
});
|
||
|
||
// INPUT: /(<div id="(.+)_container">)<\/div>/ig.exec("<div id=\"Grid1_ctl37_container\"></div>")
|
||
// OUTPUT: ["<div id="Grid1_ctl37_container"></div>", "<div id="Grid1_ctl37_container">", "Grid1_ctl37"]
|
||
Ext.each(data, function (row, rowIndex) {
|
||
Ext.each(row, function (item, index) {
|
||
/*
|
||
var regTpl = /(<div id=\"(.+)_container\">)<\/div>/ig.exec(item);
|
||
if (regTpl) {
|
||
row[index] = regTpl[1] + tplsHash[regTpl[2]] + '</div>';
|
||
}
|
||
*/
|
||
if (item.substr(0, 7) === "#@TPL@#") {
|
||
var clientId = item.substr(7);
|
||
row[index] = '<div id="' + clientId + '_container">' + tplsHash[clientId] + '</div>';
|
||
}
|
||
});
|
||
});
|
||
//////////////////////////////////////////////////
|
||
|
||
return data;
|
||
},
|
||
|
||
x_getTpls: function () {
|
||
//var tplsNode = this.el.parent().down('.x-grid-tpls');
|
||
var tplsNode = Ext.get(this.id + '_tpls');
|
||
tpls = tplsNode.dom.innerHTML;
|
||
tplsNode.remove();
|
||
return tpls;
|
||
},
|
||
|
||
|
||
x_updateTpls: function (tpls) {
|
||
if (typeof (tpls) == 'undefined') {
|
||
tpls = this.x_getTpls();
|
||
}
|
||
|
||
var e = document.createElement('div');
|
||
e.innerHTML = tpls;
|
||
Ext.each(e.childNodes, function (item, index) {
|
||
var nodeId = item.id;
|
||
Ext.get(nodeId + '_container').dom.innerHTML = item.outerHTML;
|
||
});
|
||
},
|
||
|
||
|
||
x_loadData: function () {
|
||
var datas = this.x_getData();
|
||
var pagingBar = this.getBottomToolbar();
|
||
if (pagingBar) {
|
||
var pagingDatas = [];
|
||
if (pagingBar.x_databasePaging) {
|
||
pagingDatas = datas;
|
||
} else {
|
||
for (var i = pagingBar.x_startRowIndex; i <= pagingBar.x_endRowIndex; i++) {
|
||
pagingDatas.push(datas[i]);
|
||
}
|
||
}
|
||
datas = pagingDatas;
|
||
}
|
||
|
||
|
||
var store = this.getStore();
|
||
|
||
// 拒绝之前对表格的编辑,因为接下来就要重新加载数据
|
||
store.rejectChanges();
|
||
|
||
// 重新加载数据前清空之前的改变
|
||
this.x_newAddedRows = [];
|
||
|
||
store.loadData(datas);
|
||
|
||
},
|
||
|
||
// 展开所有的行扩展列
|
||
x_expandAllRows: function () {
|
||
if (this.plugins && this.plugins[0] && this.plugins[0].id === 'expander') {
|
||
for (var i = 0, count = this.store.getCount(); i < count; i++) {
|
||
this.plugins[0].expandRow(i);
|
||
}
|
||
}
|
||
},
|
||
|
||
// 隐藏所有的行扩展列
|
||
x_collapseAllRows: function () {
|
||
if (this.plugins && this.plugins[0] && this.plugins[0].id === 'expander') {
|
||
for (var i = 0, count = this.store.getCount(); i < count; i++) {
|
||
this.plugins[0].collapseRow(i);
|
||
}
|
||
}
|
||
},
|
||
|
||
// http://evilcroco.name/2010/10/making-extjs-grid-content-selectable/
|
||
/* IE下允许选中表格中的文本 */
|
||
x_enableTextSelection: function () {
|
||
//if (Ext.isIE) {
|
||
var elems = Ext.DomQuery.select("div[unselectable=on]", this.el.dom);
|
||
for (var i = 0, len = elems.length; i < len; i++) {
|
||
Ext.get(elems[i]).set({ 'unselectable': 'off' }).removeClass('x-unselectable');
|
||
}
|
||
//}
|
||
},
|
||
|
||
|
||
// 获取选中的行数,或者单元格数(单元格编辑模式)
|
||
x_getSelectedCount: function () {
|
||
var selectedCount = 0;
|
||
var sm = this.getSelectionModel();
|
||
if (sm.hasSelection()) {
|
||
if (sm.getCount) {
|
||
selectedCount = sm.getCount();
|
||
} else {
|
||
// 单元格编辑模式,只可能选中一个单元格
|
||
selectedCount = 1;
|
||
}
|
||
}
|
||
return selectedCount;
|
||
},
|
||
|
||
// 选中某些行
|
||
x_selectRows: function (rows) {
|
||
rows = rows || this.x_state['SelectedRowIndexArray'] || [];
|
||
var sm = this.getSelectionModel();
|
||
if (sm.selectRows) {
|
||
sm.selectRows(rows);
|
||
}
|
||
},
|
||
|
||
// 获取选中的行
|
||
x_getSelectedRows: function () {
|
||
var selectedRows = [];
|
||
var sm = this.getSelectionModel();
|
||
if (sm.getSelections) {
|
||
var selections = sm.getSelections();
|
||
var store = this.getStore();
|
||
|
||
Ext.each(selections, function (record, index) {
|
||
selectedRows.push(store.indexOfId(record.id));
|
||
});
|
||
}
|
||
|
||
return selectedRows;
|
||
},
|
||
|
||
|
||
// 选中单元格(AllowCellEditing)
|
||
x_selectCell: function (cell) {
|
||
cell = cell || this.x_state['SelectedCell'] || [];
|
||
var sm = this.getSelectionModel();
|
||
if (sm.select) {
|
||
if (cell.length === 2) {
|
||
sm.select(cell[0], cell[1]);
|
||
} else {
|
||
sm.clearSelections();
|
||
}
|
||
}
|
||
},
|
||
|
||
// 获取选中的单元格(AllowCellEditing)
|
||
x_getSelectedCell: function () {
|
||
var selectedCell = [];
|
||
var sm = this.getSelectionModel();
|
||
if (sm.getSelectedCell) {
|
||
selectedCell = sm.getSelectedCell();
|
||
if (!selectedCell) {
|
||
selectedCell = [];
|
||
}
|
||
}
|
||
return selectedCell;
|
||
},
|
||
|
||
|
||
|
||
// 获取隐藏列的索引列表
|
||
x_getHiddenColumns: function () {
|
||
var hiddens = [], model = this.getColumnModel(), columns = model.config;
|
||
Ext.each(columns, function (column, index) {
|
||
if (model.isHidden(index)) {
|
||
hiddens.push(index);
|
||
}
|
||
});
|
||
return hiddens;
|
||
},
|
||
|
||
// 隐藏需要隐藏的列,显示不需要隐藏的列
|
||
x_updateColumnsHiddenStatus: function (hiddens) {
|
||
hiddens = hiddens || this.x_state['HiddenColumnIndexArray'] || [];
|
||
var model = this.getColumnModel(), columns = model.config;
|
||
Ext.each(columns, function (column, index) {
|
||
if (hiddens.indexOf(index) !== -1) {
|
||
model.setHidden(index, true);
|
||
} else {
|
||
model.setHidden(index, false);
|
||
}
|
||
});
|
||
},
|
||
|
||
// 设置表格标题栏的排序图标 .x-grid3-hd-over
|
||
x_setSortIcon: function (sortColumnIndex, sortDirection) {
|
||
var gridEl = Ext.get(this.id), columns = this.x_getColumns();
|
||
|
||
function getHeaderNode(index) {
|
||
if (typeof (index) === 'number') {
|
||
return gridEl.select('.x-grid3-hd-row .x-grid3-cell.x-grid3-td-' + columns[index].id);
|
||
} else {
|
||
return gridEl.select('.x-grid3-hd-row .x-grid3-cell.x-grid3-hd');
|
||
}
|
||
}
|
||
|
||
// Clear sort icon for all column header.
|
||
getHeaderNode().removeClass(['sort-asc', 'sort-desc']);
|
||
|
||
// Add cursor to all server sortable column header.
|
||
Ext.each(columns, function (item, index) {
|
||
if (item['sortable']) {
|
||
getHeaderNode(index).addClass('cursor-pointer');
|
||
}
|
||
});
|
||
|
||
// Set current sort column
|
||
if (sortColumnIndex >= 0 && sortColumnIndex < columns.length) {
|
||
getHeaderNode(sortColumnIndex).addClass('sort-' + sortDirection.toLowerCase());
|
||
}
|
||
|
||
},
|
||
|
||
// 获取表格列
|
||
x_getColumns: function () {
|
||
var columns = [];
|
||
// this.getColumnModel().config -> An Array of Column definition objects representing the configuration of this ColumnModel.
|
||
var configColumns = this.getColumnModel().config;
|
||
Ext.each(configColumns, function (item, index) {
|
||
// expander也属于表格列的一种类型,否则设置x_setSortIcon会出错
|
||
if (item.id !== 'numberer' && item.id !== 'checker') { // && item.id !== 'expander'
|
||
columns.push(item);
|
||
}
|
||
});
|
||
return columns;
|
||
},
|
||
|
||
// 这个方法用不到了,现在对States的更新会导致Values的改变,进而促使表格的重新加载
|
||
/*
|
||
x_setRowStates: function (states) {
|
||
var gridEl = Ext.get(this.id), columns = this.x_getColumns(), states = states || this.x_state['X_States'] || [];
|
||
|
||
function setCheckBoxStates(columnIndex, stateColumnIndex) {
|
||
var checkboxRows = gridEl.select('.x-grid3-body .x-grid3-row .x-grid3-td-' + columns[columnIndex].id + ' .box-grid-checkbox');
|
||
checkboxRows.each(function (row, rows, index) {
|
||
if (states[index][stateColumnIndex]) {
|
||
if (row.hasClass('box-grid-checkbox-unchecked-disabled')) {
|
||
row.removeClass('box-grid-checkbox-unchecked-disabled');
|
||
} else {
|
||
row.removeClass('box-grid-checkbox-unchecked');
|
||
}
|
||
} else {
|
||
if (row.hasClass('box-grid-checkbox-disabled')) {
|
||
row.addClass('box-grid-checkbox-unchecked-disabled')
|
||
} else {
|
||
row.addClass('box-grid-checkbox-unchecked')
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
var stateColumnIndex = 0;
|
||
Ext.each(columns, function (column, index) {
|
||
if (column['x_persistState']) {
|
||
if (column['x_persistStateType'] === 'checkbox') {
|
||
setCheckBoxStates(index, stateColumnIndex);
|
||
stateColumnIndex++;
|
||
}
|
||
}
|
||
});
|
||
},
|
||
*/
|
||
|
||
// 获取列状态(目前只有CheckBoxField用到)
|
||
x_getStates: function () {
|
||
var gridEl = Ext.get(this.id), columns = this.x_getColumns(), states = [];
|
||
|
||
function getCheckBoxStates(columnIndex) {
|
||
var checkboxRows = gridEl.select('.x-grid3-row .x-grid3-td-' + columns[columnIndex].id + ' .box-grid-checkbox');
|
||
var columnStates = [];
|
||
checkboxRows.each(function (row, index) {
|
||
if (row.hasClass('box-grid-checkbox-unchecked') || row.hasClass('box-grid-checkbox-unchecked-disabled')) {
|
||
columnStates.push(false);
|
||
} else {
|
||
columnStates.push(true);
|
||
}
|
||
});
|
||
return columnStates;
|
||
}
|
||
|
||
Ext.each(columns, function (column, index) {
|
||
if (column['x_persistState']) {
|
||
if (column['x_persistStateType'] === 'checkbox') {
|
||
states.push(getCheckBoxStates(index));
|
||
}
|
||
}
|
||
});
|
||
|
||
// 把列状态列表转换为行状态列表,与后台数据保持一致
|
||
var i, resolvedStates = [], rowState, rowCount;
|
||
if (states.length > 0) {
|
||
rowCount = states[0].length;
|
||
for (i = 0; i < rowCount; i++) {
|
||
rowState = [];
|
||
Ext.each(states, function (state, index) {
|
||
rowState.push(state[i]);
|
||
});
|
||
resolvedStates.push(rowState);
|
||
}
|
||
}
|
||
|
||
return resolvedStates;
|
||
},
|
||
|
||
// 提交客户端改变
|
||
x_commitChanges: function () {
|
||
|
||
this.getStore().commitChanges();
|
||
|
||
this.x_newAddedRows = [];
|
||
},
|
||
|
||
// 添加一条新纪录
|
||
x_addNewRecord: function (defaultObj, appendToEnd) {
|
||
var i, count, store = this.getStore();
|
||
var recordType = store.recordType;
|
||
var newRecord = new recordType(defaultObj);
|
||
|
||
// 记录客户端新增的行索引,this.x_newAddedRows
|
||
|
||
this.stopEditing();
|
||
if (appendToEnd) {
|
||
store.add(newRecord);
|
||
|
||
// 新增客户端改变的行索引
|
||
this.x_newAddedRows.push(store.getCount() - 1);
|
||
|
||
} else {
|
||
store.insert(0, newRecord);
|
||
|
||
// 新增客户端改变的行索引
|
||
for (i = 0, count = this.x_newAddedRows.length; i < count; i++) {
|
||
this.x_newAddedRows[i]++;
|
||
}
|
||
this.x_newAddedRows.push(0);
|
||
|
||
}
|
||
this.startEditing(0, 0);
|
||
},
|
||
|
||
|
||
// 获取用户改变的单元格值
|
||
x_getEditorData: function () {
|
||
var i, j, count, columns = this.x_getColumns();
|
||
/*
|
||
for (i = 0, count = columns.length; i < count; i++) {
|
||
columnMap[columns[i].dataIndex] = i;
|
||
}
|
||
*/
|
||
|
||
var modifiedRows = [];
|
||
var store = this.getStore();
|
||
var modifiedRecords = store.getModifiedRecords();
|
||
var rowIndex, rowData, newData, modifiedRecord;
|
||
for (i = 0, count = modifiedRecords.length; i < count; i++) {
|
||
modifiedRecord = modifiedRecords[i];
|
||
rowIndex = store.indexOf(modifiedRecord);
|
||
rowData = modifiedRecord.data;
|
||
if (rowIndex < 0) {
|
||
continue;
|
||
}
|
||
|
||
if (this.x_newAddedRows.indexOf(rowIndex) >= 0) {
|
||
|
||
// 新增数据行
|
||
modifiedRows.push([rowIndex, rowData]);
|
||
|
||
} else {
|
||
|
||
// 修改现有数据行
|
||
var rowModifiedObj = {};
|
||
for (var columnid in modifiedRecord.modified) {
|
||
/*
|
||
columnIndex = columnMap[modifiedKey];
|
||
if (typeof (columnIndex) === 'undefined') {
|
||
continue;
|
||
}*/
|
||
|
||
newData = rowData[columnid];
|
||
//oldData = modifiedRecord.modified[columnid];
|
||
|
||
rowModifiedObj[columnid] = newData;
|
||
|
||
}
|
||
|
||
modifiedRows.push([rowIndex, rowModifiedObj]);
|
||
}
|
||
|
||
}
|
||
|
||
return modifiedRows;
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.tree.TreePanel) {
|
||
Ext.override(Ext.tree.TreePanel, {
|
||
|
||
x_loadData: function () {
|
||
var datas = this.x_state['X_Nodes'];
|
||
var nodes = this.x_tranformData(datas);
|
||
var root = this.getRootNode();
|
||
if (root) {
|
||
root.removeAll();
|
||
}
|
||
this.setRootNode(new Ext.tree.AsyncTreeNode({
|
||
id: this.id + '_root',
|
||
children: nodes
|
||
}));
|
||
},
|
||
|
||
x_tranformData: function (datas) {
|
||
var that = this, i = 0, nodes = [];
|
||
for (var i = 0; i < datas.length; i++) {
|
||
var data = datas[i], node = {};
|
||
|
||
// function copyIfExists(prop) {
|
||
// if (typeof (data[prop]) !== 'undefined') {
|
||
// node[prop] = data[prop];
|
||
// }
|
||
// }
|
||
|
||
// 0 - Text
|
||
// 1 - Leaf
|
||
// 2 - NodeID
|
||
// 3 - Enabled
|
||
// 4 - EnableCheckBox
|
||
// 5 - Checked
|
||
// 6 - Expanded
|
||
// 7 - NavigateUrl
|
||
// 8 - Target
|
||
// 9 - href
|
||
// 10 - Icon
|
||
// 11 - IconUrl
|
||
// 12 - iconUrl
|
||
// 13 - ToolTip
|
||
// 14 - SingleClickExpand
|
||
// 15 - OnClientClick
|
||
// 16 - EnablePostBack
|
||
// 17 - AutoPostBack
|
||
// 18 - CommandName
|
||
// 19 - CommandArgument
|
||
// 20 - Nodes
|
||
node.text = data[0];
|
||
node.leaf = !!data[1];
|
||
node.id = data[2];
|
||
node.disabled = !data[3];
|
||
if (!!data[4]) {
|
||
node.checked = !!data[5];
|
||
}
|
||
if (!data[1]) {
|
||
node.expanded = !!data[6];
|
||
}
|
||
if (data[9]) {
|
||
node.href = data[9];
|
||
node.hrefTarget = data[8];
|
||
}
|
||
if (data[12]) {
|
||
node.icon = data[12];
|
||
}
|
||
node.qtip = data[13];
|
||
node.singleClickExpand = !!data[14];
|
||
|
||
|
||
node.listeners = {};
|
||
|
||
if (!data[3]) {
|
||
node.listeners.beforeclick = function () {
|
||
return false;
|
||
};
|
||
}
|
||
|
||
if (!!data[4] && !!data[17]) {
|
||
node.listeners.checkchange = function (node, checked) {
|
||
var args = 'Check$' + node.id + '$' + checked;
|
||
__doPostBack(that.name, args);
|
||
};
|
||
}
|
||
|
||
var clickScript = '';
|
||
if (data[15]) {
|
||
clickScript += data[15] + ';';
|
||
}
|
||
if (!!data[16]) {
|
||
clickScript += "__doPostBack('" + that.name + "', 'Command$" + node.id + "$" + data[18] + "$" + data[19] + "');";
|
||
}
|
||
if (clickScript) {
|
||
node.listeners.click = new Function('node', clickScript);
|
||
}
|
||
|
||
|
||
if (data[20] && data[20].length > 0) {
|
||
node.children = that.x_tranformData(data[20]);
|
||
}
|
||
|
||
nodes.push(node);
|
||
}
|
||
return nodes;
|
||
},
|
||
|
||
x_getExpandedNodes: function (nodes) {
|
||
var i = 0, that = this, expandedNodes = [];
|
||
|
||
for (; i < nodes.length; i++) {
|
||
var node = nodes[i];
|
||
if (node.isExpanded()) {
|
||
expandedNodes.push(node.id);
|
||
}
|
||
if (node.hasChildNodes()) {
|
||
expandedNodes = expandedNodes.concat(that.x_getExpandedNodes(node.childNodes));
|
||
}
|
||
}
|
||
|
||
return expandedNodes;
|
||
},
|
||
|
||
x_getCheckedNodes: function () {
|
||
return this.getChecked('id');
|
||
},
|
||
|
||
x_getSelectedNodes: function () {
|
||
var model = this.getSelectionModel(), nodes = [];
|
||
if (model.constructor === Ext.tree.MultiSelectionModel) {
|
||
Ext.each(model.getSelectedNodes(), function (item, index) {
|
||
nodes.push(item.id);
|
||
});
|
||
} else {
|
||
var selectedNode = model.getSelectedNode();
|
||
if (selectedNode) {
|
||
nodes.push(selectedNode.id);
|
||
}
|
||
}
|
||
return nodes;
|
||
},
|
||
|
||
x_selectNodes: function () {
|
||
var datas = this.x_state['SelectedNodeIDArray'] || [];
|
||
var model = this.getSelectionModel(), i = 0;
|
||
for (var i = 0; i < datas.length; i++) {
|
||
model.select(this.getNodeById(datas[i]), null, true);
|
||
}
|
||
}
|
||
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.PagingToolbar) {
|
||
// We don't use this Class in current version.
|
||
Ext.override(Ext.PagingToolbar, {
|
||
|
||
x_hideRefresh: function () {
|
||
var index = this.items.indexOf(this.refresh);
|
||
this.items.get(index - 1).hide();
|
||
this.refresh.hide();
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.TabPanel) {
|
||
Ext.override(Ext.TabPanel, {
|
||
|
||
x_autoPostBackTabsContains: function (tabId) {
|
||
var tabs = this.x_state['X_AutoPostBackTabs'];
|
||
return tabs.indexOf(tabId) !== -1;
|
||
},
|
||
|
||
x_setActiveTab: function () {
|
||
var tabIndex = this.x_state['ActiveTabIndex'];
|
||
this.setActiveTab(tabIndex);
|
||
},
|
||
|
||
x_getActiveTabIndex: function () {
|
||
return this.items.indexOf(this.getActiveTab());
|
||
},
|
||
|
||
/*
|
||
// private
|
||
onBeforeShowItem: function (item) {
|
||
this.showTab(item);
|
||
if (item != this.activeTab) {
|
||
this.setActiveTab(item);
|
||
return false;
|
||
}
|
||
},
|
||
// private
|
||
onStripMouseDown: function (e) {
|
||
if (e.button !== 0) {
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
var t = this.findTargets(e);
|
||
if (t.close) {
|
||
if (t.item['x_dynamic_added_tab']) {
|
||
if (t.item.fireEvent('beforeclose', t.item) !== false) {
|
||
t.item.fireEvent('close', t.item);
|
||
this.remove(t.item);
|
||
}
|
||
} else {
|
||
this.hideTab(t.item);
|
||
}
|
||
return;
|
||
}
|
||
if (t.item && t.item != this.activeTab) {
|
||
this.setActiveTab(t.item);
|
||
}
|
||
},
|
||
*/
|
||
|
||
|
||
activateNextTab: function (c) {
|
||
if (c == this.activeTab) {
|
||
var next = this.stack.next();
|
||
if (next) {
|
||
this.setActiveTab(next);
|
||
}
|
||
if (next = this.items.find(function (t) { return t.tabEl.style.display !== 'none'; })) {
|
||
// Find the first visible tab and set it active tab.
|
||
this.setActiveTab(next);
|
||
} else {
|
||
this.setActiveTab(null);
|
||
}
|
||
}
|
||
},
|
||
|
||
hideTab: function (item) {
|
||
item = this.getComponent(item);
|
||
this.hideTabStripItem(item);
|
||
item.hide();
|
||
this.activateNextTab(item);
|
||
},
|
||
|
||
showTab: function (item) {
|
||
item = this.getComponent(item);
|
||
this.unhideTabStripItem(item);
|
||
},
|
||
|
||
|
||
addTab: function (id, url, title, closable) {
|
||
var options = {};
|
||
if (typeof (id) === 'string') {
|
||
Ext.apply(options, {
|
||
'id': id,
|
||
'title': title,
|
||
'closable': closable,
|
||
'url': url
|
||
});
|
||
} else {
|
||
// id is not a string, then there should be only one argument.
|
||
Ext.apply(options, id);
|
||
}
|
||
Ext.apply(options, {
|
||
'x_dynamic_added_tab': true,
|
||
'html': '<iframe id="' + options.id + '" name="' + options.id + '" src="' + options.url + '" frameborder="0" style="height:100%;width:100%;overflow:auto;"\></iframe\>'
|
||
});
|
||
var tab = this.add(options);
|
||
this.activate(tab);
|
||
|
||
return tab;
|
||
},
|
||
|
||
getTab: function (id) {
|
||
return this.getItem(id);
|
||
},
|
||
|
||
removeTab: function (id) {
|
||
this.remove(id);
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
|
||
|
||
|
||
if (Ext.Window) {
|
||
|
||
Ext.override(Ext.Window, {
|
||
|
||
// 此函数为了兼容考虑,请使用 x_hide 函数
|
||
box_hide: function () {
|
||
this.x_hide();
|
||
},
|
||
box_hide_refresh: function () {
|
||
this.x_hide_refresh();
|
||
},
|
||
box_hide_postback: function (argument) {
|
||
this.x_hide_postback(argument);
|
||
},
|
||
box_show: function (iframeUrl, windowTitle) {
|
||
this.x_show(iframeUrl, windowTitle);
|
||
},
|
||
|
||
|
||
x_hide: function () {
|
||
X.wnd.hide(this, this.x_property_target, this.x_iframe, this.id + '_Hidden', this.x_property_guid);
|
||
},
|
||
x_hide_refresh: function () {
|
||
this.x_hide();
|
||
window.location.reload();
|
||
},
|
||
x_hide_postback: function (argument) {
|
||
this.x_hide();
|
||
__doPostBack(this.id, argument);
|
||
},
|
||
x_show: function (iframeUrl, windowTitle) {
|
||
X.wnd.show(this, iframeUrl, windowTitle, this.x_property_left, this.x_property_top, this.x_property_position, this.id + '_Hidden');
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
|
||
if (Ext.dd.DragDrop) {
|
||
// 修正IE7下,窗口出现滚动条时,点击Window控件标题栏有时node为null的问题
|
||
X.originalIsValidHandleChild = Ext.dd.DragDrop.prototype.isValidHandleChild;
|
||
Ext.dd.DragDrop.prototype.isValidHandleChild = function (node) {
|
||
if (!node || !node.nodeName) {
|
||
return false;
|
||
}
|
||
return X.originalIsValidHandleChild.apply(this, [node]);
|
||
};
|
||
}
|
||
|
||
if (Ext.grid.GridPanel) {
|
||
// 修正在IE下,Grid的模版列中出现文本输入框或者下拉列表时,第一次不能选中的问题
|
||
// 已经有网友发现这个问题:http://www.sencha.com/forum/archive/index.php/t-49653.html
|
||
// This is what caused my self-rendered-Html-Elements to "flicker" as described in my other thread.
|
||
// The Dropdown receives the Click, opens and stays open for the Millisecond until
|
||
// Ext calls back and gives focus to the Cell, causing my Drop-Down to close again.
|
||
Ext.grid.GridView.prototype.focusCell = function (row, col, hscroll) {
|
||
this.syncFocusEl(this.ensureVisible(row, col, hscroll));
|
||
|
||
var focusEl = this.focusEl;
|
||
|
||
focusEl.focus();
|
||
};
|
||
}
|
||
|
||
|
||
if (Ext.ux.grid && Ext.ux.grid.ColumnHeaderGroup) {
|
||
// 修正Chrome下多表头样式错位
|
||
// 增加 !Ext.isChrome 的判断,在Chrome下DIV的宽度不包括边框的宽度
|
||
Ext.ux.grid.ColumnHeaderGroup.prototype.getGroupStyle = function (group, gcol) {
|
||
var width = 0, hidden = true;
|
||
for (var i = gcol, len = gcol + group.colspan; i < len; i++) {
|
||
if (!this.cm.isHidden(i)) {
|
||
var cw = this.cm.getColumnWidth(i);
|
||
if (typeof cw == 'number') {
|
||
width += cw;
|
||
}
|
||
hidden = false;
|
||
}
|
||
}
|
||
return {
|
||
width: (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2 && !Ext.isChrome) ? width : Math.max(width - this.borderWidth, 0)) + 'px',
|
||
hidden: hidden
|
||
};
|
||
};
|
||
|
||
}
|
||
(function() {
|
||
|
||
function getParentIndex(levels, level, index) {
|
||
if (level > 0) {
|
||
for (var i = index - 1; i >= 0; i--) {
|
||
if (levels[i] == level - 1) {
|
||
return i;
|
||
}
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
function hasLittleBrother(levels, level, index) {
|
||
if (index < levels.length - 1) {
|
||
for (var i = index + 1; i < levels.length; i++) {
|
||
if (levels[i] == level) {
|
||
return true;
|
||
} else if (levels[i] < level) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function getParentTempData(tempdatas, tempdata, prefixIndex) {
|
||
for (var i = 0; i < prefixIndex - 1; i++) {
|
||
tempdata = tempdatas[tempdata.parentIndex];
|
||
}
|
||
return tempdata;
|
||
}
|
||
|
||
function getPrefixInner(tempdatas, tempdata, prefixIndex) {
|
||
// If level = 3, then prefixIndex array will be: [3, 2, 1]
|
||
// prefixIndex === 1 will always present the nearest prefix next to the Text.
|
||
if (prefixIndex === 1) {
|
||
if (tempdata.littleBrother) {
|
||
return '<div class="x-elbow"></div>';
|
||
}
|
||
else {
|
||
return '<div class="x-elbow-end"></div>';
|
||
}
|
||
} else {
|
||
var parentdata = getParentTempData(tempdatas, tempdata, prefixIndex);
|
||
if (parentdata.littleBrother) {
|
||
return '<div class="x-elbow-line"></div>';
|
||
}
|
||
else {
|
||
return '<div class="x-elbow-empty"></div>';
|
||
}
|
||
}
|
||
return "";
|
||
}
|
||
|
||
function getPrefix(tempdatas, index) {
|
||
var tempdata = tempdatas[index];
|
||
var level = tempdata.level;
|
||
var prefix = [];
|
||
for (var i = level; i > 0; i--) {
|
||
prefix.push(getPrefixInner(tempdatas, tempdata, i));
|
||
}
|
||
return prefix.join('');
|
||
}
|
||
|
||
X.simulateTree = {
|
||
|
||
transform: function(datas) {
|
||
if (!datas.length || datas[0].length < 4) {
|
||
return datas;
|
||
}
|
||
|
||
//// store: new Ext.data.ArrayStore({ fields: ['value', 'text', 'enabled', 'prefix'] })
|
||
//// Sample data:
|
||
//[
|
||
// ["0", "jQuery", 0, 0],
|
||
// ["1", "Core", 0, 1],
|
||
// ["2", "Selectors", 0, 1],
|
||
// ["3", "Basic Filters", 1, 2],
|
||
// ["4", "Content Filters", 1, 2],
|
||
// ["41", "Contains", 1, 3],
|
||
// ["5", "Attribute Filters", 1, 2],
|
||
// ["6", "Traversing", 1, 1],
|
||
// ["7", "Filtering", 1, 2],
|
||
// ["8", "Finding", 1, 2],
|
||
// ["9", "Events", 0, 1],
|
||
// ["10", "Page Load", 1, 2],
|
||
// ["11", "Event Handling", 1, 2],
|
||
// ["12", "Interaction Helpers", 1, 2],
|
||
// ["13", "Ajax", 1, 1]
|
||
//]
|
||
var levels = [];
|
||
Ext.each(datas, function(data, index) {
|
||
levels.push(data[3]);
|
||
});
|
||
|
||
var tempdatas = [];
|
||
Ext.each(levels, function(level, index) {
|
||
tempdatas.push({
|
||
'level': level,
|
||
'parentIndex': getParentIndex(levels, level, index),
|
||
'littleBrother': hasLittleBrother(levels, level, index)
|
||
});
|
||
});
|
||
|
||
var newdatas = [];
|
||
Ext.each(datas, function(data, index) {
|
||
newdatas.push([data[0], data[1], data[2], getPrefix(tempdatas, index)]);
|
||
});
|
||
return newdatas;
|
||
|
||
}
|
||
|
||
|
||
};
|
||
|
||
})();
|
||
(function () {
|
||
|
||
var F = Ext.util.Format;
|
||
|
||
X.format = {
|
||
|
||
capitalize: F.capitalize,
|
||
|
||
date: F.dateRenderer,
|
||
|
||
ellipsis: function (length) {
|
||
return function (value) {
|
||
return F.ellipsis(value, length, false);
|
||
};
|
||
},
|
||
|
||
fileSize: F.fileSize,
|
||
|
||
htmlEncode: F.htmlEncode,
|
||
|
||
htmlDecode: F.htmlDecode,
|
||
|
||
lowercase: F.lowercase,
|
||
|
||
uppercase: F.uppercase,
|
||
|
||
nl2br: F.nl2br,
|
||
|
||
number: F.numberRenderer,
|
||
|
||
stripScripts: F.stripScripts,
|
||
|
||
stripTags: F.stripTags,
|
||
|
||
trim: F.trim,
|
||
|
||
usMoney: F.usMoney
|
||
|
||
|
||
|
||
};
|
||
|
||
|
||
})(); |