Changeset c6b84df for public/vendors/dataTable/datatables.js
- Timestamp:
- 10/21/21 23:45:59 (3 years ago)
- Branches:
- develop, master
- Children:
- 4b7e2d3
- Parents:
- 6b95845
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
public/vendors/dataTable/datatables.js
r6b95845 rc6b84df 5740 5740 5741 5741 // 5742 // Setup limits is not necessary because in js we should not preallocate memory 5742 // Setup limits is not necessary because in js we should not preallocate memory 5743 5743 // for inflate use constant limit in 65536 bytes 5744 5744 // … … 16100 16100 var res = encoder.write(str); 16101 16101 var trail = encoder.end(); 16102 16102 16103 16103 return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res; 16104 16104 } … … 16140 16140 if (!iconv.encodings) 16141 16141 iconv.encodings = __webpack_require__(171); // Lazy load all encoding definitions. 16142 16142 16143 16143 // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. 16144 16144 var enc = (''+encoding).toLowerCase().replace(/[^0-9a-z]|:\d{4}$/g, ""); … … 16164 16164 if (!codecOptions.encodingName) 16165 16165 codecOptions.encodingName = enc; 16166 16166 16167 16167 enc = codecDef.type; 16168 16168 break; … … 16654 16654 UnicodeTrie = __webpack_require__(43); 16655 16655 16656 16656 16657 16657 16658 16658 base64 = __webpack_require__(131); … … 16828 16828 this.tag = 0; 16829 16829 this.bitcount = 0; 16830 16830 16831 16831 this.dest = dest; 16832 16832 this.destLen = 0; 16833 16833 16834 16834 this.ltree = new Tree(); /* dynamic length/symbol tree */ 16835 16835 this.dtree = new Tree(); /* dynamic distance tree */ … … 16973 16973 d.bitcount += 8; 16974 16974 } 16975 16975 16976 16976 var sum = 0, cur = 0, len = 0; 16977 16977 var tag = d.tag; … … 16986 16986 cur -= t.table[len]; 16987 16987 } while (cur >= 0); 16988 16988 16989 16989 d.tag = tag; 16990 16990 d.bitcount -= len; … … 17097 17097 var length, invlength; 17098 17098 var i; 17099 17099 17100 17100 /* unread from bitbuffer */ 17101 17101 while (d.bitcount > 8) { … … 17170 17170 return d.dest.subarray(0, d.destLen); 17171 17171 } 17172 17172 17173 17173 return d.dest; 17174 17174 } … … 20677 20677 return 16; 20678 20678 } 20679 20679 20680 20680 n = br.readBits(3); 20681 20681 if (n > 0) { 20682 20682 return 17 + n; 20683 20683 } 20684 20684 20685 20685 n = br.readBits(3); 20686 20686 if (n > 0) { 20687 20687 return 8 + n; 20688 20688 } 20689 20689 20690 20690 return 17; 20691 20691 } … … 20712 20712 20713 20713 function DecodeMetaBlockLength(br) { 20714 var out = new MetaBlockLength; 20714 var out = new MetaBlockLength; 20715 20715 var size_nibbles; 20716 20716 var size_bytes; 20717 20717 var i; 20718 20718 20719 20719 out.input_end = br.readBits(1); 20720 20720 if (out.input_end && br.readBits(1)) { 20721 20721 return out; 20722 20722 } 20723 20723 20724 20724 size_nibbles = br.readBits(2) + 4; 20725 20725 if (size_nibbles === 7) { 20726 20726 out.is_metadata = true; 20727 20727 20728 20728 if (br.readBits(1) !== 0) 20729 20729 throw new Error('Invalid reserved bit'); 20730 20730 20731 20731 size_bytes = br.readBits(2); 20732 20732 if (size_bytes === 0) 20733 20733 return out; 20734 20734 20735 20735 for (i = 0; i < size_bytes; i++) { 20736 20736 var next_byte = br.readBits(8); 20737 20737 if (i + 1 === size_bytes && size_bytes > 1 && next_byte === 0) 20738 20738 throw new Error('Invalid size byte'); 20739 20739 20740 20740 out.meta_block_length |= next_byte << (i * 8); 20741 20741 } … … 20745 20745 if (i + 1 === size_nibbles && size_nibbles > 4 && next_nibble === 0) 20746 20746 throw new Error('Invalid size nibble'); 20747 20747 20748 20748 out.meta_block_length |= next_nibble << (i * 4); 20749 20749 } 20750 20750 } 20751 20751 20752 20752 ++out.meta_block_length; 20753 20753 20754 20754 if (!out.input_end && !out.is_metadata) { 20755 20755 out.is_uncompressed = br.readBits(1); 20756 20756 } 20757 20757 20758 20758 return out; 20759 20759 } … … 20762 20762 function ReadSymbol(table, index, br) { 20763 20763 var start_index = index; 20764 20764 20765 20765 var nbits; 20766 20766 br.fillBitWindow(); … … 20782 20782 var repeat_code_len = 0; 20783 20783 var space = 32768; 20784 20784 20785 20785 var table = []; 20786 20786 for (var i = 0; i < 32; i++) 20787 20787 table.push(new HuffmanCode(0, 0)); 20788 20788 20789 20789 BrotliBuildHuffmanTable(table, 0, 5, code_length_code_lengths, CODE_LENGTH_CODES); 20790 20790 … … 20792 20792 var p = 0; 20793 20793 var code_len; 20794 20794 20795 20795 br.readMoreInput(); 20796 20796 br.fillBitWindow(); … … 20827 20827 throw new Error('[ReadHuffmanCodeLengths] symbol + repeat_delta > num_symbols'); 20828 20828 } 20829 20829 20830 20830 for (var x = 0; x < repeat_delta; x++) 20831 20831 code_lengths[symbol + x] = repeat_code_len; 20832 20832 20833 20833 symbol += repeat_delta; 20834 20834 20835 20835 if (repeat_code_len !== 0) { 20836 20836 space -= repeat_delta << (15 - repeat_code_len); … … 20841 20841 throw new Error("[ReadHuffmanCodeLengths] space = " + space); 20842 20842 } 20843 20843 20844 20844 for (; symbol < num_symbols; symbol++) 20845 20845 code_lengths[symbol] = 0; … … 20850 20850 var simple_code_or_skip; 20851 20851 var code_lengths = new Uint8Array(alphabet_size); 20852 20852 20853 20853 br.readMoreInput(); 20854 20854 20855 20855 /* simple_code_or_skip is used as follows: 20856 20856 1 for simple code; … … 20888 20888 throw new Error('[ReadHuffmanCode] invalid symbols'); 20889 20889 } 20890 20890 20891 20891 code_lengths[symbols[1]] = 1; 20892 20892 break; … … 20900 20900 throw new Error('[ReadHuffmanCode] invalid symbols'); 20901 20901 } 20902 20902 20903 20903 if (br.readBits(1)) { 20904 20904 code_lengths[symbols[2]] = 3; … … 20916 20916 /* Static Huffman code for the code length code lengths */ 20917 20917 var huff = [ 20918 new HuffmanCode(2, 0), new HuffmanCode(2, 4), new HuffmanCode(2, 3), new HuffmanCode(3, 2), 20918 new HuffmanCode(2, 0), new HuffmanCode(2, 4), new HuffmanCode(2, 3), new HuffmanCode(3, 2), 20919 20919 new HuffmanCode(2, 0), new HuffmanCode(2, 4), new HuffmanCode(2, 3), new HuffmanCode(4, 1), 20920 new HuffmanCode(2, 0), new HuffmanCode(2, 4), new HuffmanCode(2, 3), new HuffmanCode(3, 2), 20920 new HuffmanCode(2, 0), new HuffmanCode(2, 4), new HuffmanCode(2, 3), new HuffmanCode(3, 2), 20921 20921 new HuffmanCode(2, 0), new HuffmanCode(2, 4), new HuffmanCode(2, 3), new HuffmanCode(4, 5) 20922 20922 ]; … … 20935 20935 } 20936 20936 } 20937 20937 20938 20938 if (!(num_codes === 1 || space === 0)) 20939 20939 throw new Error('[ReadHuffmanCode] invalid num_codes or space'); 20940 20940 20941 20941 ReadHuffmanCodeLengths(code_length_code_lengths, alphabet_size, code_lengths, br); 20942 20942 } 20943 20943 20944 20944 table_size = BrotliBuildHuffmanTable(tables, table, HUFFMAN_TABLE_BITS, code_lengths, alphabet_size); 20945 20945 20946 20946 if (table_size === 0) { 20947 20947 throw new Error("[ReadHuffmanCode] BuildHuffmanTable failed: "); 20948 20948 } 20949 20949 20950 20950 return table_size; 20951 20951 } … … 20995 20995 this.alphabet_size = alphabet_size; 20996 20996 this.num_htrees = num_htrees; 20997 this.codes = new Array(num_htrees + num_htrees * kMaxHuffmanTableSize[(alphabet_size + 31) >>> 5]); 20997 this.codes = new Array(num_htrees + num_htrees * kMaxHuffmanTableSize[(alphabet_size + 31) >>> 5]); 20998 20998 this.htrees = new Uint32Array(num_htrees); 20999 20999 } … … 21016 21016 var table; 21017 21017 var i; 21018 21018 21019 21019 br.readMoreInput(); 21020 21020 var num_htrees = out.num_htrees = DecodeVarLenUint8(br) + 1; … … 21029 21029 max_run_length_prefix = br.readBits(4) + 1; 21030 21030 } 21031 21031 21032 21032 table = []; 21033 21033 for (i = 0; i < HUFFMAN_MAX_TABLE_SIZE; i++) { 21034 21034 table[i] = new HuffmanCode(0, 0); 21035 21035 } 21036 21036 21037 21037 ReadHuffmanCode(num_htrees + max_run_length_prefix, table, 0, br); 21038 21038 21039 21039 for (i = 0; i < context_map_size;) { 21040 21040 var code; … … 21062 21062 InverseMoveToFrontTransform(context_map, context_map_size); 21063 21063 } 21064 21064 21065 21065 return out; 21066 21066 } … … 21123 21123 for (var x = 0; x < tail; x++) 21124 21124 ringbuffer[rb_pos + x] = br.buf_[br_pos + x]; 21125 21125 21126 21126 nbytes -= tail; 21127 21127 rb_pos += tail; … … 21132 21132 for (var x = 0; x < nbytes; x++) 21133 21133 ringbuffer[rb_pos + x] = br.buf_[br_pos + x]; 21134 21134 21135 21135 rb_pos += nbytes; 21136 21136 len -= nbytes; … … 21140 21140 if (rb_pos >= rb_size) { 21141 21141 output.write(ringbuffer, rb_size); 21142 rb_pos -= rb_size; 21142 rb_pos -= rb_size; 21143 21143 for (var x = 0; x < rb_pos; x++) 21144 21144 ringbuffer[x] = ringbuffer[rb_size + x]; … … 21188 21188 function BrotliDecompressBuffer(buffer, output_size) { 21189 21189 var input = new BrotliInput(buffer); 21190 21190 21191 21191 if (output_size == null) { 21192 21192 output_size = BrotliDecompressedSize(buffer); 21193 21193 } 21194 21194 21195 21195 var output_buffer = new Uint8Array(output_size); 21196 21196 var output = new BrotliOutput(output_buffer); 21197 21197 21198 21198 BrotliDecompress(input, output); 21199 21199 21200 21200 if (output.pos < output.buffer.length) { 21201 21201 output.buffer = output.buffer.subarray(0, output.pos); 21202 21202 } 21203 21203 21204 21204 return output.buffer; 21205 21205 } … … 21288 21288 21289 21289 br.readMoreInput(); 21290 21290 21291 21291 var _out = DecodeMetaBlockLength(br); 21292 21292 meta_block_remaining_len = _out.meta_block_length; … … 21296 21296 tmp.set( output.buffer ); 21297 21297 output.buffer = tmp; 21298 } 21298 } 21299 21299 input_end = _out.input_end; 21300 21300 is_uncompressed = _out.is_uncompressed; 21301 21301 21302 21302 if (_out.is_metadata) { 21303 21303 JumpToByteBoundary(br); 21304 21304 21305 21305 for (; meta_block_remaining_len > 0; --meta_block_remaining_len) { 21306 21306 br.readMoreInput(); … … 21308 21308 br.readBits(8); 21309 21309 } 21310 21310 21311 21311 continue; 21312 21312 } 21313 21313 21314 21314 if (meta_block_remaining_len === 0) { 21315 21315 continue; 21316 21316 } 21317 21317 21318 21318 if (is_uncompressed) { 21319 21319 br.bit_pos_ = (br.bit_pos_ + 7) & ~7; … … 21323 21323 continue; 21324 21324 } 21325 21325 21326 21326 for (i = 0; i < 3; ++i) { 21327 21327 num_block_types[i] = DecodeVarLenUint8(br) + 1; … … 21333 21333 } 21334 21334 } 21335 21335 21336 21336 br.readMoreInput(); 21337 21337 21338 21338 distance_postfix_bits = br.readBits(2); 21339 21339 num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES + (br.readBits(4) << distance_postfix_bits); … … 21346 21346 context_modes[i] = (br.readBits(2) << 1); 21347 21347 } 21348 21348 21349 21349 var _o1 = DecodeContextMap(num_block_types[0] << kLiteralContextBits, br); 21350 21350 num_literal_htrees = _o1.num_htrees; 21351 21351 context_map = _o1.context_map; 21352 21352 21353 21353 var _o2 = DecodeContextMap(num_block_types[2] << kDistanceContextBits, br); 21354 21354 num_dist_htrees = _o2.num_htrees; 21355 21355 dist_context_map = _o2.context_map; 21356 21356 21357 21357 hgroup[0] = new HuffmanTreeGroup(kNumLiteralCodes, num_literal_htrees); 21358 21358 hgroup[1] = new HuffmanTreeGroup(kNumInsertAndCopyCodes, num_block_types[1]); … … 21384 21384 21385 21385 br.readMoreInput(); 21386 21386 21387 21387 if (block_length[1] === 0) { 21388 21388 DecodeBlockType(num_block_types[1], … … 21440 21440 if (distance_code < 0) { 21441 21441 var context; 21442 21442 21443 21443 br.readMoreInput(); 21444 21444 if (block_length[2] === 0) { … … 21502 21502 if (copy_dst >= ringbuffer_end) { 21503 21503 output.write(ringbuffer, ringbuffer_size); 21504 21504 21505 21505 for (var _x = 0; _x < (copy_dst - ringbuffer_end); _x++) 21506 21506 ringbuffer[_x] = ringbuffer[ringbuffer_end + _x]; … … 21567 21567 count = this.buffer.length - this.pos; 21568 21568 } 21569 21569 21570 21570 for (var p = 0; p < count; p++) 21571 21571 buf[i + p] = this.buffer[this.pos + p]; 21572 21572 21573 21573 this.pos += count; 21574 21574 return count; … … 21585 21585 if (this.pos + count > this.buffer.length) 21586 21586 throw new Error('Output buffer is not large enough'); 21587 21587 21588 21588 this.buffer.set(buf.subarray(0, count), this.pos); 21589 21589 this.pos += count; … … 21717 21717 } 21718 21718 } 21719 21719 21720 21720 table_bits = root_bits; 21721 21721 table_size = 1 << table_bits; … … 21727 21727 root_table[table + key] = new HuffmanCode(0, sorted[0] & 0xffff); 21728 21728 } 21729 21729 21730 21730 return total_size; 21731 21731 } … … 21760 21760 } 21761 21761 } 21762 21762 21763 21763 return total_size; 21764 21764 } … … 21772 21772 21773 21773 /* 21774 PDFImage - embeds images in PDF documents21774 PDFImage - embeds images in PDF folders 21775 21775 By Devon Govett 21776 21776 */ … … 22307 22307 * var docDefinition = { 22308 22308 * info: { 22309 * title: 'awesome Document',22309 * title: 'awesome Folder', 22310 22310 * author: 'john doe', 22311 22311 * subject: 'subject of document', … … 34686 34686 this._font = null; 34687 34687 this._registeredFonts = {}; 34688 34688 34689 34689 }, 34690 34690 font: function(src, family, size) { … … 35185 35185 35186 35186 // ISO (deprecated) 35187 [], { // windows 35187 [], { // windows 35188 35188 0x0436: 'af', 0x4009: 'en-IN', 0x0487: 'rw', 0x0432: 'tn', 35189 35189 0x041C: 'sq', 0x1809: 'en-IE', 0x0441: 'sw', 0x045B: 'si', … … 42587 42587 * - apply ljmo, vjmo, and tjmo OpenType features to decomposed Jamo sequences. 42588 42588 * 42589 * This logic is based on the following documents:42589 * This logic is based on the following folders: 42590 42590 * - http://www.microsoft.com/typography/OpenTypeDev/hangul/intro.htm 42591 42591 * - http://ktug.org/~nomos/harfbuzz-hangul/hangulshaper.pdf … … 49958 49958 ]; 49959 49959 49960 // Put all encoding/alias/codec definitions to single object and export it. 49960 // Put all encoding/alias/codec definitions to single object and export it. 49961 49961 for (var i = 0; i < modules.length; i++) { 49962 49962 var module = modules[i]; … … 50110 50110 50111 50111 InternalDecoderCesu8.prototype.write = function(buf) { 50112 var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, 50112 var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, 50113 50113 res = ''; 50114 50114 for (var i = 0; i < buf.length; i++) { … … 50284 50284 this.initialBytes.push(buf); 50285 50285 this.initialBytesLen += buf.length; 50286 50286 50287 50287 if (this.initialBytesLen < 16) // We need more bytes to use space heuristic (see below) 50288 50288 return ''; … … 50380 50380 // Non-direct chars are encoded as "+<base64>-"; single "+" char is encoded as "+-". 50381 50381 return new Buffer(str.replace(nonDirectChars, function(chunk) { 50382 return "+" + (chunk === '+' ? '' : 50383 this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) 50382 return "+" + (chunk === '+' ? '' : 50383 this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) 50384 50384 + "-"; 50385 50385 }.bind(this))); … … 50403 50403 base64Chars[i] = base64Regex.test(String.fromCharCode(i)); 50404 50404 50405 var plusChar = '+'.charCodeAt(0), 50405 var plusChar = '+'.charCodeAt(0), 50406 50406 minusChar = '-'.charCodeAt(0), 50407 50407 andChar = '&'.charCodeAt(0); … … 50652 50652 50653 50653 // Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that 50654 // correspond to encoded bytes (if 128 - then lower half is ASCII). 50654 // correspond to encoded bytes (if 128 - then lower half is ASCII). 50655 50655 50656 50656 exports._sbcs = SBCSCodec; … … 50658 50658 if (!codecOptions) 50659 50659 throw new Error("SBCS codec is called without the data.") 50660 50660 50661 50661 // Prepare char buffer for decoding. 50662 50662 if (!codecOptions.chars || (codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256)) 50663 50663 throw new Error("Encoding '"+codecOptions.type+"' has incorrect 'chars' (must be of len 128 or 256)"); 50664 50664 50665 50665 if (codecOptions.chars.length === 128) { 50666 50666 var asciiString = ""; … … 50671 50671 50672 50672 this.decodeBuf = new Buffer(codecOptions.chars, 'ucs2'); 50673 50673 50674 50674 // Encoding buffer. 50675 50675 var encodeBuf = new Buffer(65536); … … 50694 50694 for (var i = 0; i < str.length; i++) 50695 50695 buf[i] = this.encodeBuf[str.charCodeAt(i)]; 50696 50696 50697 50697 return buf; 50698 50698 } … … 51427 51427 this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node. 51428 51428 51429 // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. 51429 // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. 51430 51430 this.decodeTableSeq = []; 51431 51431 … … 51436 51436 this.defaultCharUnicode = iconv.defaultCharUnicode; 51437 51437 51438 51438 51439 51439 // Encode tables: Unicode -> DBCS. 51440 51440 … … 51445 51445 // <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence. 51446 51446 this.encodeTable = []; 51447 51447 51448 51448 // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of 51449 51449 // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key … … 51463 51463 skipEncodeChars[j] = true; 51464 51464 } 51465 51465 51466 51466 // Use decode trie to recursively fill out encode tables. 51467 51467 this._fillEncodeTable(0, 0, skipEncodeChars); … … 51500 51500 for (var i = 0x30; i <= 0x39; i++) 51501 51501 fourthByteNode[i] = GB18030_CODE 51502 } 51502 } 51503 51503 } 51504 51504 … … 51565 51565 writeTable[curAddr++] = code; // Basic char 51566 51566 } 51567 } 51567 } 51568 51568 else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character. 51569 51569 var charCode = writeTable[curAddr - 1] + 1; … … 51596 51596 51597 51597 DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) { 51598 51598 51599 51599 // Get the root of character tree according to first character of the sequence. 51600 51600 var uCode = seq[0]; … … 51657 51657 this.leadSurrogate = -1; 51658 51658 this.seqObj = undefined; 51659 51659 51660 51660 // Static data 51661 51661 this.encodeTable = codec.encodeTable; … … 51666 51666 51667 51667 DBCSEncoder.prototype.write = function(str) { 51668 var newBuf = new Buffer(str.length * (this.gb18030 ? 4 : 3)), 51668 var newBuf = new Buffer(str.length * (this.gb18030 ? 4 : 3)), 51669 51669 leadSurrogate = this.leadSurrogate, 51670 51670 seqObj = this.seqObj, nextChar = -1, … … 51679 51679 else { 51680 51680 var uCode = nextChar; 51681 nextChar = -1; 51681 nextChar = -1; 51682 51682 } 51683 51683 … … 51701 51701 uCode = UNASSIGNED; 51702 51702 } 51703 51703 51704 51704 } 51705 51705 } … … 51742 51742 if (subtable !== undefined) 51743 51743 dbcsCode = subtable[uCode & 0xFF]; 51744 51744 51745 51745 if (dbcsCode <= SEQ_START) { // Sequence start 51746 51746 seqObj = this.encodeTableSeq[SEQ_START-dbcsCode]; … … 51765 51765 if (dbcsCode === UNASSIGNED) 51766 51766 dbcsCode = this.defaultCharSingleByte; 51767 51767 51768 51768 if (dbcsCode < 0x100) { 51769 51769 newBuf[j++] = dbcsCode; … … 51812 51812 this.leadSurrogate = -1; 51813 51813 } 51814 51814 51815 51815 return newBuf.slice(0, j); 51816 51816 } … … 51836 51836 DBCSDecoder.prototype.write = function(buf) { 51837 51837 var newBuf = new Buffer(buf.length*2), 51838 nodeIdx = this.nodeIdx, 51838 nodeIdx = this.nodeIdx, 51839 51839 prevBuf = this.prevBuf, prevBufOffset = this.prevBuf.length, 51840 51840 seqStart = -this.prevBuf.length, // idx of the start of current parsed sequence. … … 51843 51843 if (prevBufOffset > 0) // Make prev buf overlap a little to make it easier to slice later. 51844 51844 prevBuf = Buffer.concat([prevBuf, buf.slice(0, 10)]); 51845 51845 51846 51846 for (var i = 0, j = 0; i < buf.length; i++) { 51847 51847 var curByte = (i >= 0) ? buf[i] : prevBuf[i + prevBufOffset]; … … 51850 51850 var uCode = this.decodeTables[nodeIdx][curByte]; 51851 51851 51852 if (uCode >= 0) { 51852 if (uCode >= 0) { 51853 51853 // Normal character, just use it. 51854 51854 } … … 51882 51882 51883 51883 // Write the character to buffer, handling higher planes using surrogate pair. 51884 if (uCode > 0xFFFF) { 51884 if (uCode > 0xFFFF) { 51885 51885 uCode -= 0x10000; 51886 51886 var uCodeLead = 0xD800 + Math.floor(uCode / 0x400); … … 51952 51952 51953 51953 module.exports = { 51954 51954 51955 51955 // == Japanese/ShiftJIS ==================================================== 51956 51956 // All japanese encodings are based on JIS X set of standards: 51957 51957 // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. 51958 // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. 51958 // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. 51959 51959 // Has several variations in 1978, 1983, 1990 and 1997. 51960 51960 // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. … … 51974 51974 // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. 51975 51975 // Used as-is in ISO2022 family. 51976 // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, 51976 // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, 51977 51977 // 0201-1976 Roman, 0208-1978, 0208-1983. 51978 51978 // * ISO2022-JP-1: Adds esc seq for 0212-1990. … … 52086 52086 // * Big5-2003 (Taiwan standard) almost superset of cp950. 52087 52087 // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. 52088 // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. 52088 // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. 52089 52089 // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. 52090 52090 // Plus, it has 4 combining sequences. … … 52097 52097 // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt 52098 52098 // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt 52099 // 52099 // 52100 52100 // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder 52101 52101 // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. … … 52166 52166 // == Exports ================================================================== 52167 52167 module.exports = function(iconv) { 52168 52168 52169 52169 // Additional Public API. 52170 52170 iconv.encodeStream = function encodeStream(encoding, options) { … … 52261 52261 try { 52262 52262 var res = this.conv.end(); 52263 if (res && res.length) this.push(res, this.encoding); 52263 if (res && res.length) this.push(res, this.encoding); 52264 52264 done(); 52265 52265 } … … 52309 52309 52310 52310 var nodeNativeEncodings = { 52311 'hex': true, 'utf8': true, 'utf-8': true, 'ascii': true, 'binary': true, 52311 'hex': true, 'utf8': true, 'utf-8': true, 'ascii': true, 'binary': true, 52312 52312 'base64': true, 'ucs2': true, 'ucs-2': true, 'utf16le': true, 'utf-16le': true, 52313 52313 }; … … 56164 56164 this.buf_ = new Uint8Array(BROTLI_IBUF_SIZE); 56165 56165 this.input_ = input; /* input callback */ 56166 56166 56167 56167 this.reset(); 56168 56168 } … … 56178 56178 this.bit_end_pos_ = 0; /* bit-reading end position from LSB of val_ */ 56179 56179 this.eos_ = 0; /* input stream is finished */ 56180 56180 56181 56181 this.readMoreInput(); 56182 56182 for (var i = 0; i < 4; i++) { … … 56184 56184 ++this.pos_; 56185 56185 } 56186 56186 56187 56187 return this.bit_end_pos_ > 0; 56188 56188 }; … … 56212 56212 throw new Error('Unexpected end of input'); 56213 56213 } 56214 56214 56215 56215 if (bytes_read < BROTLI_READ_SIZE) { 56216 56216 this.eos_ = 1; … … 56219 56219 this.buf_[dst + bytes_read + p] = 0; 56220 56220 } 56221 56221 56222 56222 if (dst === 0) { 56223 56223 /* Copy the head of the ringbuffer to the slack region. */ … … 56229 56229 this.buf_ptr_ = 0; 56230 56230 } 56231 56231 56232 56232 this.bit_end_pos_ += bytes_read << 3; 56233 56233 } … … 56235 56235 56236 56236 /* Guarantees that there are at least 24 bits in the buffer. */ 56237 BrotliBitReader.prototype.fillBitWindow = function() { 56237 BrotliBitReader.prototype.fillBitWindow = function() { 56238 56238 while (this.bit_pos_ >= 8) { 56239 56239 this.val_ >>>= 8; … … 56250 56250 this.fillBitWindow(); 56251 56251 } 56252 56252 56253 56253 var val = ((this.val_ >>> this.bit_pos_) & kBitMask[n_bits]); 56254 56254 this.bit_pos_ += n_bits; … … 56267 56267 56268 56268 /** 56269 * The normal dictionary-data.js is quite large, which makes it 56270 * unsuitable for browser usage. In order to make it smaller, 56269 * The normal dictionary-data.js is quite large, which makes it 56270 * unsuitable for browser usage. In order to make it smaller, 56271 56271 * we read dictionary.bin, which is a compressed version of 56272 * the dictionary, and on initial load, Brotli decompresses 56272 * the dictionary, and on initial load, Brotli decompresses 56273 56273 * it's own dictionary. 😜 56274 56274 */ … … 56781 56781 this.transform = transform; 56782 56782 this.suffix = new Uint8Array(suffix.length); 56783 56783 56784 56784 for (var i = 0; i < prefix.length; i++) 56785 56785 this.prefix[i] = prefix.charCodeAt(i); 56786 56786 56787 56787 for (var i = 0; i < suffix.length; i++) 56788 56788 this.suffix[i] = suffix.charCodeAt(i); … … 56923 56923 return 1; 56924 56924 } 56925 56925 56926 56926 /* An overly simplified uppercasing model for utf-8. */ 56927 56927 if (p[i] < 0xe0) { … … 56929 56929 return 2; 56930 56930 } 56931 56931 56932 56932 /* An arbitrary transform for three byte characters. */ 56933 56933 p[i + 2] ^= 5; … … 56943 56943 var start_idx = idx; 56944 56944 var uppercase; 56945 56945 56946 56946 if (skip > len) { 56947 56947 skip = len; 56948 56948 } 56949 56949 56950 56950 var prefix_pos = 0; 56951 56951 while (prefix_pos < prefix.length) { 56952 56952 dst[idx++] = prefix[prefix_pos++]; 56953 56953 } 56954 56954 56955 56955 word += skip; 56956 56956 len -= skip; 56957 56957 56958 56958 if (t <= kOmitLast9) { 56959 56959 len -= t; 56960 56960 } 56961 56961 56962 56962 for (i = 0; i < len; i++) { 56963 56963 dst[idx++] = BrotliDictionary.dictionary[word + i]; 56964 56964 } 56965 56965 56966 56966 uppercase = idx - len; 56967 56967 56968 56968 if (t === kUppercaseFirst) { 56969 56969 ToUpperCase(dst, uppercase); … … 56975 56975 } 56976 56976 } 56977 56977 56978 56978 var suffix_pos = 0; 56979 56979 while (suffix_pos < suffix.length) { 56980 56980 dst[idx++] = suffix[suffix_pos++]; 56981 56981 } 56982 56982 56983 56983 return idx - start_idx; 56984 56984 } … … 58713 58713 # MIT LICENSE 58714 58714 # Copyright (c) 2011 Devon Govett 58715 # 58716 # Permission is hereby granted, free of charge, to any person obtaining a copy of this 58717 # software and associated documentation files (the "Software"), to deal in the Software 58718 # without restriction, including without limitation the rights to use, copy, modify, merge, 58719 # publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 58715 # 58716 # Permission is hereby granted, free of charge, to any person obtaining a copy of this 58717 # software and associated documentation files (the "Software"), to deal in the Software 58718 # without restriction, including without limitation the rights to use, copy, modify, merge, 58719 # publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 58720 58720 # to whom the Software is furnished to do so, subject to the following conditions: 58721 # 58722 # The above copyright notice and this permission notice shall be included in all copies or 58721 # 58722 # The above copyright notice and this permission notice shall be included in all copies or 58723 58723 # substantial portions of the Software. 58724 # 58725 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 58726 # BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 58727 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 58728 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 58724 # 58725 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 58726 # BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 58727 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 58728 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 58729 58729 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 58730 58730 */ … … 59800 59800 return this.api(true).$( sSelector, oOpts ); 59801 59801 }; 59802 59803 59802 59803 59804 59804 /** 59805 59805 * Almost identical to $ in operation, but in this case returns the data for the matched … … 59854 59854 return this.api(true).rows( sSelector, oOpts ).data(); 59855 59855 }; 59856 59857 59856 59857 59858 59858 /** 59859 59859 * Create a DataTables Api instance, with the currently selected tables for … … 59873 59873 new _Api( this ); 59874 59874 }; 59875 59876 59875 59876 59877 59877 /** 59878 59878 * Add a single new row or multiple rows of data to the table. Please note … … 59916 59916 { 59917 59917 var api = this.api( true ); 59918 59918 59919 59919 /* Check if we want to add multiple rows or not */ 59920 59920 var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ? 59921 59921 api.rows.add( data ) : 59922 59922 api.row.add( data ); 59923 59923 59924 59924 if ( redraw === undefined || redraw ) { 59925 59925 api.draw(); 59926 59926 } 59927 59927 59928 59928 return rows.flatten().toArray(); 59929 59929 }; 59930 59931 59930 59931 59932 59932 /** 59933 59933 * This function will make DataTables recalculate the column sizes, based on the data … … 59956 59956 var settings = api.settings()[0]; 59957 59957 var scroll = settings.oScroll; 59958 59958 59959 59959 if ( bRedraw === undefined || bRedraw ) { 59960 59960 api.draw( false ); … … 59965 59965 } 59966 59966 }; 59967 59968 59967 59968 59969 59969 /** 59970 59970 * Quickly and simply clear a table … … 59984 59984 { 59985 59985 var api = this.api( true ).clear(); 59986 59986 59987 59987 if ( bRedraw === undefined || bRedraw ) { 59988 59988 api.draw(); 59989 59989 } 59990 59990 }; 59991 59992 59991 59992 59993 59993 /** 59994 59994 * The exact opposite of 'opening' a row, this function will close any rows which … … 60019 60019 this.api( true ).row( nTr ).child.hide(); 60020 60020 }; 60021 60022 60021 60022 60023 60023 /** 60024 60024 * Remove a row for the table … … 60045 60045 var settings = rows.settings()[0]; 60046 60046 var data = settings.aoData[ rows[0][0] ]; 60047 60047 60048 60048 rows.remove(); 60049 60049 60050 60050 if ( callback ) { 60051 60051 callback.call( this, settings, data ); 60052 60052 } 60053 60053 60054 60054 if ( redraw === undefined || redraw ) { 60055 60055 api.draw(); 60056 60056 } 60057 60057 60058 60058 return data; 60059 60059 }; 60060 60061 60060 60061 60062 60062 /** 60063 60063 * Restore the table to it's original state in the DOM by removing all of DataTables … … 60078 60078 this.api( true ).destroy( remove ); 60079 60079 }; 60080 60081 60080 60081 60082 60082 /** 60083 60083 * Redraw the table … … 60100 60100 this.api( true ).draw( complete ); 60101 60101 }; 60102 60103 60102 60103 60104 60104 /** 60105 60105 * Filter the input based on data … … 60124 60124 { 60125 60125 var api = this.api( true ); 60126 60126 60127 60127 if ( iColumn === null || iColumn === undefined ) { 60128 60128 api.search( sInput, bRegex, bSmart, bCaseInsensitive ); … … 60131 60131 api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive ); 60132 60132 } 60133 60133 60134 60134 api.draw(); 60135 60135 }; 60136 60137 60136 60137 60138 60138 /** 60139 60139 * Get the data for the whole table, an individual row or an individual cell based on the … … 60176 60176 { 60177 60177 var api = this.api( true ); 60178 60178 60179 60179 if ( src !== undefined ) { 60180 60180 var type = src.nodeName ? src.nodeName.toLowerCase() : ''; 60181 60181 60182 60182 return col !== undefined || type == 'td' || type == 'th' ? 60183 60183 api.cell( src, col ).data() : 60184 60184 api.row( src ).data() || null; 60185 60185 } 60186 60186 60187 60187 return api.data().toArray(); 60188 60188 }; 60189 60190 60189 60190 60191 60191 /** 60192 60192 * Get an array of the TR nodes that are used in the table's body. Note that you will … … 60210 60210 { 60211 60211 var api = this.api( true ); 60212 60212 60213 60213 return iRow !== undefined ? 60214 60214 api.row( iRow ).node() : 60215 60215 api.rows().nodes().flatten().toArray(); 60216 60216 }; 60217 60218 60217 60218 60219 60219 /** 60220 60220 * Get the array indexes of a particular cell from it's DOM element … … 60249 60249 var api = this.api( true ); 60250 60250 var nodeName = node.nodeName.toUpperCase(); 60251 60251 60252 60252 if ( nodeName == 'TR' ) { 60253 60253 return api.row( node ).index(); … … 60255 60255 else if ( nodeName == 'TD' || nodeName == 'TH' ) { 60256 60256 var cell = api.cell( node ).index(); 60257 60257 60258 60258 return [ 60259 60259 cell.row, … … 60264 60264 return null; 60265 60265 }; 60266 60267 60266 60267 60268 60268 /** 60269 60269 * Check to see if a row is 'open' or not. … … 60293 60293 return this.api( true ).row( nTr ).child.isShown(); 60294 60294 }; 60295 60296 60295 60296 60297 60297 /** 60298 60298 * This function will place a new row directly after a row which is currently … … 60333 60333 .child()[0]; 60334 60334 }; 60335 60336 60335 60336 60337 60337 /** 60338 60338 * Change the pagination - provides the internal logic for pagination in a simple API … … 60354 60354 { 60355 60355 var api = this.api( true ).page( mAction ); 60356 60356 60357 60357 if ( bRedraw === undefined || bRedraw ) { 60358 60358 api.draw(false); 60359 60359 } 60360 60360 }; 60361 60362 60361 60362 60363 60363 /** 60364 60364 * Show a particular column … … 60380 60380 { 60381 60381 var api = this.api( true ).column( iCol ).visible( bShow ); 60382 60382 60383 60383 if ( bRedraw === undefined || bRedraw ) { 60384 60384 api.columns.adjust().draw(); 60385 60385 } 60386 60386 }; 60387 60388 60387 60388 60389 60389 /** 60390 60390 * Get the settings for a particular table for external manipulation … … 60407 60407 return _fnSettingsFromNode( this[_ext.iApiIndex] ); 60408 60408 }; 60409 60410 60409 60410 60411 60411 /** 60412 60412 * Sort the table by a particular column … … 60428 60428 this.api( true ).order( aaSort ).draw(); 60429 60429 }; 60430 60431 60430 60431 60432 60432 /** 60433 60433 * Attach a sort listener to an element for a given column … … 60450 60450 this.api( true ).order.listener( nNode, iColumn, fnCallback ); 60451 60451 }; 60452 60453 60452 60453 60454 60454 /** 60455 60455 * Update a table cell or row - this method will accept either a single value to … … 60477 60477 { 60478 60478 var api = this.api( true ); 60479 60479 60480 60480 if ( iColumn === undefined || iColumn === null ) { 60481 60481 api.row( mRow ).data( mData ); … … 60484 60484 api.cell( mRow, iColumn ).data( mData ); 60485 60485 } 60486 60486 60487 60487 if ( bAction === undefined || bAction ) { 60488 60488 api.columns.adjust(); 60489 60489 } 60490 60490 60491 60491 if ( bRedraw === undefined || bRedraw ) { 60492 60492 api.draw(); … … 60494 60494 return 0; 60495 60495 }; 60496 60497 60496 60497 60498 60498 /** 60499 60499 * Provide a common method for plug-ins to check the version of DataTables being used, in order … … 60514 60514 */ 60515 60515 this.fnVersionCheck = _ext.fnVersionCheck; 60516 60516 60517 60517 60518 60518 var _that = this; … … 60547 60547 var defaults = DataTable.defaults; 60548 60548 var $this = $(this); 60549 60550 60549 60550 60551 60551 /* Sanity check */ 60552 60552 if ( this.nodeName.toLowerCase() != 'table' ) … … 60555 60555 return; 60556 60556 } 60557 60557 60558 60558 /* Backwards compatibility for the defaults */ 60559 60559 _fnCompatOpts( defaults ); 60560 60560 _fnCompatCols( defaults.column ); 60561 60561 60562 60562 /* Convert the camel-case defaults to Hungarian */ 60563 60563 _fnCamelToHungarian( defaults, defaults, true ); 60564 60564 _fnCamelToHungarian( defaults.column, defaults.column, true ); 60565 60565 60566 60566 /* Setting up the initialisation object */ 60567 60567 _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true ); 60568 60569 60570 60568 60569 60570 60571 60571 /* Check to see if we are re-initialising a table */ 60572 60572 var allSettings = DataTable.settings; … … 60574 60574 { 60575 60575 var s = allSettings[i]; 60576 60576 60577 60577 /* Base check on table node */ 60578 60578 if ( … … 60583 60583 var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve; 60584 60584 var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy; 60585 60585 60586 60586 if ( emptyInit || bRetrieve ) 60587 60587 { … … 60599 60599 } 60600 60600 } 60601 60601 60602 60602 /* If the element we are initialising has the same ID as a table which was previously 60603 60603 * initialised, but the table nodes don't match (from before) then we destroy the old … … 60611 60611 } 60612 60612 } 60613 60613 60614 60614 /* Ensure the table has an ID - required for accessibility */ 60615 60615 if ( sId === null || sId === "" ) … … 60618 60618 this.id = sId; 60619 60619 } 60620 60620 60621 60621 /* Create the settings object for this table and set some of the default parameters */ 60622 60622 var oSettings = $.extend( true, {}, DataTable.models.oSettings, { … … 60628 60628 oSettings.oApi = _that.internal; 60629 60629 oSettings.oInit = oInit; 60630 60630 60631 60631 allSettings.push( oSettings ); 60632 60632 60633 60633 // Need to add the instance after the instance after the settings object has been added 60634 60634 // to the settings array, so we can self reference the table instance if more than one 60635 60635 oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable(); 60636 60636 60637 60637 // Backwards compatibility, before we apply all the defaults 60638 60638 _fnCompatOpts( oInit ); 60639 60639 _fnLanguageCompat( oInit.oLanguage ); 60640 60640 60641 60641 // If the length menu is given, but the init display length is not, use the length menu 60642 60642 if ( oInit.aLengthMenu && ! oInit.iDisplayLength ) … … 60645 60645 oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0]; 60646 60646 } 60647 60647 60648 60648 // Apply the defaults and init options to make a single init object will all 60649 60649 // options defined from defaults and instance options. 60650 60650 oInit = _fnExtend( $.extend( true, {}, defaults ), oInit ); 60651 60652 60651 60652 60653 60653 // Map the initialisation options onto the settings object 60654 60654 _fnMap( oSettings.oFeatures, oInit, [ … … 60698 60698 ] ); 60699 60699 _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); 60700 60700 60701 60701 /* Callback functions which are array driven */ 60702 60702 _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' ); … … 60711 60711 _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' ); 60712 60712 _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' ); 60713 60713 60714 60714 oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId ); 60715 60715 60716 60716 /* Browser support detection */ 60717 60717 _fnBrowserDetect( oSettings ); 60718 60718 60719 60719 var oClasses = oSettings.oClasses; 60720 60720 60721 60721 $.extend( oClasses, DataTable.ext.classes, oInit.oClasses ); 60722 60722 $this.addClass( oClasses.sTable ); 60723 60724 60723 60724 60725 60725 if ( oSettings.iInitDisplayStart === undefined ) 60726 60726 { … … 60729 60729 oSettings._iDisplayStart = oInit.iDisplayStart; 60730 60730 } 60731 60731 60732 60732 if ( oInit.iDeferLoading !== null ) 60733 60733 { … … 60737 60737 oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading; 60738 60738 } 60739 60739 60740 60740 /* Language definitions */ 60741 60741 var oLanguage = oSettings.oLanguage; 60742 60742 $.extend( true, oLanguage, oInit.oLanguage ); 60743 60743 60744 60744 if ( oLanguage.sUrl ) 60745 60745 { … … 60764 60764 bInitHandedOff = true; 60765 60765 } 60766 60766 60767 60767 /* 60768 60768 * Stripes … … 60775 60775 ]; 60776 60776 } 60777 60777 60778 60778 /* Remove row stripe classes if they are already on the table row */ 60779 60779 var stripeClasses = oSettings.asStripeClasses; … … 60785 60785 oSettings.asDestroyStripes = stripeClasses.slice(); 60786 60786 } 60787 60787 60788 60788 /* 60789 60789 * Columns … … 60798 60798 anThs = _fnGetUniqueThs( oSettings ); 60799 60799 } 60800 60800 60801 60801 /* If not given a column array, generate one with nulls */ 60802 60802 if ( oInit.aoColumns === null ) … … 60812 60812 aoColumnsInit = oInit.aoColumns; 60813 60813 } 60814 60814 60815 60815 /* Add the columns */ 60816 60816 for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ ) … … 60818 60818 _fnAddColumn( oSettings, anThs ? anThs[i] : null ); 60819 60819 } 60820 60820 60821 60821 /* Apply the column definitions */ 60822 60822 _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) { 60823 60823 _fnColumnOptions( oSettings, iCol, oDef ); 60824 60824 } ); 60825 60825 60826 60826 /* HTML5 attribute detection - build an mData object automatically if the 60827 60827 * attributes are found … … 60831 60831 return cell.getAttribute( 'data-'+name ) !== null ? name : null; 60832 60832 }; 60833 60833 60834 60834 $( rowOne[0] ).children('th, td').each( function (i, cell) { 60835 60835 var col = oSettings.aoColumns[i]; 60836 60836 60837 60837 if ( col.mData === i ) { 60838 60838 var sort = a( cell, 'sort' ) || a( cell, 'order' ); 60839 60839 var filter = a( cell, 'filter' ) || a( cell, 'search' ); 60840 60840 60841 60841 if ( sort !== null || filter !== null ) { 60842 60842 col.mData = { … … 60846 60846 filter: filter !== null ? i+'.@data-'+filter : undefined 60847 60847 }; 60848 60848 60849 60849 _fnColumnOptions( oSettings, i ); 60850 60850 } … … 60852 60852 } ); 60853 60853 } 60854 60854 60855 60855 var features = oSettings.oFeatures; 60856 60856 var loadedInit = function () { … … 60859 60859 * @todo For modularisation (1.11) this needs to do into a sort start up handler 60860 60860 */ 60861 60861 60862 60862 // If aaSorting is not defined, then we use the first indicator in asSorting 60863 60863 // in case that has been altered, so the default sort reflects that option … … 60868 60868 } 60869 60869 } 60870 60870 60871 60871 /* Do a first pass on the sorting classes (allows any size changes to be taken into 60872 60872 * account, and also will apply sorting disabled classes if disabled 60873 60873 */ 60874 60874 _fnSortingClasses( oSettings ); 60875 60875 60876 60876 if ( features.bSort ) { 60877 60877 _fnCallbackReg( oSettings, 'aoDrawCallback', function () { … … 60879 60879 var aSort = _fnSortFlatten( oSettings ); 60880 60880 var sortedColumns = {}; 60881 60881 60882 60882 $.each( aSort, function (i, val) { 60883 60883 sortedColumns[ val.src ] = val.dir; 60884 60884 } ); 60885 60885 60886 60886 _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] ); 60887 60887 _fnSortAria( oSettings ); … … 60889 60889 } ); 60890 60890 } 60891 60891 60892 60892 _fnCallbackReg( oSettings, 'aoDrawCallback', function () { 60893 60893 if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) { … … 60895 60895 } 60896 60896 }, 'sc' ); 60897 60898 60897 60898 60899 60899 /* 60900 60900 * Final init 60901 60901 * Cache the header, body and footer as required, creating them if needed 60902 60902 */ 60903 60903 60904 60904 // Work around for Webkit bug 83867 - store the caption-side before removing from doc 60905 60905 var captions = $this.children('caption').each( function () { 60906 60906 this._captionSide = $(this).css('caption-side'); 60907 60907 } ); 60908 60908 60909 60909 var thead = $this.children('thead'); 60910 60910 if ( thead.length === 0 ) { … … 60912 60912 } 60913 60913 oSettings.nTHead = thead[0]; 60914 60914 60915 60915 var tbody = $this.children('tbody'); 60916 60916 if ( tbody.length === 0 ) { … … 60918 60918 } 60919 60919 oSettings.nTBody = tbody[0]; 60920 60920 60921 60921 var tfoot = $this.children('tfoot'); 60922 60922 if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) { … … 60925 60925 tfoot = $('<tfoot/>').appendTo($this); 60926 60926 } 60927 60927 60928 60928 if ( tfoot.length === 0 || tfoot.children().length === 0 ) { 60929 60929 $this.addClass( oClasses.sNoFooter ); … … 60933 60933 _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot ); 60934 60934 } 60935 60935 60936 60936 /* Check if there is data passing into the constructor */ 60937 60937 if ( oInit.aaData ) { … … 60947 60947 _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') ); 60948 60948 } 60949 60949 60950 60950 /* Copy the data index array */ 60951 60951 oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); 60952 60952 60953 60953 /* Initialisation complete - table can be drawn */ 60954 60954 oSettings.bInitialised = true; 60955 60955 60956 60956 /* Check if we need to initialise the table (it might not have been handed off to the 60957 60957 * language processor) … … 60961 60961 } 60962 60962 }; 60963 60963 60964 60964 /* Must be done after everything which can be overridden by the state saving! */ 60965 60965 if ( oInit.bStateSave ) … … 60972 60972 loadedInit(); 60973 60973 } 60974 60974 60975 60975 } ); 60976 60976 _that = null; … … 60978 60978 }; 60979 60979 60980 60980 60981 60981 /* 60982 60982 * It is useful to have variables which are scoped locally so only the … … 60987 60987 * clashing of variable names and that they can easily referenced for reuse. 60988 60988 */ 60989 60990 60989 60990 60991 60991 // Defined else where 60992 60992 // _selector_run … … 60994 60994 // _selector_first 60995 60995 // _selector_row_indexes 60996 60996 60997 60997 var _ext; // DataTable.ext 60998 60998 var _Api; // DataTable.Api 60999 60999 var _api_register; // DataTable.Api.register 61000 61000 var _api_registerPlural; // DataTable.Api.registerPlural 61001 61001 61002 61002 var _re_dic = {}; 61003 61003 var _re_new_lines = /[\r\n\u2028]/g; 61004 61004 var _re_html = /<.*?>/g; 61005 61005 61006 61006 // This is not strict ISO8601 - Date.parse() is quite lax, although 61007 61007 // implementations differ between browsers. 61008 61008 var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/; 61009 61009 61010 61010 // Escape regular expression special characters 61011 61011 var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); 61012 61012 61013 61013 // http://en.wikipedia.org/wiki/Foreign_exchange_market 61014 61014 // - \u20BD - Russian ruble. … … 61024 61024 // standards as thousands separators. 61025 61025 var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi; 61026 61027 61026 61027 61028 61028 var _empty = function ( d ) { 61029 61029 return !d || d === true || d === '-' ? true : false; 61030 61030 }; 61031 61032 61031 61032 61033 61033 var _intVal = function ( s ) { 61034 61034 var integer = parseInt( s, 10 ); 61035 61035 return !isNaN(integer) && isFinite(s) ? integer : null; 61036 61036 }; 61037 61037 61038 61038 // Convert from a formatted number with characters other than `.` as the 61039 61039 // decimal place, to a Javascript number … … 61047 61047 num; 61048 61048 }; 61049 61050 61049 61050 61051 61051 var _isNumber = function ( d, decimalPoint, formatted ) { 61052 61052 var strType = typeof d === 'string'; 61053 61053 61054 61054 // If empty return immediately so there must be a number if it is a 61055 61055 // formatted string (this stops the string "k", or "kr", etc being detected … … 61058 61058 return true; 61059 61059 } 61060 61060 61061 61061 if ( decimalPoint && strType ) { 61062 61062 d = _numToDecimal( d, decimalPoint ); 61063 61063 } 61064 61064 61065 61065 if ( formatted && strType ) { 61066 61066 d = d.replace( _re_formatted_numeric, '' ); 61067 61067 } 61068 61068 61069 61069 return !isNaN( parseFloat(d) ) && isFinite( d ); 61070 61070 }; 61071 61072 61071 61072 61073 61073 // A string without HTML in it can be considered to be HTML still 61074 61074 var _isHtml = function ( d ) { 61075 61075 return _empty( d ) || typeof d === 'string'; 61076 61076 }; 61077 61078 61077 61078 61079 61079 var _htmlNumeric = function ( d, decimalPoint, formatted ) { 61080 61080 if ( _empty( d ) ) { 61081 61081 return true; 61082 61082 } 61083 61083 61084 61084 var html = _isHtml( d ); 61085 61085 return ! html ? … … 61089 61089 null; 61090 61090 }; 61091 61092 61091 61092 61093 61093 var _pluck = function ( a, prop, prop2 ) { 61094 61094 var out = []; 61095 61095 var i=0, ien=a.length; 61096 61096 61097 61097 // Could have the test in the loop for slightly smaller code, but speed 61098 61098 // is essential here … … 61111 61111 } 61112 61112 } 61113 61113 61114 61114 return out; 61115 61115 }; 61116 61117 61116 61117 61118 61118 // Basically the same as _pluck, but rather than looping over `a` we use `order` 61119 61119 // as the indexes to pick from `a` … … 61122 61122 var out = []; 61123 61123 var i=0, ien=order.length; 61124 61124 61125 61125 // Could have the test in the loop for slightly smaller code, but speed 61126 61126 // is essential here … … 61137 61137 } 61138 61138 } 61139 61139 61140 61140 return out; 61141 61141 }; 61142 61143 61142 61143 61144 61144 var _range = function ( len, start ) 61145 61145 { 61146 61146 var out = []; 61147 61147 var end; 61148 61148 61149 61149 if ( start === undefined ) { 61150 61150 start = 0; … … 61155 61155 start = len; 61156 61156 } 61157 61157 61158 61158 for ( var i=start ; i<end ; i++ ) { 61159 61159 out.push( i ); 61160 61160 } 61161 61161 61162 61162 return out; 61163 61163 }; 61164 61165 61164 61165 61166 61166 var _removeEmpty = function ( a ) 61167 61167 { 61168 61168 var out = []; 61169 61169 61170 61170 for ( var i=0, ien=a.length ; i<ien ; i++ ) { 61171 61171 if ( a[i] ) { // careful - will remove all falsy values! … … 61173 61173 } 61174 61174 } 61175 61175 61176 61176 return out; 61177 61177 }; 61178 61179 61178 61179 61180 61180 var _stripHtml = function ( d ) { 61181 61181 return d.replace( _re_html, '' ); 61182 61182 }; 61183 61184 61183 61184 61185 61185 /** 61186 61186 * Determine if all values in the array are unique. This means we can short … … 61196 61196 return true; 61197 61197 } 61198 61198 61199 61199 var sorted = src.slice().sort(); 61200 61200 var last = sorted[0]; 61201 61201 61202 61202 for ( var i=1, ien=sorted.length ; i<ien ; i++ ) { 61203 61203 if ( sorted[i] === last ) { 61204 61204 return false; 61205 61205 } 61206 61206 61207 61207 last = sorted[i]; 61208 61208 } 61209 61209 61210 61210 return true; 61211 61211 }; 61212 61213 61212 61213 61214 61214 /** 61215 61215 * Find the unique elements in a source array. … … 61224 61224 return src.slice(); 61225 61225 } 61226 61226 61227 61227 // A faster unique method is to use object keys to identify used values, 61228 61228 // but this doesn't work with arrays or objects, which we must also … … 61234 61234 i, ien=src.length, 61235 61235 j, k=0; 61236 61236 61237 61237 again: for ( i=0 ; i<ien ; i++ ) { 61238 61238 val = src[i]; 61239 61239 61240 61240 for ( j=0 ; j<k ; j++ ) { 61241 61241 if ( out[j] === val ) { … … 61243 61243 } 61244 61244 } 61245 61245 61246 61246 out.push( val ); 61247 61247 k++; 61248 61248 } 61249 61249 61250 61250 return out; 61251 61251 }; 61252 61253 61252 61253 61254 61254 /** 61255 61255 * DataTables utility methods 61256 * 61256 * 61257 61257 * This namespace provides helper methods that DataTables uses internally to 61258 61258 * create a DataTable, but which are not exclusively used only for DataTables. … … 61276 61276 last, 61277 61277 timer; 61278 61278 61279 61279 return function () { 61280 61280 var … … 61282 61282 now = +new Date(), 61283 61283 args = arguments; 61284 61284 61285 61285 if ( last && now < last + frequency ) { 61286 61286 clearTimeout( timer ); 61287 61287 61288 61288 timer = setTimeout( function () { 61289 61289 last = undefined; … … 61297 61297 }; 61298 61298 }, 61299 61300 61299 61300 61301 61301 /** 61302 61302 * Escape a string such that it can be used in a regular expression … … 61309 61309 } 61310 61310 }; 61311 61312 61313 61311 61312 61313 61314 61314 /** 61315 61315 * Create a mapping object that allows camel case parameters to be looked up … … 61326 61326 newKey, 61327 61327 map = {}; 61328 61328 61329 61329 $.each( o, function (key, val) { 61330 61330 match = key.match(/^([^A-Z]+?)([A-Z])/); 61331 61331 61332 61332 if ( match && hungarian.indexOf(match[1]+' ') !== -1 ) 61333 61333 { 61334 61334 newKey = key.replace( match[0], match[2].toLowerCase() ); 61335 61335 map[ newKey ] = key; 61336 61336 61337 61337 if ( match[1] === 'o' ) 61338 61338 { … … 61341 61341 } 61342 61342 } ); 61343 61343 61344 61344 o._hungarianMap = map; 61345 61345 } 61346 61347 61346 61347 61348 61348 /** 61349 61349 * Convert from camel case parameters to Hungarian, based on a Hungarian map … … 61362 61362 _fnHungarianMap( src ); 61363 61363 } 61364 61364 61365 61365 var hungarianKey; 61366 61366 61367 61367 $.each( user, function (key, val) { 61368 61368 hungarianKey = src._hungarianMap[ key ]; 61369 61369 61370 61370 if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) ) 61371 61371 { … … 61378 61378 } 61379 61379 $.extend( true, user[hungarianKey], user[key] ); 61380 61380 61381 61381 _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force ); 61382 61382 } … … 61387 61387 } ); 61388 61388 } 61389 61390 61389 61390 61391 61391 /** 61392 61392 * Language compatibility - when certain options are given, and others aren't, we … … 61401 61401 // this is called after the mapping of camelCase to Hungarian 61402 61402 var defaults = DataTable.defaults.oLanguage; 61403 61403 61404 61404 // Default mapping 61405 61405 var defaultDecimal = defaults.sDecimal; … … 61407 61407 _addNumericSort( defaultDecimal ); 61408 61408 } 61409 61409 61410 61410 if ( lang ) { 61411 61411 var zeroRecords = lang.sZeroRecords; 61412 61412 61413 61413 // Backwards compatibility - if there is no sEmptyTable given, then use the same as 61414 61414 // sZeroRecords - assuming that is given. … … 61418 61418 _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' ); 61419 61419 } 61420 61420 61421 61421 // Likewise with loading records 61422 61422 if ( ! lang.sLoadingRecords && zeroRecords && … … 61425 61425 _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' ); 61426 61426 } 61427 61427 61428 61428 // Old parameter name of the thousands separator mapped onto the new 61429 61429 if ( lang.sInfoThousands ) { 61430 61430 lang.sThousands = lang.sInfoThousands; 61431 61431 } 61432 61432 61433 61433 var decimal = lang.sDecimal; 61434 61434 if ( decimal && defaultDecimal !== decimal ) { … … 61437 61437 } 61438 61438 } 61439 61440 61439 61440 61441 61441 /** 61442 61442 * Map one parameter onto another … … 61450 61450 } 61451 61451 }; 61452 61453 61452 61453 61454 61454 /** 61455 61455 * Provide backwards compatibility for the main DT options. Note that the new … … 61470 61470 _fnCompatMap( init, 'pageLength', 'iDisplayLength' ); 61471 61471 _fnCompatMap( init, 'searching', 'bFilter' ); 61472 61472 61473 61473 // Boolean initialisation of x-scrolling 61474 61474 if ( typeof init.sScrollX === 'boolean' ) { … … 61478 61478 init.scrollX = init.scrollX ? '100%' : ''; 61479 61479 } 61480 61480 61481 61481 // Column search objects are in an array, so it needs to be converted 61482 61482 // element by element 61483 61483 var searchCols = init.aoSearchCols; 61484 61484 61485 61485 if ( searchCols ) { 61486 61486 for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) { … … 61491 61491 } 61492 61492 } 61493 61494 61493 61494 61495 61495 /** 61496 61496 * Provide backwards compatibility for column options. Note that the new options … … 61505 61505 _fnCompatMap( init, 'orderSequence', 'asSorting' ); 61506 61506 _fnCompatMap( init, 'orderDataType', 'sortDataType' ); 61507 61507 61508 61508 // orderData can be given as an integer 61509 61509 var dataSort = init.aDataSort; … … 61512 61512 } 61513 61513 } 61514 61515 61514 61515 61516 61516 /** 61517 61517 * Browser feature detection for capabilities, quirks … … 61527 61527 var browser = {}; 61528 61528 DataTable.__browser = browser; 61529 61529 61530 61530 // Scrolling feature / quirks detection 61531 61531 var n = $('<div/>') … … 61556 61556 ) 61557 61557 .appendTo( 'body' ); 61558 61558 61559 61559 var outer = n.children(); 61560 61560 var inner = outer.children(); 61561 61561 61562 61562 // Numbers below, in order, are: 61563 61563 // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth … … 61569 61569 // Evergreen Mac with scrollbars: 85 85 100 85 61570 61570 // Evergreen Mac without scrollbars: 100 100 100 100 61571 61571 61572 61572 // Get scrollbar width 61573 61573 browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth; 61574 61574 61575 61575 // IE6/7 will oversize a width 100% element inside a scrolling element, to 61576 61576 // include the width of the scrollbar, while other browsers ensure the inner 61577 61577 // element is contained without forcing scrolling 61578 61578 browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100; 61579 61579 61580 61580 // In rtl text layout, some browsers (most, but not all) will place the 61581 61581 // scrollbar on the left, rather than the right. 61582 61582 browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1; 61583 61583 61584 61584 // IE8- don't provide height and width for getBoundingClientRect 61585 61585 browser.bBounding = n[0].getBoundingClientRect().width ? true : false; 61586 61586 61587 61587 n.remove(); 61588 61588 } 61589 61589 61590 61590 $.extend( settings.oBrowser, DataTable.__browser ); 61591 61591 settings.oScroll.iBarWidth = DataTable.__browser.barWidth; 61592 61592 } 61593 61594 61593 61594 61595 61595 /** 61596 61596 * Array.prototype reduce[Right] method, used for browsers which don't support … … 61605 61605 value, 61606 61606 isSet = false; 61607 61607 61608 61608 if ( init !== undefined ) { 61609 61609 value = init; 61610 61610 isSet = true; 61611 61611 } 61612 61612 61613 61613 while ( i !== end ) { 61614 61614 if ( ! that.hasOwnProperty(i) ) { 61615 61615 continue; 61616 61616 } 61617 61617 61618 61618 value = isSet ? 61619 61619 fn( value, that[i], i, that ) : 61620 61620 that[i]; 61621 61621 61622 61622 isSet = true; 61623 61623 i += inc; 61624 61624 } 61625 61625 61626 61626 return value; 61627 61627 } 61628 61628 61629 61629 /** 61630 61630 * Add a column to the list used for the table with default values … … 61646 61646 } ); 61647 61647 oSettings.aoColumns.push( oCol ); 61648 61648 61649 61649 // Add search object for column specific search. Note that the `searchCols[ iCol ]` 61650 61650 // passed into extend can be undefined. This allows the user to give a default … … 61652 61652 var searchCols = oSettings.aoPreSearchCols; 61653 61653 searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] ); 61654 61654 61655 61655 // Use the default column options function to initialise classes etc 61656 61656 _fnColumnOptions( oSettings, iCol, $(nTh).data() ); 61657 61657 } 61658 61659 61658 61659 61660 61660 /** 61661 61661 * Apply options for a column … … 61670 61670 var oClasses = oSettings.oClasses; 61671 61671 var th = $(oCol.nTh); 61672 61672 61673 61673 // Try to get width information from the DOM. We can't get it from CSS 61674 61674 // as we'd need to parse the CSS stylesheet. `width` option can override … … 61676 61676 // Width attribute 61677 61677 oCol.sWidthOrig = th.attr('width') || null; 61678 61678 61679 61679 // Style attribute 61680 61680 var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/); … … 61683 61683 } 61684 61684 } 61685 61685 61686 61686 /* User specified column options */ 61687 61687 if ( oOptions !== undefined && oOptions !== null ) … … 61689 61689 // Backwards compatibility 61690 61690 _fnCompatCols( oOptions ); 61691 61691 61692 61692 // Map camel case parameters to their Hungarian counterparts 61693 61693 _fnCamelToHungarian( DataTable.defaults.column, oOptions, true ); 61694 61694 61695 61695 /* Backwards compatibility for mDataProp */ 61696 61696 if ( oOptions.mDataProp !== undefined && !oOptions.mData ) … … 61698 61698 oOptions.mData = oOptions.mDataProp; 61699 61699 } 61700 61700 61701 61701 if ( oOptions.sType ) 61702 61702 { 61703 61703 oCol._sManualType = oOptions.sType; 61704 61704 } 61705 61705 61706 61706 // `class` is a reserved word in Javascript, so we need to provide 61707 61707 // the ability to use a valid name for the camel case input … … 61713 61713 th.addClass( oOptions.sClass ); 61714 61714 } 61715 61715 61716 61716 $.extend( oCol, oOptions ); 61717 61717 _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); 61718 61718 61719 61719 /* iDataSort to be applied (backwards compatibility), but aDataSort will take 61720 61720 * priority if defined … … 61726 61726 _fnMap( oCol, oOptions, "aDataSort" ); 61727 61727 } 61728 61728 61729 61729 /* Cache the data get and set functions for speed */ 61730 61730 var mDataSrc = oCol.mData; 61731 61731 var mData = _fnGetObjectDataFn( mDataSrc ); 61732 61732 var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; 61733 61733 61734 61734 var attrTest = function( src ) { 61735 61735 return typeof src === 'string' && src.indexOf('@') !== -1; … … 61739 61739 ); 61740 61740 oCol._setter = null; 61741 61741 61742 61742 oCol.fnGetData = function (rowData, type, meta) { 61743 61743 var innerData = mData( rowData, type, undefined, meta ); 61744 61744 61745 61745 return mRender && type ? 61746 61746 mRender( innerData, type, rowData, meta ) : … … 61750 61750 return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta ); 61751 61751 }; 61752 61752 61753 61753 // Indicate if DataTables should read DOM data as an object or array 61754 61754 // Used in _fnGetRowElements … … 61756 61756 oSettings._rowReadObject = true; 61757 61757 } 61758 61758 61759 61759 /* Feature sorting overrides column specific when off */ 61760 61760 if ( !oSettings.oFeatures.bSort ) … … 61763 61763 th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called 61764 61764 } 61765 61765 61766 61766 /* Check that the class assignment is correct for sorting */ 61767 61767 var bAsc = $.inArray('asc', oCol.asSorting) !== -1; … … 61788 61788 } 61789 61789 } 61790 61791 61790 61791 61792 61792 /** 61793 61793 * Adjust the table column widths for new data. Note: you would probably want to … … 61802 61802 { 61803 61803 var columns = settings.aoColumns; 61804 61804 61805 61805 _fnCalculateColumnWidths( settings ); 61806 61806 for ( var i=0 , iLen=columns.length ; i<iLen ; i++ ) … … 61809 61809 } 61810 61810 } 61811 61811 61812 61812 var scroll = settings.oScroll; 61813 61813 if ( scroll.sY !== '' || scroll.sX !== '') … … 61815 61815 _fnScrollDraw( settings ); 61816 61816 } 61817 61817 61818 61818 _fnCallbackFire( settings, null, 'column-sizing', [settings] ); 61819 61819 } 61820 61821 61820 61821 61822 61822 /** 61823 61823 * Covert the index of a visible column to the index in the data array (take account … … 61831 61831 { 61832 61832 var aiVis = _fnGetColumns( oSettings, 'bVisible' ); 61833 61833 61834 61834 return typeof aiVis[iMatch] === 'number' ? 61835 61835 aiVis[iMatch] : 61836 61836 null; 61837 61837 } 61838 61839 61838 61839 61840 61840 /** 61841 61841 * Covert the index of an index in the data array and convert it to the visible … … 61850 61850 var aiVis = _fnGetColumns( oSettings, 'bVisible' ); 61851 61851 var iPos = $.inArray( iMatch, aiVis ); 61852 61852 61853 61853 return iPos !== -1 ? iPos : null; 61854 61854 } 61855 61856 61855 61856 61857 61857 /** 61858 61858 * Get the number of visible columns … … 61864 61864 { 61865 61865 var vis = 0; 61866 61866 61867 61867 // No reduce in IE8, use a loop for now 61868 61868 $.each( oSettings.aoColumns, function ( i, col ) { … … 61871 61871 } 61872 61872 } ); 61873 61873 61874 61874 return vis; 61875 61875 } 61876 61877 61876 61877 61878 61878 /** 61879 61879 * Get an array of column indexes that match a given property … … 61887 61887 { 61888 61888 var a = []; 61889 61889 61890 61890 $.map( oSettings.aoColumns, function(val, i) { 61891 61891 if ( val[sParam] ) { … … 61893 61893 } 61894 61894 } ); 61895 61895 61896 61896 return a; 61897 61897 } 61898 61899 61898 61899 61900 61900 /** 61901 61901 * Calculate the 'type' of a column … … 61910 61910 var i, ien, j, jen, k, ken; 61911 61911 var col, cell, detectedType, cache; 61912 61913 // For each column, spin over the 61912 61913 // For each column, spin over the 61914 61914 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 61915 61915 col = columns[i]; 61916 61916 cache = []; 61917 61917 61918 61918 if ( ! col.sType && col._sManualType ) { 61919 61919 col.sType = col._sManualType; … … 61927 61927 cache[k] = _fnGetCellData( settings, k, i, 'type' ); 61928 61928 } 61929 61929 61930 61930 detectedType = types[j]( cache[k], settings ); 61931 61931 61932 61932 // If null, then this type can't apply to this column, so 61933 61933 // rather than testing all cells, break out. There is an … … 61938 61938 break; 61939 61939 } 61940 61940 61941 61941 // Only a single match is needed for html type since it is 61942 61942 // bottom of the pile and very similar to string … … 61945 61945 } 61946 61946 } 61947 61947 61948 61948 // Type is valid for all data points in the column - use this 61949 61949 // type … … 61953 61953 } 61954 61954 } 61955 61955 61956 61956 // Fall back - if no type was detected, always use string 61957 61957 if ( ! col.sType ) { … … 61961 61961 } 61962 61962 } 61963 61964 61963 61964 61965 61965 /** 61966 61966 * Take the column definitions and static columns arrays and calculate how … … 61978 61978 var i, iLen, j, jLen, k, kLen, def; 61979 61979 var columns = oSettings.aoColumns; 61980 61980 61981 61981 // Column definitions with aTargets 61982 61982 if ( aoColDefs ) … … 61986 61986 { 61987 61987 def = aoColDefs[i]; 61988 61988 61989 61989 /* Each definition can target multiple columns, as it is an array */ 61990 61990 var aTargets = def.targets !== undefined ? 61991 61991 def.targets : 61992 61992 def.aTargets; 61993 61993 61994 61994 if ( ! $.isArray( aTargets ) ) 61995 61995 { 61996 61996 aTargets = [ aTargets ]; 61997 61997 } 61998 61998 61999 61999 for ( j=0, jLen=aTargets.length ; j<jLen ; j++ ) 62000 62000 { … … 62006 62006 _fnAddColumn( oSettings ); 62007 62007 } 62008 62008 62009 62009 /* Integer, basic index */ 62010 62010 fn( aTargets[j], def ); … … 62030 62030 } 62031 62031 } 62032 62032 62033 62033 // Statically defined columns array 62034 62034 if ( aoCols ) … … 62040 62040 } 62041 62041 } 62042 62042 62043 62043 /** 62044 62044 * Add a data array to the table, creating DOM node etc. This is the parallel to … … 62062 62062 idx: iRow 62063 62063 } ); 62064 62064 62065 62065 oData._aData = aDataIn; 62066 62066 oSettings.aoData.push( oData ); 62067 62067 62068 62068 /* Create the cells */ 62069 62069 var nTd, sThisType; 62070 62070 var columns = oSettings.aoColumns; 62071 62071 62072 62072 // Invalidate the column types as the new data needs to be revalidated 62073 62073 for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) … … 62075 62075 columns[i].sType = null; 62076 62076 } 62077 62077 62078 62078 /* Add to the display array */ 62079 62079 oSettings.aiDisplayMaster.push( iRow ); 62080 62080 62081 62081 var id = oSettings.rowIdFn( aDataIn ); 62082 62082 if ( id !== undefined ) { 62083 62083 oSettings.aIds[ id ] = oData; 62084 62084 } 62085 62085 62086 62086 /* Create the DOM information, or register it if already present */ 62087 62087 if ( nTr || ! oSettings.oFeatures.bDeferRender ) … … 62089 62089 _fnCreateTr( oSettings, iRow, nTr, anTds ); 62090 62090 } 62091 62091 62092 62092 return iRow; 62093 62093 } 62094 62095 62094 62095 62096 62096 /** 62097 62097 * Add one or more TR elements to the table. Generally we'd expect to … … 62107 62107 { 62108 62108 var row; 62109 62109 62110 62110 // Allow an individual node to be passed in 62111 62111 if ( ! (trs instanceof $) ) { 62112 62112 trs = $(trs); 62113 62113 } 62114 62114 62115 62115 return trs.map( function (i, el) { 62116 62116 row = _fnGetRowElements( settings, el ); … … 62118 62118 } ); 62119 62119 } 62120 62121 62120 62121 62122 62122 /** 62123 62123 * Take a TR element and convert it to an index in aoData … … 62131 62131 return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null; 62132 62132 } 62133 62134 62133 62134 62135 62135 /** 62136 62136 * Take a TD element and convert it into a column data index (not the visible index) … … 62145 62145 return $.inArray( n, oSettings.aoData[ iRow ].anCells ); 62146 62146 } 62147 62148 62147 62148 62149 62149 /** 62150 62150 * Get the data for a given cell from the internal cache, taking into account data mapping … … 62167 62167 col: colIdx 62168 62168 } ); 62169 62169 62170 62170 if ( cellData === undefined ) { 62171 62171 if ( settings.iDrawError != draw && defaultContent === null ) { … … 62177 62177 return defaultContent; 62178 62178 } 62179 62179 62180 62180 // When the data source is null and a specific data type is requested (i.e. 62181 62181 // not the original data), we can use default column data … … 62188 62188 return cellData.call( rowData ); 62189 62189 } 62190 62190 62191 62191 if ( cellData === null && type == 'display' ) { 62192 62192 return ''; … … 62194 62194 return cellData; 62195 62195 } 62196 62197 62196 62197 62198 62198 /** 62199 62199 * Set the value for a specific cell, into the internal data cache … … 62208 62208 var col = settings.aoColumns[colIdx]; 62209 62209 var rowData = settings.aoData[rowIdx]._aData; 62210 62210 62211 62211 col.fnSetData( rowData, val, { 62212 62212 settings: settings, … … 62215 62215 } ); 62216 62216 } 62217 62218 62217 62218 62219 62219 // Private variable that is used to match action syntax in the data property object 62220 62220 var __reArray = /\[.*?\]$/; 62221 62221 var __reFn = /\(\)$/; 62222 62222 62223 62223 /** 62224 62224 * Split string on periods, taking into account escaped periods … … 62232 62232 } ); 62233 62233 } 62234 62235 62234 62235 62236 62236 /** 62237 62237 * Return a function that can be used to get data from a source object, taking … … 62252 62252 } 62253 62253 } ); 62254 62254 62255 62255 return function (data, type, row, meta) { 62256 62256 var t = o[type] || o._; … … 62284 62284 var fetchData = function (data, type, src) { 62285 62285 var arrayNotation, funcNotation, out, innerSrc; 62286 62286 62287 62287 if ( src !== "" ) 62288 62288 { 62289 62289 var a = _fnSplitObjNotation( src ); 62290 62290 62291 62291 for ( var i=0, iLen=a.length ; i<iLen ; i++ ) 62292 62292 { … … 62294 62294 arrayNotation = a[i].match(__reArray); 62295 62295 funcNotation = a[i].match(__reFn); 62296 62296 62297 62297 if ( arrayNotation ) 62298 62298 { 62299 62299 // Array notation 62300 62300 a[i] = a[i].replace(__reArray, ''); 62301 62301 62302 62302 // Condition allows simply [] to be passed in 62303 62303 if ( a[i] !== "" ) { … … 62305 62305 } 62306 62306 out = []; 62307 62307 62308 62308 // Get the remainder of the nested object to get 62309 62309 a.splice( 0, i+1 ); 62310 62310 innerSrc = a.join('.'); 62311 62311 62312 62312 // Traverse each entry in the array getting the properties requested 62313 62313 if ( $.isArray( data ) ) { … … 62316 62316 } 62317 62317 } 62318 62318 62319 62319 // If a string is given in between the array notation indicators, that 62320 62320 // is used to join the strings together, otherwise an array is returned 62321 62321 var join = arrayNotation[0].substring(1, arrayNotation[0].length-1); 62322 62322 data = (join==="") ? out : out.join(join); 62323 62323 62324 62324 // The inner call to fetchData has already traversed through the remainder 62325 62325 // of the source requested, so we exit from the loop … … 62333 62333 continue; 62334 62334 } 62335 62335 62336 62336 if ( data === null || data[ a[i] ] === undefined ) 62337 62337 { … … 62341 62341 } 62342 62342 } 62343 62343 62344 62344 return data; 62345 62345 }; 62346 62346 62347 62347 return function (data, type) { // row and meta also passed, but not used 62348 62348 return fetchData( data, type, mSource ); … … 62357 62357 } 62358 62358 } 62359 62360 62359 62360 62361 62361 /** 62362 62362 * Return a function that can be used to set data from a source object, taking … … 62396 62396 var aLast = a[a.length-1]; 62397 62397 var arrayNotation, funcNotation, o, innerSrc; 62398 62398 62399 62399 for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ ) 62400 62400 { … … 62402 62402 arrayNotation = a[i].match(__reArray); 62403 62403 funcNotation = a[i].match(__reFn); 62404 62404 62405 62405 if ( arrayNotation ) 62406 62406 { 62407 62407 a[i] = a[i].replace(__reArray, ''); 62408 62408 data[ a[i] ] = []; 62409 62409 62410 62410 // Get the remainder of the nested object to set so we can recurse 62411 62411 b = a.slice(); 62412 62412 b.splice( 0, i+1 ); 62413 62413 innerSrc = b.join('.'); 62414 62414 62415 62415 // Traverse each entry in the array setting the properties requested 62416 62416 if ( $.isArray( val ) ) … … 62430 62430 data[ a[i] ] = val; 62431 62431 } 62432 62432 62433 62433 // The inner call to setData has already traversed through the remainder 62434 62434 // of the source and has set the data, thus we can exit here … … 62441 62441 data = data[ a[i] ]( val ); 62442 62442 } 62443 62443 62444 62444 // If the nested object doesn't currently exist - since we are 62445 62445 // trying to set the value - create it … … 62450 62450 data = data[ a[i] ]; 62451 62451 } 62452 62452 62453 62453 // Last item in the input - i.e, the actual set 62454 62454 if ( aLast.match(__reFn ) ) … … 62464 62464 } 62465 62465 }; 62466 62466 62467 62467 return function (data, val) { // meta is also passed in, but not used 62468 62468 return setData( data, val, mSource ); … … 62477 62477 } 62478 62478 } 62479 62480 62479 62480 62481 62481 /** 62482 62482 * Return an array with the full table data … … 62489 62489 return _pluck( settings.aoData, '_aData' ); 62490 62490 } 62491 62492 62491 62492 62493 62493 /** 62494 62494 * Nuke the table … … 62503 62503 settings.aIds = {}; 62504 62504 } 62505 62506 62505 62506 62507 62507 /** 62508 62508 * Take an array of integers (index array) and remove a target integer (value - not … … 62515 62515 { 62516 62516 var iTargetIndex = -1; 62517 62517 62518 62518 for ( var i=0, iLen=a.length ; i<iLen ; i++ ) 62519 62519 { … … 62527 62527 } 62528 62528 } 62529 62529 62530 62530 if ( iTargetIndex != -1 && splice === undefined ) 62531 62531 { … … 62533 62533 } 62534 62534 } 62535 62536 62535 62536 62537 62537 /** 62538 62538 * Mark cached data as invalid such that a re-read of the data will occur when … … 62562 62562 cell.removeChild( cell.firstChild ); 62563 62563 } 62564 62564 62565 62565 cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' ); 62566 62566 }; 62567 62567 62568 62568 // Are we reading last data from DOM or the data object? 62569 62569 if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) { … … 62577 62577 // Reading from data object, update the DOM 62578 62578 var cells = row.anCells; 62579 62579 62580 62580 if ( cells ) { 62581 62581 if ( colIdx !== undefined ) { … … 62589 62589 } 62590 62590 } 62591 62591 62592 62592 // For both row and cell invalidation, the cached data for sorting and 62593 62593 // filtering is nulled out 62594 62594 row._aSortData = null; 62595 62595 row._aFilterData = null; 62596 62596 62597 62597 // Invalidate the type for a specific column (if given) or all columns since 62598 62598 // the data might have changed … … 62605 62605 cols[i].sType = null; 62606 62606 } 62607 62607 62608 62608 // Update DataTables special `DT_*` attributes for the row 62609 62609 _fnRowAttributes( settings, row ); 62610 62610 } 62611 62611 } 62612 62613 62612 62613 62614 62614 /** 62615 62615 * Build a data source object from an HTML row, reading the contents of the … … 62637 62637 columns = settings.aoColumns, 62638 62638 objectRead = settings._rowReadObject; 62639 62639 62640 62640 // Allow the data object to be passed in, or construct 62641 62641 d = d !== undefined ? … … 62644 62644 {} : 62645 62645 []; 62646 62646 62647 62647 var attr = function ( str, td ) { 62648 62648 if ( typeof str === 'string' ) { 62649 62649 var idx = str.indexOf('@'); 62650 62650 62651 62651 if ( idx !== -1 ) { 62652 62652 var attr = str.substring( idx+1 ); … … 62656 62656 } 62657 62657 }; 62658 62658 62659 62659 // Read data from a cell and store into the data object 62660 62660 var cellProcess = function ( cell ) { … … 62662 62662 col = columns[i]; 62663 62663 contents = $.trim(cell.innerHTML); 62664 62664 62665 62665 if ( col && col._bAttrSrc ) { 62666 62666 var setter = _fnSetObjectDataFn( col.mData._ ); 62667 62667 setter( d, contents ); 62668 62668 62669 62669 attr( col.mData.sort, cell ); 62670 62670 attr( col.mData.type, cell ); … … 62686 62686 } 62687 62687 } 62688 62688 62689 62689 i++; 62690 62690 }; 62691 62691 62692 62692 if ( td ) { 62693 62693 // `tr` element was passed in 62694 62694 while ( td ) { 62695 62695 name = td.nodeName.toUpperCase(); 62696 62696 62697 62697 if ( name == "TD" || name == "TH" ) { 62698 62698 cellProcess( td ); 62699 62699 tds.push( td ); 62700 62700 } 62701 62701 62702 62702 td = td.nextSibling; 62703 62703 } … … 62706 62706 // Existing row object passed in 62707 62707 tds = row.anCells; 62708 62708 62709 62709 for ( var j=0, jen=tds.length ; j<jen ; j++ ) { 62710 62710 cellProcess( tds[j] ); 62711 62711 } 62712 62712 } 62713 62713 62714 62714 // Read the ID from the DOM if present 62715 62715 var rowNode = row.firstChild ? row : row.nTr; 62716 62716 62717 62717 if ( rowNode ) { 62718 62718 var id = rowNode.getAttribute( 'id' ); 62719 62719 62720 62720 if ( id ) { 62721 62721 _fnSetObjectDataFn( settings.rowId )( d, id ); 62722 62722 } 62723 62723 } 62724 62724 62725 62725 return { 62726 62726 data: d, … … 62746 62746 nTr, nTd, oCol, 62747 62747 i, iLen, create; 62748 62748 62749 62749 if ( row.nTr === null ) 62750 62750 { 62751 62751 nTr = nTrIn || document.createElement('tr'); 62752 62752 62753 62753 row.nTr = nTr; 62754 62754 row.anCells = cells; 62755 62755 62756 62756 /* Use a private property on the node to allow reserve mapping from the node 62757 62757 * to the aoData array for fast look up 62758 62758 */ 62759 62759 nTr._DT_RowIndex = iRow; 62760 62760 62761 62761 /* Special parameters can be given by the data source to be used on the row */ 62762 62762 _fnRowAttributes( oSettings, row ); 62763 62763 62764 62764 /* Process each column */ 62765 62765 for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) … … 62767 62767 oCol = oSettings.aoColumns[i]; 62768 62768 create = nTrIn ? false : true; 62769 62769 62770 62770 nTd = create ? document.createElement( oCol.sCellType ) : anTds[i]; 62771 62771 nTd._DT_CellIndex = { … … 62773 62773 column: i 62774 62774 }; 62775 62775 62776 62776 cells.push( nTd ); 62777 62777 62778 62778 // Need to create the HTML if new, or if a rendering function is defined 62779 62779 if ( create || ((!nTrIn || oCol.mRender || oCol.mData !== i) && … … 62782 62782 nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' ); 62783 62783 } 62784 62784 62785 62785 /* Add user defined class */ 62786 62786 if ( oCol.sClass ) … … 62788 62788 nTd.className += ' '+oCol.sClass; 62789 62789 } 62790 62790 62791 62791 // Visibility - add or remove as required 62792 62792 if ( oCol.bVisible && ! nTrIn ) … … 62798 62798 nTd.parentNode.removeChild( nTd ); 62799 62799 } 62800 62800 62801 62801 if ( oCol.fnCreatedCell ) 62802 62802 { … … 62806 62806 } 62807 62807 } 62808 62808 62809 62809 _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] ); 62810 62810 } 62811 62811 62812 62812 // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved 62813 62813 // and deployed 62814 62814 row.nTr.setAttribute( 'role', 'row' ); 62815 62815 } 62816 62817 62816 62817 62818 62818 /** 62819 62819 * Add attributes to a row based on the special `DT_*` parameters in a data … … 62827 62827 var tr = row.nTr; 62828 62828 var data = row._aData; 62829 62829 62830 62830 if ( tr ) { 62831 62831 var id = settings.rowIdFn( data ); 62832 62832 62833 62833 if ( id ) { 62834 62834 tr.id = id; 62835 62835 } 62836 62836 62837 62837 if ( data.DT_RowClass ) { 62838 62838 // Remove any classes added by DT_RowClass before … … 62841 62841 _unique( row.__rowc.concat( a ) ) : 62842 62842 a; 62843 62843 62844 62844 $(tr) 62845 62845 .removeClass( row.__rowc.join(' ') ) 62846 62846 .addClass( data.DT_RowClass ); 62847 62847 } 62848 62848 62849 62849 if ( data.DT_RowAttr ) { 62850 62850 $(tr).attr( data.DT_RowAttr ); 62851 62851 } 62852 62852 62853 62853 if ( data.DT_RowData ) { 62854 62854 $(tr).data( data.DT_RowData ); … … 62856 62856 } 62857 62857 } 62858 62859 62858 62859 62860 62860 /** 62861 62861 * Create the HTML header for the table … … 62871 62871 var classes = oSettings.oClasses; 62872 62872 var columns = oSettings.aoColumns; 62873 62873 62874 62874 if ( createHeader ) { 62875 62875 row = $('<tr/>').appendTo( thead ); 62876 62876 } 62877 62877 62878 62878 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 62879 62879 column = columns[i]; 62880 62880 cell = $( column.nTh ).addClass( column.sClass ); 62881 62881 62882 62882 if ( createHeader ) { 62883 62883 cell.appendTo( row ); 62884 62884 } 62885 62885 62886 62886 // 1.11 move into sorting 62887 62887 if ( oSettings.oFeatures.bSort ) { 62888 62888 cell.addClass( column.sSortingClass ); 62889 62889 62890 62890 if ( column.bSortable !== false ) { 62891 62891 cell 62892 62892 .attr( 'tabindex', oSettings.iTabIndex ) 62893 62893 .attr( 'aria-controls', oSettings.sTableId ); 62894 62894 62895 62895 _fnSortAttachListener( oSettings, column.nTh, i ); 62896 62896 } 62897 62897 } 62898 62898 62899 62899 if ( column.sTitle != cell[0].innerHTML ) { 62900 62900 cell.html( column.sTitle ); 62901 62901 } 62902 62902 62903 62903 _fnRenderer( oSettings, 'header' )( 62904 62904 oSettings, cell, column, classes 62905 62905 ); 62906 62906 } 62907 62907 62908 62908 if ( createHeader ) { 62909 62909 _fnDetectHeader( oSettings.aoHeader, thead ); 62910 62910 } 62911 62911 62912 62912 /* ARIA role for the rows */ 62913 62913 $(thead).find('>tr').attr('role', 'row'); 62914 62914 62915 62915 /* Deal with the footer - add classes if required */ 62916 62916 $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH ); 62917 62917 $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH ); 62918 62918 62919 62919 // Cache the footer cells. Note that we only take the cells from the first 62920 62920 // row in the footer. If there is more than one row the user wants to … … 62923 62923 if ( tfoot !== null ) { 62924 62924 var cells = oSettings.aoFooter[0]; 62925 62925 62926 62926 for ( i=0, ien=cells.length ; i<ien ; i++ ) { 62927 62927 column = columns[i]; 62928 62928 column.nTf = cells[i].cell; 62929 62929 62930 62930 if ( column.sClass ) { 62931 62931 $(column.nTf).addClass( column.sClass ); … … 62934 62934 } 62935 62935 } 62936 62937 62936 62937 62938 62938 /** 62939 62939 * Draw the header (or footer) element based on the column visibility states. The … … 62956 62956 var iColumns = oSettings.aoColumns.length; 62957 62957 var iRowspan, iColspan; 62958 62958 62959 62959 if ( ! aoSource ) 62960 62960 { 62961 62961 return; 62962 62962 } 62963 62963 62964 62964 if ( bIncludeHidden === undefined ) 62965 62965 { 62966 62966 bIncludeHidden = false; 62967 62967 } 62968 62968 62969 62969 /* Make a copy of the master layout array, but without the visible columns in it */ 62970 62970 for ( i=0, iLen=aoSource.length ; i<iLen ; i++ ) … … 62972 62972 aoLocal[i] = aoSource[i].slice(); 62973 62973 aoLocal[i].nTr = aoSource[i].nTr; 62974 62974 62975 62975 /* Remove any columns which are currently hidden */ 62976 62976 for ( j=iColumns-1 ; j>=0 ; j-- ) … … 62981 62981 } 62982 62982 } 62983 62983 62984 62984 /* Prep the applied array - it needs an element for each row */ 62985 62985 aApplied.push( [] ); 62986 62986 } 62987 62987 62988 62988 for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ ) 62989 62989 { 62990 62990 nLocalTr = aoLocal[i].nTr; 62991 62991 62992 62992 /* All cells are going to be replaced, so empty out the row */ 62993 62993 if ( nLocalTr ) … … 62998 62998 } 62999 62999 } 63000 63000 63001 63001 for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ ) 63002 63002 { 63003 63003 iRowspan = 1; 63004 63004 iColspan = 1; 63005 63005 63006 63006 /* Check to see if there is already a cell (row/colspan) covering our target 63007 63007 * insert point. If there is, then there is nothing to do. … … 63011 63011 nLocalTr.appendChild( aoLocal[i][j].cell ); 63012 63012 aApplied[i][j] = 1; 63013 63013 63014 63014 /* Expand the cell to cover as many rows as needed */ 63015 63015 while ( aoLocal[i+iRowspan] !== undefined && … … 63019 63019 iRowspan++; 63020 63020 } 63021 63021 63022 63022 /* Expand the cell to cover as many columns as needed */ 63023 63023 while ( aoLocal[i][j+iColspan] !== undefined && … … 63031 63031 iColspan++; 63032 63032 } 63033 63033 63034 63034 /* Do the actual expansion in the DOM */ 63035 63035 $(aoLocal[i][j].cell) … … 63040 63040 } 63041 63041 } 63042 63043 63042 63043 63044 63044 /** 63045 63045 * Insert the required TR nodes into the table for display … … 63056 63056 return; 63057 63057 } 63058 63058 63059 63059 var i, iLen, n; 63060 63060 var anRows = []; … … 63067 63067 var bServerSide = _fnDataSource( oSettings ) == 'ssp'; 63068 63068 var aiDisplay = oSettings.aiDisplay; 63069 63069 63070 63070 oSettings.bDrawing = true; 63071 63071 63072 63072 /* Check and see if we have an initial draw position from state saving */ 63073 63073 if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 ) … … 63078 63078 0 : 63079 63079 iInitDisplayStart; 63080 63080 63081 63081 oSettings.iInitDisplayStart = -1; 63082 63082 } 63083 63083 63084 63084 var iDisplayStart = oSettings._iDisplayStart; 63085 63085 var iDisplayEnd = oSettings.fnDisplayEnd(); 63086 63086 63087 63087 /* Server-side processing draw intercept */ 63088 63088 if ( oSettings.bDeferLoading ) … … 63100 63100 return; 63101 63101 } 63102 63102 63103 63103 if ( aiDisplay.length !== 0 ) 63104 63104 { 63105 63105 var iStart = bServerSide ? 0 : iDisplayStart; 63106 63106 var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd; 63107 63107 63108 63108 for ( var j=iStart ; j<iEnd ; j++ ) 63109 63109 { … … 63114 63114 _fnCreateTr( oSettings, iDataIndex ); 63115 63115 } 63116 63116 63117 63117 var nRow = aoData.nTr; 63118 63118 63119 63119 /* Remove the old striping classes and then add the new one */ 63120 63120 if ( iStripes !== 0 ) … … 63127 63127 } 63128 63128 } 63129 63129 63130 63130 // Row callback functions - might want to manipulate the row 63131 63131 // iRowCount and j are not currently documented. Are they at all … … 63133 63133 _fnCallbackFire( oSettings, 'aoRowCallback', null, 63134 63134 [nRow, aoData._aData, iRowCount, j, iDataIndex] ); 63135 63135 63136 63136 anRows.push( nRow ); 63137 63137 iRowCount++; … … 63150 63150 sZero = oLang.sEmptyTable; 63151 63151 } 63152 63152 63153 63153 anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } ) 63154 63154 .append( $('<td />', { … … 63158 63158 } ).html( sZero ) )[0]; 63159 63159 } 63160 63160 63161 63161 /* Header and footer callbacks */ 63162 63162 _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0], 63163 63163 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); 63164 63164 63165 63165 _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0], 63166 63166 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); 63167 63167 63168 63168 var body = $(oSettings.nTBody); 63169 63169 63170 63170 body.children().detach(); 63171 63171 body.append( $(anRows) ); 63172 63172 63173 63173 /* Call all required callback functions for the end of a draw */ 63174 63174 _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] ); 63175 63175 63176 63176 /* Draw is complete, sorting and filtering must be as well */ 63177 63177 oSettings.bSorted = false; … … 63179 63179 oSettings.bDrawing = false; 63180 63180 } 63181 63182 63181 63182 63183 63183 /** 63184 63184 * Redraw the table - taking account of the various features which are enabled … … 63194 63194 sort = features.bSort, 63195 63195 filter = features.bFilter; 63196 63196 63197 63197 if ( sort ) { 63198 63198 _fnSort( settings ); 63199 63199 } 63200 63200 63201 63201 if ( filter ) { 63202 63202 _fnFilterComplete( settings, settings.oPreviousSearch ); … … 63206 63206 settings.aiDisplay = settings.aiDisplayMaster.slice(); 63207 63207 } 63208 63208 63209 63209 if ( holdPosition !== true ) { 63210 63210 settings._iDisplayStart = 0; 63211 63211 } 63212 63212 63213 63213 // Let any modules know about the draw hold position state (used by 63214 63214 // scrolling internally) 63215 63215 settings._drawHold = holdPosition; 63216 63216 63217 63217 _fnDraw( settings ); 63218 63218 63219 63219 settings._drawHold = false; 63220 63220 } 63221 63222 63221 63222 63223 63223 /** 63224 63224 * Add the options to the page HTML for the table … … 63232 63232 var holding = $('<div/>').insertBefore( table ); // Holding element for speed 63233 63233 var features = oSettings.oFeatures; 63234 63234 63235 63235 // All DataTables are wrapped in a div 63236 63236 var insert = $('<div/>', { … … 63238 63238 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter) 63239 63239 } ); 63240 63240 63241 63241 oSettings.nHolding = holding[0]; 63242 63242 oSettings.nTableWrapper = insert[0]; 63243 63243 oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; 63244 63244 63245 63245 /* Loop over the user set positioning and place the elements as needed */ 63246 63246 var aDom = oSettings.sDom.split(''); … … 63250 63250 featureNode = null; 63251 63251 cOption = aDom[i]; 63252 63252 63253 63253 if ( cOption == '<' ) 63254 63254 { 63255 63255 /* New container div */ 63256 63256 nNewNode = $('<div/>')[0]; 63257 63257 63258 63258 /* Check to see if we should append an id and/or a class name to the container */ 63259 63259 cNext = aDom[i+1]; … … 63267 63267 j++; 63268 63268 } 63269 63269 63270 63270 /* Replace jQuery UI constants @todo depreciated */ 63271 63271 if ( sAttr == "H" ) … … 63277 63277 sAttr = classes.sJUIFooter; 63278 63278 } 63279 63279 63280 63280 /* The attribute can be in the format of "#id.class", "#id" or "class" This logic 63281 63281 * breaks the string into parts and applies them as needed … … 63295 63295 nNewNode.className = sAttr; 63296 63296 } 63297 63297 63298 63298 i += j; /* Move along the position array */ 63299 63299 } 63300 63300 63301 63301 insert.append( nNewNode ); 63302 63302 insert = $(nNewNode); … … 63351 63351 } 63352 63352 } 63353 63353 63354 63354 /* Add to the 2D features array */ 63355 63355 if ( featureNode ) 63356 63356 { 63357 63357 var aanFeatures = oSettings.aanFeatures; 63358 63358 63359 63359 if ( ! aanFeatures[cOption] ) 63360 63360 { 63361 63361 aanFeatures[cOption] = []; 63362 63362 } 63363 63363 63364 63364 aanFeatures[cOption].push( featureNode ); 63365 63365 insert.append( featureNode ); 63366 63366 } 63367 63367 } 63368 63368 63369 63369 /* Built our DOM structure - replace the holding div with what we want */ 63370 63370 holding.replaceWith( insert ); 63371 63371 oSettings.nHolding = null; 63372 63372 } 63373 63374 63373 63374 63375 63375 /** 63376 63376 * Use the DOM source to create up an array of header cells. The idea here is to … … 63395 63395 return j; 63396 63396 }; 63397 63397 63398 63398 aLayout.splice( 0, aLayout.length ); 63399 63399 63400 63400 /* We know how many rows there are in the layout - so prep it */ 63401 63401 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ ) … … 63403 63403 aLayout.push( [] ); 63404 63404 } 63405 63405 63406 63406 /* Calculate a layout array */ 63407 63407 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ ) … … 63409 63409 nTr = nTrs[i]; 63410 63410 iColumn = 0; 63411 63411 63412 63412 /* For every cell in the row... */ 63413 63413 nCell = nTr.firstChild; … … 63421 63421 iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan; 63422 63422 iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan; 63423 63423 63424 63424 /* There might be colspan cells already in this row, so shift our target 63425 63425 * accordingly 63426 63426 */ 63427 63427 iColShifted = fnShiftCol( aLayout, i, iColumn ); 63428 63428 63429 63429 /* Cache calculation for unique columns */ 63430 63430 bUnique = iColspan === 1 ? true : false; 63431 63431 63432 63432 /* If there is col / rowspan, copy the information into the layout grid */ 63433 63433 for ( l=0 ; l<iColspan ; l++ ) … … 63447 63447 } 63448 63448 } 63449 63450 63449 63450 63451 63451 /** 63452 63452 * Get an array of unique th elements, one for each column … … 63469 63469 } 63470 63470 } 63471 63471 63472 63472 for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ ) 63473 63473 { … … 63481 63481 } 63482 63482 } 63483 63483 63484 63484 return aReturn; 63485 63485 } 63486 63486 63487 63487 /** 63488 63488 * Create an Ajax call based on the table's settings, taking into account that … … 63498 63498 // Compatibility with 1.9-, allow fnServerData and event to manipulate 63499 63499 _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] ); 63500 63500 63501 63501 // Convert to object based for 1.10+ if using the old array scheme which can 63502 63502 // come from server-side processing or serverParams … … 63504 63504 var tmp = {}; 63505 63505 var rbracket = /(.*?)\[\]$/; 63506 63506 63507 63507 $.each( data, function (key, val) { 63508 63508 var match = val.name.match(rbracket); 63509 63509 63510 63510 if ( match ) { 63511 63511 // Support for arrays 63512 63512 var name = match[0]; 63513 63513 63514 63514 if ( ! tmp[ name ] ) { 63515 63515 tmp[ name ] = []; … … 63523 63523 data = tmp; 63524 63524 } 63525 63525 63526 63526 var ajaxData; 63527 63527 var ajax = oSettings.ajax; … … 63531 63531 fn( json ); 63532 63532 }; 63533 63533 63534 63534 if ( $.isPlainObject( ajax ) && ajax.data ) 63535 63535 { 63536 63536 ajaxData = ajax.data; 63537 63537 63538 63538 var newData = typeof ajaxData === 'function' ? 63539 63539 ajaxData( data, oSettings ) : // fn can manipulate data or return 63540 63540 ajaxData; // an object object or array to merge 63541 63541 63542 63542 // If the function returned something, use that alone 63543 63543 data = typeof ajaxData === 'function' && newData ? 63544 63544 newData : 63545 63545 $.extend( true, data, newData ); 63546 63546 63547 63547 // Remove the data property as we've resolved it already and don't want 63548 63548 // jQuery to do it again (it is restored at the end of the function) 63549 63549 delete ajax.data; 63550 63550 } 63551 63551 63552 63552 var baseAjax = { 63553 63553 "data": data, … … 63557 63557 _fnLog( oSettings, 0, error ); 63558 63558 } 63559 63559 63560 63560 oSettings.json = json; 63561 63561 callback( json ); … … 63566 63566 "error": function (xhr, error, thrown) { 63567 63567 var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] ); 63568 63568 63569 63569 if ( $.inArray( true, ret ) === -1 ) { 63570 63570 if ( error == "parsererror" ) { … … 63575 63575 } 63576 63576 } 63577 63577 63578 63578 _fnProcessingDisplay( oSettings, false ); 63579 63579 } 63580 63580 }; 63581 63581 63582 63582 // Store the data submitted for the API 63583 63583 oSettings.oAjaxData = data; 63584 63584 63585 63585 // Allow plug-ins and external processes to modify the data 63586 63586 _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] ); 63587 63587 63588 63588 if ( oSettings.fnServerData ) 63589 63589 { … … 63614 63614 // Object to extend the base settings 63615 63615 oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) ); 63616 63616 63617 63617 // Restore for next time around 63618 63618 ajax.data = ajaxData; 63619 63619 } 63620 63620 } 63621 63622 63621 63622 63623 63623 /** 63624 63624 * Update the table using an Ajax call … … 63632 63632 settings.iDraw++; 63633 63633 _fnProcessingDisplay( settings, true ); 63634 63634 63635 63635 _fnBuildAjax( 63636 63636 settings, … … 63640 63640 } 63641 63641 ); 63642 63642 63643 63643 return false; 63644 63644 } 63645 63645 return true; 63646 63646 } 63647 63648 63647 63648 63649 63649 /** 63650 63650 * Build up the parameters in an object needed for a server-side processing … … 63672 63672 settings._iDisplayLength : 63673 63673 -1; 63674 63674 63675 63675 var param = function ( name, value ) { 63676 63676 data.push( { 'name': name, 'value': value } ); 63677 63677 }; 63678 63678 63679 63679 // DataTables 1.9- compatible method 63680 63680 param( 'sEcho', settings.iDraw ); … … 63683 63683 param( 'iDisplayStart', displayStart ); 63684 63684 param( 'iDisplayLength', displayLength ); 63685 63685 63686 63686 // DataTables 1.10+ method 63687 63687 var d = { … … 63696 63696 } 63697 63697 }; 63698 63698 63699 63699 for ( i=0 ; i<columnCount ; i++ ) { 63700 63700 column = columns[i]; 63701 63701 columnSearch = preColSearch[i]; 63702 63702 dataProp = typeof column.mData=="function" ? 'function' : column.mData ; 63703 63703 63704 63704 d.columns.push( { 63705 63705 data: dataProp, … … 63712 63712 } 63713 63713 } ); 63714 63714 63715 63715 param( "mDataProp_"+i, dataProp ); 63716 63716 63717 63717 if ( features.bFilter ) { 63718 63718 param( 'sSearch_'+i, columnSearch.sSearch ); … … 63720 63720 param( 'bSearchable_'+i, column.bSearchable ); 63721 63721 } 63722 63722 63723 63723 if ( features.bSort ) { 63724 63724 param( 'bSortable_'+i, column.bSortable ); 63725 63725 } 63726 63726 } 63727 63727 63728 63728 if ( features.bFilter ) { 63729 63729 param( 'sSearch', preSearch.sSearch ); 63730 63730 param( 'bRegex', preSearch.bRegex ); 63731 63731 } 63732 63732 63733 63733 if ( features.bSort ) { 63734 63734 $.each( sort, function ( i, val ) { 63735 63735 d.order.push( { column: val.col, dir: val.dir } ); 63736 63736 63737 63737 param( 'iSortCol_'+i, val.col ); 63738 63738 param( 'sSortDir_'+i, val.dir ); 63739 63739 } ); 63740 63740 63741 63741 param( 'iSortingCols', sort.length ); 63742 63742 } 63743 63743 63744 63744 // If the legacy.ajax parameter is null, then we automatically decide which 63745 63745 // form to use, based on sAjaxSource … … 63748 63748 return settings.sAjaxSource ? data : d; 63749 63749 } 63750 63750 63751 63751 // Otherwise, if legacy has been specified then we use that to decide on the 63752 63752 // form 63753 63753 return legacy ? data : d; 63754 63754 } 63755 63756 63755 63756 63757 63757 /** 63758 63758 * Data the data from the server (nuking the old) and redraw the table … … 63773 63773 return json[old] !== undefined ? json[old] : json[modern]; 63774 63774 }; 63775 63775 63776 63776 var data = _fnAjaxDataSrc( settings, json ); 63777 63777 var draw = compat( 'sEcho', 'draw' ); 63778 63778 var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' ); 63779 63779 var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' ); 63780 63780 63781 63781 if ( draw ) { 63782 63782 // Protect against out of sequence returns … … 63786 63786 settings.iDraw = draw * 1; 63787 63787 } 63788 63788 63789 63789 _fnClearTable( settings ); 63790 63790 settings._iRecordsTotal = parseInt(recordsTotal, 10); 63791 63791 settings._iRecordsDisplay = parseInt(recordsFiltered, 10); 63792 63792 63793 63793 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 63794 63794 _fnAddData( settings, data[i] ); 63795 63795 } 63796 63796 settings.aiDisplay = settings.aiDisplayMaster.slice(); 63797 63797 63798 63798 settings.bAjaxDataGet = false; 63799 63799 _fnDraw( settings ); 63800 63800 63801 63801 if ( ! settings._bInitComplete ) { 63802 63802 _fnInitComplete( settings, json ); 63803 63803 } 63804 63804 63805 63805 settings.bAjaxDataGet = true; 63806 63806 _fnProcessingDisplay( settings, false ); 63807 63807 } 63808 63809 63808 63809 63810 63810 /** 63811 63811 * Get the data from the JSON data source to use for drawing a table. Using … … 63821 63821 oSettings.ajax.dataSrc : 63822 63822 oSettings.sAjaxDataProp; // Compatibility with 1.9-. 63823 63823 63824 63824 // Compatibility with 1.9-. In order to read from aaData, check if the 63825 63825 // default has been changed, if not, check for aaData … … 63827 63827 return json.aaData || json[dataSrc]; 63828 63828 } 63829 63829 63830 63830 return dataSrc !== "" ? 63831 63831 _fnGetObjectDataFn( dataSrc )( json ) : 63832 63832 json; 63833 63833 } 63834 63834 63835 63835 /** 63836 63836 * Generate the node required for filtering text … … 63847 63847 var features = settings.aanFeatures; 63848 63848 var input = '<input type="search" class="'+classes.sFilterInput+'"/>'; 63849 63849 63850 63850 var str = language.sSearch; 63851 63851 str = str.match(/_INPUT_/) ? 63852 63852 str.replace('_INPUT_', input) : 63853 63853 str+input; 63854 63854 63855 63855 var filter = $('<div/>', { 63856 63856 'id': ! features.f ? tableId+'_filter' : null, … … 63858 63858 } ) 63859 63859 .append( $('<label/>' ).append( str ) ); 63860 63860 63861 63861 var searchFn = function() { 63862 63862 /* Update all other filter input elements for the new display */ 63863 63863 var n = features.f; 63864 63864 var val = !this.value ? "" : this.value; // mental IE8 fix :-( 63865 63865 63866 63866 /* Now do the filter */ 63867 63867 if ( val != previousSearch.sSearch ) { … … 63872 63872 "bCaseInsensitive": previousSearch.bCaseInsensitive 63873 63873 } ); 63874 63874 63875 63875 // Need to redraw, without resorting 63876 63876 settings._iDisplayStart = 0; … … 63878 63878 } 63879 63879 }; 63880 63880 63881 63881 var searchDelay = settings.searchDelay !== null ? 63882 63882 settings.searchDelay : … … 63884 63884 400 : 63885 63885 0; 63886 63886 63887 63887 var jqFilter = $('input', filter) 63888 63888 .val( previousSearch.sSearch ) … … 63901 63901 } ) 63902 63902 .attr('aria-controls', tableId); 63903 63903 63904 63904 // Update the input elements whenever the table is filtered 63905 63905 $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) { … … 63915 63915 } 63916 63916 } ); 63917 63917 63918 63918 return filter[0]; 63919 63919 } 63920 63921 63920 63921 63922 63922 /** 63923 63923 * Filter the table using both the global filter and column based filtering … … 63942 63942 return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex; 63943 63943 }; 63944 63944 63945 63945 // Resolve any column types that are unknown due to addition or invalidation 63946 63946 // @todo As per sort - can this be moved into an event handler? 63947 63947 _fnColumnTypes( oSettings ); 63948 63948 63949 63949 /* In server-side processing all filtering is done by the server, so no point hanging around here */ 63950 63950 if ( _fnDataSource( oSettings ) != 'ssp' ) … … 63953 63953 _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive ); 63954 63954 fnSaveFilter( oInput ); 63955 63955 63956 63956 /* Now do the individual column filter */ 63957 63957 for ( var i=0 ; i<aoPrevSearch.length ; i++ ) … … 63960 63960 aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive ); 63961 63961 } 63962 63962 63963 63963 /* Custom filtering */ 63964 63964 _fnFilterCustom( oSettings ); … … 63968 63968 fnSaveFilter( oInput ); 63969 63969 } 63970 63970 63971 63971 /* Tell the draw function we have been filtering */ 63972 63972 oSettings.bFiltered = true; 63973 63973 _fnCallbackFire( oSettings, null, 'search', [oSettings] ); 63974 63974 } 63975 63976 63975 63976 63977 63977 /** 63978 63978 * Apply custom filtering functions … … 63985 63985 var displayRows = settings.aiDisplay; 63986 63986 var row, rowIdx; 63987 63987 63988 63988 for ( var i=0, ien=filters.length ; i<ien ; i++ ) { 63989 63989 var rows = []; 63990 63990 63991 63991 // Loop over each row and see if it should be included 63992 63992 for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) { 63993 63993 rowIdx = displayRows[ j ]; 63994 63994 row = settings.aoData[ rowIdx ]; 63995 63995 63996 63996 if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) { 63997 63997 rows.push( rowIdx ); 63998 63998 } 63999 63999 } 64000 64000 64001 64001 // So the array reference doesn't break set the results into the 64002 64002 // existing array … … 64005 64005 } 64006 64006 } 64007 64008 64007 64008 64009 64009 /** 64010 64010 * Filter the table on a per-column basis … … 64022 64022 return; 64023 64023 } 64024 64024 64025 64025 var data; 64026 64026 var out = []; 64027 64027 var display = settings.aiDisplay; 64028 64028 var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive ); 64029 64029 64030 64030 for ( var i=0 ; i<display.length ; i++ ) { 64031 64031 data = settings.aoData[ display[i] ]._aFilterData[ colIdx ]; 64032 64032 64033 64033 if ( rpSearch.test( data ) ) { 64034 64034 out.push( display[i] ); 64035 64035 } 64036 64036 } 64037 64037 64038 64038 settings.aiDisplay = out; 64039 64039 } 64040 64041 64040 64041 64042 64042 /** 64043 64043 * Filter the data table based on user input and draw the table … … 64057 64057 var display, invalidated, i; 64058 64058 var filtered = []; 64059 64059 64060 64060 // Need to take account of custom filtering functions - always filter 64061 64061 if ( DataTable.ext.search.length !== 0 ) { 64062 64062 force = true; 64063 64063 } 64064 64064 64065 64065 // Check if any of the rows were invalidated 64066 64066 invalidated = _fnFilterData( settings ); 64067 64067 64068 64068 // If the input is blank - we just want the full data set 64069 64069 if ( input.length <= 0 ) { … … 64082 64082 settings.aiDisplay = displayMaster.slice(); 64083 64083 } 64084 64084 64085 64085 // Search the display array 64086 64086 display = settings.aiDisplay; 64087 64087 64088 64088 for ( i=0 ; i<display.length ; i++ ) { 64089 64089 if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) { … … 64091 64091 } 64092 64092 } 64093 64093 64094 64094 settings.aiDisplay = filtered; 64095 64095 } 64096 64096 } 64097 64098 64097 64098 64099 64099 /** 64100 64100 * Build a regular expression object suitable for searching a table … … 64111 64111 search : 64112 64112 _fnEscapeRegex( search ); 64113 64113 64114 64114 if ( smart ) { 64115 64115 /* For smart filtering we want to allow the search to work regardless of … … 64117 64117 * order is important - a la google. So this is what we want to 64118 64118 * generate: 64119 * 64119 * 64120 64120 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$ 64121 64121 */ … … 64125 64125 word = m ? m[1] : word; 64126 64126 } 64127 64127 64128 64128 return word.replace('"', ''); 64129 64129 } ); 64130 64130 64131 64131 search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$'; 64132 64132 } 64133 64133 64134 64134 return new RegExp( search, caseInsensitive ? 'i' : '' ); 64135 64135 } 64136 64137 64136 64137 64138 64138 /** 64139 64139 * Escape a string such that it can be used in a regular expression … … 64143 64143 */ 64144 64144 var _fnEscapeRegex = DataTable.util.escapeRegex; 64145 64145 64146 64146 var __filter_div = $('<div>')[0]; 64147 64147 var __filter_div_textContent = __filter_div.textContent !== undefined; 64148 64148 64149 64149 // Update the filtering data for each row if needed (by invalidation or first run) 64150 64150 function _fnFilterData ( settings ) … … 64155 64155 var fomatters = DataTable.ext.type.search; 64156 64156 var wasInvalidated = false; 64157 64157 64158 64158 for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 64159 64159 row = settings.aoData[i]; 64160 64160 64161 64161 if ( ! row._aFilterData ) { 64162 64162 filterData = []; 64163 64163 64164 64164 for ( j=0, jen=columns.length ; j<jen ; j++ ) { 64165 64165 column = columns[j]; 64166 64166 64167 64167 if ( column.bSearchable ) { 64168 64168 cellData = _fnGetCellData( settings, i, j, 'filter' ); 64169 64169 64170 64170 if ( fomatters[ column.sType ] ) { 64171 64171 cellData = fomatters[ column.sType ]( cellData ); 64172 64172 } 64173 64173 64174 64174 // Search in DataTables 1.10 is string based. In 1.11 this 64175 64175 // should be altered to also allow strict type checking. … … 64177 64177 cellData = ''; 64178 64178 } 64179 64179 64180 64180 if ( typeof cellData !== 'string' && cellData.toString ) { 64181 64181 cellData = cellData.toString(); … … 64185 64185 cellData = ''; 64186 64186 } 64187 64187 64188 64188 // If it looks like there is an HTML entity in the string, 64189 64189 // attempt to decode it so sorting works as expected. Note that … … 64196 64196 __filter_div.innerText; 64197 64197 } 64198 64198 64199 64199 if ( cellData.replace ) { 64200 64200 cellData = cellData.replace(/[\r\n\u2028]/g, ''); 64201 64201 } 64202 64202 64203 64203 filterData.push( cellData ); 64204 64204 } 64205 64205 64206 64206 row._aFilterData = filterData; 64207 64207 row._sFilterRow = filterData.join(' '); … … 64209 64209 } 64210 64210 } 64211 64211 64212 64212 return wasInvalidated; 64213 64213 } 64214 64215 64214 64215 64216 64216 /** 64217 64217 * Convert from the internal Hungarian notation to camelCase for external … … 64230 64230 }; 64231 64231 } 64232 64233 64234 64232 64233 64234 64235 64235 /** 64236 64236 * Convert from camelCase notation to the internal Hungarian. We could use the … … 64249 64249 }; 64250 64250 } 64251 64251 64252 64252 /** 64253 64253 * Generate the node required for the info display … … 64265 64265 'id': ! nodes ? tid+'_info' : null 64266 64266 } ); 64267 64267 64268 64268 if ( ! nodes ) { 64269 64269 // Update display on each draw … … 64272 64272 "sName": "information" 64273 64273 } ); 64274 64274 64275 64275 n 64276 64276 .attr( 'role', 'status' ) 64277 64277 .attr( 'aria-live', 'polite' ); 64278 64278 64279 64279 // Table is described by our info div 64280 64280 $(settings.nTable).attr( 'aria-describedby', tid+'_info' ); 64281 64281 } 64282 64282 64283 64283 return n[0]; 64284 64284 } 64285 64286 64285 64286 64287 64287 /** 64288 64288 * Update the information elements in the display … … 64297 64297 return; 64298 64298 } 64299 64299 64300 64300 var 64301 64301 lang = settings.oLanguage, … … 64307 64307 lang.sInfo : 64308 64308 lang.sInfoEmpty; 64309 64309 64310 64310 if ( total !== max ) { 64311 64311 /* Record set after filtering */ 64312 64312 out += ' ' + lang.sInfoFiltered; 64313 64313 } 64314 64314 64315 64315 // Convert the macros 64316 64316 out += lang.sInfoPostFix; 64317 64317 out = _fnInfoMacros( settings, out ); 64318 64318 64319 64319 var callback = lang.fnInfoCallback; 64320 64320 if ( callback !== null ) { … … 64323 64323 ); 64324 64324 } 64325 64325 64326 64326 $(nodes).html( out ); 64327 64327 } 64328 64329 64328 64329 64330 64330 function _fnInfoMacros ( settings, str ) 64331 64331 { … … 64338 64338 vis = settings.fnRecordsDisplay(), 64339 64339 all = len === -1; 64340 64340 64341 64341 return str. 64342 64342 replace(/_START_/g, formatter.call( settings, start ) ). … … 64347 64347 replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) ); 64348 64348 } 64349 64350 64351 64349 64350 64351 64352 64352 /** 64353 64353 * Draw the table for the first time, adding all required features … … 64361 64361 var features = settings.oFeatures; 64362 64362 var deferLoading = settings.bDeferLoading; // value modified by the draw 64363 64363 64364 64364 /* Ensure that the table data is fully initialised */ 64365 64365 if ( ! settings.bInitialised ) { … … 64367 64367 return; 64368 64368 } 64369 64369 64370 64370 /* Show the display HTML options */ 64371 64371 _fnAddOptionsHtml( settings ); 64372 64372 64373 64373 /* Build and draw the header / footer for the table */ 64374 64374 _fnBuildHead( settings ); 64375 64375 _fnDrawHead( settings, settings.aoHeader ); 64376 64376 _fnDrawHead( settings, settings.aoFooter ); 64377 64377 64378 64378 /* Okay to show that something is going on now */ 64379 64379 _fnProcessingDisplay( settings, true ); 64380 64380 64381 64381 /* Calculate sizes for columns */ 64382 64382 if ( features.bAutoWidth ) { 64383 64383 _fnCalculateColumnWidths( settings ); 64384 64384 } 64385 64385 64386 64386 for ( i=0, iLen=columns.length ; i<iLen ; i++ ) { 64387 64387 column = columns[i]; 64388 64388 64389 64389 if ( column.sWidth ) { 64390 64390 column.nTh.style.width = _fnStringToCss( column.sWidth ); 64391 64391 } 64392 64392 } 64393 64393 64394 64394 _fnCallbackFire( settings, null, 'preInit', [settings] ); 64395 64395 64396 64396 // If there is default sorting required - let's do it. The sort function 64397 64397 // will do the drawing for us. Otherwise we draw the table regardless of the … … 64399 64399 // data (show 'loading' message possibly) 64400 64400 _fnReDraw( settings ); 64401 64401 64402 64402 // Server-side processing init complete is done by _fnAjaxUpdateDraw 64403 64403 var dataSrc = _fnDataSource( settings ); … … 64407 64407 _fnBuildAjax( settings, [], function(json) { 64408 64408 var aData = _fnAjaxDataSrc( settings, json ); 64409 64409 64410 64410 // Got the data - add it to the table 64411 64411 for ( i=0 ; i<aData.length ; i++ ) { 64412 64412 _fnAddData( settings, aData[i] ); 64413 64413 } 64414 64414 64415 64415 // Reset the init display for cookie saving. We've already done 64416 64416 // a filter, and therefore cleared it before. So we need to make 64417 64417 // it appear 'fresh' 64418 64418 settings.iInitDisplayStart = iAjaxStart; 64419 64419 64420 64420 _fnReDraw( settings ); 64421 64421 64422 64422 _fnProcessingDisplay( settings, false ); 64423 64423 _fnInitComplete( settings, json ); … … 64430 64430 } 64431 64431 } 64432 64433 64432 64433 64434 64434 /** 64435 64435 * Draw the table for the first time, adding all required features … … 64442 64442 { 64443 64443 settings._bInitComplete = true; 64444 64444 64445 64445 // When data was added after the initialisation (data or Ajax) we need to 64446 64446 // calculate the column sizing … … 64448 64448 _fnAdjustColumnSizing( settings ); 64449 64449 } 64450 64450 64451 64451 _fnCallbackFire( settings, null, 'plugin-init', [settings, json] ); 64452 64452 _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] ); 64453 64453 } 64454 64455 64454 64455 64456 64456 function _fnLengthChange ( settings, val ) 64457 64457 { 64458 64458 var len = parseInt( val, 10 ); 64459 64459 settings._iDisplayLength = len; 64460 64460 64461 64461 _fnLengthOverflow( settings ); 64462 64462 64463 64463 // Fire length change event 64464 64464 _fnCallbackFire( settings, null, 'length', [settings, len] ); 64465 64465 } 64466 64467 64466 64467 64468 64468 /** 64469 64469 * Generate the node required for user display length changing … … 64481 64481 lengths = d2 ? menu[0] : menu, 64482 64482 language = d2 ? menu[1] : menu; 64483 64483 64484 64484 var select = $('<select/>', { 64485 64485 'name': tableId+'_length', … … 64487 64487 'class': classes.sLengthSelect 64488 64488 } ); 64489 64489 64490 64490 for ( var i=0, ien=lengths.length ; i<ien ; i++ ) { 64491 64491 select[0][ i ] = new Option( … … 64496 64496 ); 64497 64497 } 64498 64498 64499 64499 var div = $('<div><label/></div>').addClass( classes.sLength ); 64500 64500 if ( ! settings.aanFeatures.l ) { 64501 64501 div[0].id = tableId+'_length'; 64502 64502 } 64503 64503 64504 64504 div.children().append( 64505 64505 settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML ) 64506 64506 ); 64507 64507 64508 64508 // Can't use `select` variable as user might provide their own and the 64509 64509 // reference is broken by the use of outerHTML … … 64514 64514 _fnDraw( settings ); 64515 64515 } ); 64516 64516 64517 64517 // Update node value whenever anything changes the table's length 64518 64518 $(settings.nTable).on( 'length.dt.DT', function (e, s, len) { … … 64521 64521 } 64522 64522 } ); 64523 64523 64524 64524 return div[0]; 64525 64525 } 64526 64527 64528 64526 64527 64528 64529 64529 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 64530 64530 * Note that most of the paging logic is done in 64531 64531 * DataTable.ext.pager 64532 64532 */ 64533 64533 64534 64534 /** 64535 64535 * Generate the node required for default pagination … … 64549 64549 node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0], 64550 64550 features = settings.aanFeatures; 64551 64551 64552 64552 if ( ! modern ) { 64553 64553 plugin.fnInit( settings, node, redraw ); 64554 64554 } 64555 64555 64556 64556 /* Add a draw callback for the pagination on first instance, to update the paging display */ 64557 64557 if ( ! features.p ) 64558 64558 { 64559 64559 node.id = settings.sTableId+'_paginate'; 64560 64560 64561 64561 settings.aoDrawCallback.push( { 64562 64562 "fn": function( settings ) { … … 64571 64571 buttons = plugin(page, pages), 64572 64572 i, ien; 64573 64573 64574 64574 for ( i=0, ien=features.p.length ; i<ien ; i++ ) { 64575 64575 _fnRenderer( settings, 'pageButton' )( … … 64585 64585 } ); 64586 64586 } 64587 64587 64588 64588 return node; 64589 64589 } 64590 64591 64590 64591 64592 64592 /** 64593 64593 * Alter the display settings to change the page … … 64605 64605 len = settings._iDisplayLength, 64606 64606 records = settings.fnRecordsDisplay(); 64607 64607 64608 64608 if ( records === 0 || len === -1 ) 64609 64609 { … … 64613 64613 { 64614 64614 start = action * len; 64615 64615 64616 64616 if ( start > records ) 64617 64617 { … … 64628 64628 start - len : 64629 64629 0; 64630 64630 64631 64631 if ( start < 0 ) 64632 64632 { … … 64649 64649 _fnLog( settings, 0, "Unknown paging action: "+action, 5 ); 64650 64650 } 64651 64651 64652 64652 var changed = settings._iDisplayStart !== start; 64653 64653 settings._iDisplayStart = start; 64654 64654 64655 64655 if ( changed ) { 64656 64656 _fnCallbackFire( settings, null, 'page', [settings] ); 64657 64657 64658 64658 if ( redraw ) { 64659 64659 _fnDraw( settings ); 64660 64660 } 64661 64661 } 64662 64662 64663 64663 return changed; 64664 64664 } 64665 64666 64667 64665 64666 64667 64668 64668 /** 64669 64669 * Generate the node required for the processing node … … 64681 64681 .insertBefore( settings.nTable )[0]; 64682 64682 } 64683 64684 64683 64684 64685 64685 /** 64686 64686 * Display or hide the processing indicator … … 64694 64694 $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' ); 64695 64695 } 64696 64696 64697 64697 _fnCallbackFire( settings, null, 'processing', [settings, show] ); 64698 64698 } 64699 64699 64700 64700 /** 64701 64701 * Add any control elements for the table - specifically scrolling … … 64707 64707 { 64708 64708 var table = $(settings.nTable); 64709 64709 64710 64710 // Add the ARIA grid role to the table 64711 64711 table.attr( 'role', 'grid' ); 64712 64712 64713 64713 // Scrolling from here on in 64714 64714 var scroll = settings.oScroll; 64715 64715 64716 64716 if ( scroll.sX === '' && scroll.sY === '' ) { 64717 64717 return settings.nTable; 64718 64718 } 64719 64719 64720 64720 var scrollX = scroll.sX; 64721 64721 var scrollY = scroll.sY; … … 64730 64730 return !s ? null : _fnStringToCss( s ); 64731 64731 }; 64732 64732 64733 64733 if ( ! footer.length ) { 64734 64734 footer = null; 64735 64735 } 64736 64736 64737 64737 /* 64738 64738 * The HTML structure that we want to generate in this function is: … … 64786 64786 .append( table ) 64787 64787 ); 64788 64788 64789 64789 if ( footer ) { 64790 64790 scroller.append( … … 64809 64809 ); 64810 64810 } 64811 64811 64812 64812 var children = scroller.children(); 64813 64813 var scrollHead = children[0]; 64814 64814 var scrollBody = children[1]; 64815 64815 var scrollFoot = footer ? children[2] : null; 64816 64816 64817 64817 // When the body is scrolled, then we also want to scroll the headers 64818 64818 if ( scrollX ) { 64819 64819 $(scrollBody).on( 'scroll.DT', function (e) { 64820 64820 var scrollLeft = this.scrollLeft; 64821 64821 64822 64822 scrollHead.scrollLeft = scrollLeft; 64823 64823 64824 64824 if ( footer ) { 64825 64825 scrollFoot.scrollLeft = scrollLeft; … … 64827 64827 } ); 64828 64828 } 64829 64829 64830 64830 $(scrollBody).css( 64831 scrollY && scroll.bCollapse ? 'max-height' : 'height', 64831 scrollY && scroll.bCollapse ? 'max-height' : 'height', 64832 64832 scrollY 64833 64833 ); 64834 64834 64835 64835 settings.nScrollHead = scrollHead; 64836 64836 settings.nScrollBody = scrollBody; 64837 64837 settings.nScrollFoot = scrollFoot; 64838 64838 64839 64839 // On redraw - align columns 64840 64840 settings.aoDrawCallback.push( { … … 64842 64842 "sName": "scrolling" 64843 64843 } ); 64844 64844 64845 64845 return scroller[0]; 64846 64846 } 64847 64848 64849 64847 64848 64849 64850 64850 /** 64851 64851 * Update the header, footer and body tables for resizing - i.e. column … … 64905 64905 style.height = 0; 64906 64906 }; 64907 64907 64908 64908 // If the scrollbar visibility has changed from the last draw, we need to 64909 64909 // adjust the column sizes as the table width will have changed to account 64910 64910 // for the scrollbar 64911 64911 var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight; 64912 64912 64913 64913 if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) { 64914 64914 settings.scrollBarVis = scrollBarVis; … … 64919 64919 settings.scrollBarVis = scrollBarVis; 64920 64920 } 64921 64921 64922 64922 /* 64923 64923 * 1. Re-create the table inside the scrolling div 64924 64924 */ 64925 64925 64926 64926 // Remove the old minimised thead and tfoot elements in the inner table 64927 64927 table.children('thead, tfoot').remove(); 64928 64928 64929 64929 if ( footer ) { 64930 64930 footerCopy = footer.clone().prependTo( table ); … … 64932 64932 footerSrcEls = footerCopy.find('tr'); 64933 64933 } 64934 64934 64935 64935 // Clone the current header and footer elements and then place it into the inner table 64936 64936 headerCopy = header.clone().prependTo( table ); … … 64938 64938 headerSrcEls = headerCopy.find('tr'); 64939 64939 headerCopy.find('th, td').removeAttr('tabindex'); 64940 64941 64940 64941 64942 64942 /* 64943 64943 * 2. Take live measurements from the DOM - do not alter the DOM itself! 64944 64944 */ 64945 64945 64946 64946 // Remove old sizing and apply the calculated column widths 64947 64947 // Get the unique column headers in the newly created (cloned) header. We want to apply the … … 64952 64952 divHeader[0].style.width = '100%'; 64953 64953 } 64954 64954 64955 64955 $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) { 64956 64956 idx = _fnVisibleToColumnIndex( settings, i ); 64957 64957 el.style.width = settings.aoColumns[idx].sWidth; 64958 64958 } ); 64959 64959 64960 64960 if ( footer ) { 64961 64961 _fnApplyToChildren( function(n) { … … 64963 64963 }, footerSrcEls ); 64964 64964 } 64965 64965 64966 64966 // Size the table as a whole 64967 64967 sanityWidth = table.outerWidth(); … … 64969 64969 // No x scrolling 64970 64970 tableStyle.width = "100%"; 64971 64971 64972 64972 // IE7 will make the width of the table when 100% include the scrollbar 64973 64973 // - which is shouldn't. When there is a scrollbar we need to take this … … 64978 64978 tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth); 64979 64979 } 64980 64980 64981 64981 // Recalculate the sanity width 64982 64982 sanityWidth = table.outerWidth(); … … 64985 64985 // legacy x scroll inner has been given - use it 64986 64986 tableStyle.width = _fnStringToCss(scrollXInner); 64987 64987 64988 64988 // Recalculate the sanity width 64989 64989 sanityWidth = table.outerWidth(); 64990 64990 } 64991 64991 64992 64992 // Hidden header should have zero height, so remove padding and borders. Then 64993 64993 // set the width based on the real headers 64994 64994 64995 64995 // Apply all styles in one pass 64996 64996 _fnApplyToChildren( zeroOut, headerSrcEls ); 64997 64997 64998 64998 // Read all widths in next pass 64999 64999 _fnApplyToChildren( function(nSizer) { … … 65001 65001 headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) ); 65002 65002 }, headerSrcEls ); 65003 65003 65004 65004 // Apply all widths in final pass 65005 65005 _fnApplyToChildren( function(nToSize, i) { … … 65010 65010 } 65011 65011 }, headerTrgEls ); 65012 65012 65013 65013 $(headerSrcEls).height(0); 65014 65014 65015 65015 /* Same again with the footer if we have one */ 65016 65016 if ( footer ) 65017 65017 { 65018 65018 _fnApplyToChildren( zeroOut, footerSrcEls ); 65019 65019 65020 65020 _fnApplyToChildren( function(nSizer) { 65021 65021 footerContent.push( nSizer.innerHTML ); 65022 65022 footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) ); 65023 65023 }, footerSrcEls ); 65024 65024 65025 65025 _fnApplyToChildren( function(nToSize, i) { 65026 65026 nToSize.style.width = footerWidths[i]; 65027 65027 }, footerTrgEls ); 65028 65028 65029 65029 $(footerSrcEls).height(0); 65030 65030 } 65031 65032 65031 65032 65033 65033 /* 65034 65034 * 3. Apply the measurements 65035 65035 */ 65036 65036 65037 65037 // "Hide" the header and footer that we used for the sizing. We need to keep 65038 65038 // the content of the cell so that the width applied to the header and body … … 65045 65045 nSizer.style.width = headerWidths[i]; 65046 65046 }, headerSrcEls ); 65047 65047 65048 65048 if ( footer ) 65049 65049 { … … 65055 65055 }, footerSrcEls ); 65056 65056 } 65057 65057 65058 65058 // Sanity check that the table is of a sensible width. If not then we are going to get 65059 65059 // misalignment - try to prevent this by not allowing the table to shrink below its min width … … 65065 65065 sanityWidth+barWidth : 65066 65066 sanityWidth; 65067 65067 65068 65068 // IE6/7 are a law unto themselves... 65069 65069 if ( ie67 && (divBodyEl.scrollHeight > … … 65072 65072 tableStyle.width = _fnStringToCss( correction-barWidth ); 65073 65073 } 65074 65074 65075 65075 // And give the user a warning that we've stopped the table getting too small 65076 65076 if ( scrollX === "" || scrollXInner !== "" ) { … … 65082 65082 correction = '100%'; 65083 65083 } 65084 65084 65085 65085 // Apply to the container elements 65086 65086 divBodyStyle.width = _fnStringToCss( correction ); 65087 65087 divHeaderStyle.width = _fnStringToCss( correction ); 65088 65088 65089 65089 if ( footer ) { 65090 65090 settings.nScrollFoot.style.width = _fnStringToCss( correction ); 65091 65091 } 65092 65093 65092 65093 65094 65094 /* 65095 65095 * 4. Clean up … … 65104 65104 } 65105 65105 } 65106 65106 65107 65107 /* Finally set the width's of the header and footer tables */ 65108 65108 var iOuterWidth = table.outerWidth(); 65109 65109 divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth ); 65110 65110 divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth ); 65111 65111 65112 65112 // Figure out if there are scrollbar present - if so then we need a the header and footer to 65113 65113 // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar) … … 65115 65115 var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' ); 65116 65116 divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px"; 65117 65117 65118 65118 if ( footer ) { 65119 65119 divFooterTable[0].style.width = _fnStringToCss( iOuterWidth ); … … 65121 65121 divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px"; 65122 65122 } 65123 65123 65124 65124 // Correct DOM ordering for colgroup - comes before the thead 65125 65125 table.children('colgroup').insertBefore( table.children('thead') ); 65126 65126 65127 65127 /* Adjust the position of the header in case we loose the y-scrollbar */ 65128 65128 divBody.trigger('scroll'); 65129 65129 65130 65130 // If sorting or filtering has occurred, jump the scrolling back to the top 65131 65131 // only if we aren't holding the position … … 65134 65134 } 65135 65135 } 65136 65137 65138 65136 65137 65138 65139 65139 /** 65140 65140 * Apply a given function to the display child nodes of an element array (typically … … 65149 65149 var index=0, i=0, iLen=an1.length; 65150 65150 var nNode1, nNode2; 65151 65151 65152 65152 while ( i < iLen ) { 65153 65153 nNode1 = an1[i].firstChild; 65154 65154 nNode2 = an2 ? an2[i].firstChild : null; 65155 65155 65156 65156 while ( nNode1 ) { 65157 65157 if ( nNode1.nodeType === 1 ) { … … 65162 65162 fn( nNode1, index ); 65163 65163 } 65164 65164 65165 65165 index++; 65166 65166 } 65167 65167 65168 65168 nNode1 = nNode1.nextSibling; 65169 65169 nNode2 = an2 ? nNode2.nextSibling : null; 65170 65170 } 65171 65171 65172 65172 i++; 65173 65173 } 65174 65174 } 65175 65176 65177 65175 65176 65177 65178 65178 var __re_html_remove = /<.*?>/g; 65179 65180 65179 65180 65181 65181 /** 65182 65182 * Calculate the width of columns for the table … … 65202 65202 browser = oSettings.oBrowser, 65203 65203 ie67 = browser.bScrollOversize; 65204 65204 65205 65205 var styleWidth = table.style.width; 65206 65206 if ( styleWidth && styleWidth.indexOf('%') !== -1 ) { 65207 65207 tableWidthAttr = styleWidth; 65208 65208 } 65209 65209 65210 65210 /* Convert any user input sizes into pixel sizes */ 65211 65211 for ( i=0 ; i<visibleColumns.length ; i++ ) { 65212 65212 column = columns[ visibleColumns[i] ]; 65213 65213 65214 65214 if ( column.sWidth !== null ) { 65215 65215 column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer ); 65216 65216 65217 65217 userInputs = true; 65218 65218 } 65219 65219 } 65220 65220 65221 65221 /* If the number of columns in the DOM equals the number that we have to 65222 65222 * process in DataTables, then we can use the offsets that are created by … … 65230 65230 for ( i=0 ; i<columnCount ; i++ ) { 65231 65231 var colIdx = _fnVisibleToColumnIndex( oSettings, i ); 65232 65232 65233 65233 if ( colIdx !== null ) { 65234 65234 columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() ); … … 65245 65245 .css( 'visibility', 'hidden' ) 65246 65246 .removeAttr( 'id' ); 65247 65247 65248 65248 // Clean up the table body 65249 65249 tmpTable.find('tbody tr').remove(); 65250 65250 var tr = $('<tr/>').appendTo( tmpTable.find('tbody') ); 65251 65251 65252 65252 // Clone the table header and footer - we can't use the header / footer 65253 65253 // from the cloned table, since if scrolling is active, the table's … … 65257 65257 .append( $(oSettings.nTHead).clone() ) 65258 65258 .append( $(oSettings.nTFoot).clone() ); 65259 65259 65260 65260 // Remove any assigned widths from the footer (from scrolling) 65261 65261 tmpTable.find('tfoot th, tfoot td').css('width', ''); 65262 65262 65263 65263 // Apply custom sizing to the cloned header 65264 65264 headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] ); 65265 65265 65266 65266 for ( i=0 ; i<visibleColumns.length ; i++ ) { 65267 65267 column = columns[ visibleColumns[i] ]; 65268 65268 65269 65269 headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ? 65270 65270 _fnStringToCss( column.sWidthOrig ) : 65271 65271 ''; 65272 65272 65273 65273 // For scrollX we need to force the column width otherwise the 65274 65274 // browser will collapse it. If this width is smaller than the … … 65284 65284 } 65285 65285 } 65286 65286 65287 65287 // Find the widest cell for each column and put it into the table 65288 65288 if ( oSettings.aoData.length ) { … … 65290 65290 columnIdx = visibleColumns[i]; 65291 65291 column = columns[ columnIdx ]; 65292 65292 65293 65293 $( _fnGetWidestNode( oSettings, columnIdx ) ) 65294 65294 .clone( false ) … … 65297 65297 } 65298 65298 } 65299 65299 65300 65300 // Tidy the temporary table - remove name attributes so there aren't 65301 65301 // duplicated in the dom (radio elements for example) 65302 65302 $('[name]', tmpTable).removeAttr('name'); 65303 65303 65304 65304 // Table has been built, attach to the document so we can work with it. 65305 65305 // A holding element is used, positioned at the top of the container … … 65320 65320 .append( tmpTable ) 65321 65321 .appendTo( tableContainer ); 65322 65323 // When scrolling (X or Y) we want to set the width of the table as 65322 65323 // When scrolling (X or Y) we want to set the width of the table as 65324 65324 // appropriate. However, when not scrolling leave the table width as it 65325 65325 // is. This results in slightly different, but I think correct behaviour … … 65330 65330 tmpTable.css( 'width', 'auto' ); 65331 65331 tmpTable.removeAttr('width'); 65332 65332 65333 65333 // If there is no width attribute or style, then allow the table to 65334 65334 // collapse … … 65343 65343 tmpTable.width( tableWidthAttr ); 65344 65344 } 65345 65345 65346 65346 // Get the width of each column in the constructed table - we need to 65347 65347 // know the inner width (so it can be assigned to the other table's … … 65354 65354 var cell = $(headerCells[i]); 65355 65355 var border = cell.outerWidth() - cell.width(); 65356 65356 65357 65357 // Use getBounding... where possible (not IE8-) because it can give 65358 65358 // sub-pixel accuracy, which we then want to round up! … … 65360 65360 Math.ceil( headerCells[i].getBoundingClientRect().width ) : 65361 65361 cell.outerWidth(); 65362 65362 65363 65363 // Total is tracked to remove any sub-pixel errors as the outerWidth 65364 65364 // of the table might not equal the total given here (IE!). 65365 65365 total += bounding; 65366 65366 65367 65367 // Width for each column to use 65368 65368 columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border ); 65369 65369 } 65370 65370 65371 65371 table.style.width = _fnStringToCss( total ); 65372 65372 65373 65373 // Finished with the table - ditch it 65374 65374 holder.remove(); 65375 65375 } 65376 65376 65377 65377 // If there is a width attr, we want to attach an event listener which 65378 65378 // allows the table sizing to automatically adjust when the window is … … 65382 65382 table.style.width = _fnStringToCss( tableWidthAttr ); 65383 65383 } 65384 65384 65385 65385 if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) { 65386 65386 var bindResize = function () { … … 65389 65389 } ) ); 65390 65390 }; 65391 65391 65392 65392 // IE6/7 will crash if we bind a resize event handler on page load. 65393 65393 // To be removed in 1.11 which drops IE6/7 support … … 65398 65398 bindResize(); 65399 65399 } 65400 65400 65401 65401 oSettings._reszEvt = true; 65402 65402 } 65403 65403 } 65404 65405 65404 65405 65406 65406 /** 65407 65407 * Throttle the calls to a function. Arguments and context are maintained for … … 65413 65413 */ 65414 65414 var _fnThrottle = DataTable.util.throttle; 65415 65416 65415 65416 65417 65417 /** 65418 65418 * Convert a CSS unit width to pixels (e.g. 2em) … … 65427 65427 return 0; 65428 65428 } 65429 65429 65430 65430 var n = $('<div/>') 65431 65431 .css( 'width', _fnStringToCss( width ) ) 65432 65432 .appendTo( parent || document.body ); 65433 65433 65434 65434 var val = n[0].offsetWidth; 65435 65435 n.remove(); 65436 65436 65437 65437 return val; 65438 65438 } 65439 65440 65439 65440 65441 65441 /** 65442 65442 * Get the widest node … … 65452 65452 return null; 65453 65453 } 65454 65454 65455 65455 var data = settings.aoData[ idx ]; 65456 65456 return ! data.nTr ? // Might not have been created when deferred rendering … … 65458 65458 data.anCells[ colIdx ]; 65459 65459 } 65460 65461 65460 65461 65462 65462 /** 65463 65463 * Get the maximum strlen for each data column … … 65470 65470 { 65471 65471 var s, max=-1, maxIdx = -1; 65472 65472 65473 65473 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 65474 65474 s = _fnGetCellData( settings, i, colIdx, 'display' )+''; 65475 65475 s = s.replace( __re_html_remove, '' ); 65476 65476 s = s.replace( / /g, ' ' ); 65477 65477 65478 65478 if ( s.length > max ) { 65479 65479 max = s.length; … … 65481 65481 } 65482 65482 } 65483 65483 65484 65484 return maxIdx; 65485 65485 } 65486 65487 65486 65487 65488 65488 /** 65489 65489 * Append a CSS unit (only if required) to a string … … 65497 65497 return '0px'; 65498 65498 } 65499 65499 65500 65500 if ( typeof s == 'number' ) { 65501 65501 return s < 0 ? … … 65503 65503 s+'px'; 65504 65504 } 65505 65505 65506 65506 // Check it has a unit character already 65507 65507 return s.match(/\d$/) ? … … 65509 65509 s; 65510 65510 } 65511 65512 65513 65511 65512 65513 65514 65514 function _fnSortFlatten ( settings ) 65515 65515 { … … 65533 65533 } 65534 65534 }; 65535 65535 65536 65536 // Build the sort array, with pre-fix and post-fix options if they have been 65537 65537 // specified … … 65539 65539 add( fixed ); 65540 65540 } 65541 65541 65542 65542 if ( fixedObj && fixed.pre ) { 65543 65543 add( fixed.pre ); 65544 65544 } 65545 65545 65546 65546 add( settings.aaSorting ); 65547 65547 65548 65548 if (fixedObj && fixed.post ) { 65549 65549 add( fixed.post ); 65550 65550 } 65551 65551 65552 65552 for ( i=0 ; i<nestedSort.length ; i++ ) 65553 65553 { 65554 65554 srcCol = nestedSort[i][0]; 65555 65555 aDataSort = aoColumns[ srcCol ].aDataSort; 65556 65556 65557 65557 for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ ) 65558 65558 { 65559 65559 iCol = aDataSort[k]; 65560 65560 sType = aoColumns[ iCol ].sType || 'string'; 65561 65561 65562 65562 if ( nestedSort[i]._idx === undefined ) { 65563 65563 nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting ); 65564 65564 } 65565 65565 65566 65566 aSort.push( { 65567 65567 src: srcCol, … … 65574 65574 } 65575 65575 } 65576 65576 65577 65577 return aSort; 65578 65578 } 65579 65579 65580 65580 /** 65581 65581 * Change the order of the table … … 65598 65598 displayMaster = oSettings.aiDisplayMaster, 65599 65599 aSort; 65600 65600 65601 65601 // Resolve any column types that are unknown due to addition or invalidation 65602 65602 // @todo Can this be moved into a 'data-ready' handler which is called when 65603 65603 // data is going to be used in the table? 65604 65604 _fnColumnTypes( oSettings ); 65605 65605 65606 65606 aSort = _fnSortFlatten( oSettings ); 65607 65607 65608 65608 for ( i=0, ien=aSort.length ; i<ien ; i++ ) { 65609 65609 sortCol = aSort[i]; 65610 65610 65611 65611 // Track if we can use the fast sort algorithm 65612 65612 if ( sortCol.formatter ) { 65613 65613 formatters++; 65614 65614 } 65615 65615 65616 65616 // Load the data needed for the sort, for each cell 65617 65617 _fnSortData( oSettings, sortCol.col ); 65618 65618 } 65619 65619 65620 65620 /* No sorting required if server-side or no sorting array */ 65621 65621 if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 ) … … 65626 65626 aiOrig[ displayMaster[i] ] = i; 65627 65627 } 65628 65628 65629 65629 /* Do the sort - here we want multi-column sorting based on a given data source (column) 65630 65630 * and sorting function (from oSort) in a certain direction. It's reasonably complex to … … 65656 65656 dataA = aoData[a]._aSortData, 65657 65657 dataB = aoData[b]._aSortData; 65658 65658 65659 65659 for ( k=0 ; k<len ; k++ ) { 65660 65660 sort = aSort[k]; 65661 65661 65662 65662 x = dataA[ sort.col ]; 65663 65663 y = dataB[ sort.col ]; 65664 65664 65665 65665 test = x<y ? -1 : x>y ? 1 : 0; 65666 65666 if ( test !== 0 ) { … … 65668 65668 } 65669 65669 } 65670 65670 65671 65671 x = aiOrig[a]; 65672 65672 y = aiOrig[b]; … … 65684 65684 dataA = aoData[a]._aSortData, 65685 65685 dataB = aoData[b]._aSortData; 65686 65686 65687 65687 for ( k=0 ; k<len ; k++ ) { 65688 65688 sort = aSort[k]; 65689 65689 65690 65690 x = dataA[ sort.col ]; 65691 65691 y = dataB[ sort.col ]; 65692 65692 65693 65693 fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ]; 65694 65694 test = fn( x, y ); … … 65697 65697 } 65698 65698 } 65699 65699 65700 65700 x = aiOrig[a]; 65701 65701 y = aiOrig[b]; … … 65704 65704 } 65705 65705 } 65706 65706 65707 65707 /* Tell the draw function that we have sorted the data */ 65708 65708 oSettings.bSorted = true; 65709 65709 } 65710 65711 65710 65711 65712 65712 function _fnSortAria ( settings ) 65713 65713 { … … 65717 65717 var aSort = _fnSortFlatten( settings ); 65718 65718 var oAria = settings.oLanguage.oAria; 65719 65719 65720 65720 // ARIA attributes - need to loop all columns, to update all (removing old 65721 65721 // attributes as needed) … … 65726 65726 var sTitle = col.sTitle.replace( /<.*?>/g, "" ); 65727 65727 var th = col.nTh; 65728 65728 65729 65729 // IE7 is throwing an error when setting these properties with jQuery's 65730 65730 // attr() and removeAttr() methods... 65731 65731 th.removeAttribute('aria-sort'); 65732 65732 65733 65733 /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ 65734 65734 if ( col.bSortable ) { … … 65740 65740 nextSort = asSorting[0]; 65741 65741 } 65742 65742 65743 65743 label = sTitle + ( nextSort === "asc" ? 65744 65744 oAria.sSortAscending : … … 65749 65749 label = sTitle; 65750 65750 } 65751 65751 65752 65752 th.setAttribute('aria-label', label); 65753 65753 } 65754 65754 } 65755 65756 65755 65756 65757 65757 /** 65758 65758 * Function to run on user sort request … … 65776 65776 idx = $.inArray( a[1], asSorting ); 65777 65777 } 65778 65778 65779 65779 return idx+1 < asSorting.length ? 65780 65780 idx+1 : … … 65783 65783 0; 65784 65784 }; 65785 65785 65786 65786 // Convert to 2D array if needed 65787 65787 if ( typeof sorting[0] === 'number' ) { 65788 65788 sorting = settings.aaSorting = [ sorting ]; 65789 65789 } 65790 65790 65791 65791 // If appending the sort then we are multi-column sorting 65792 65792 if ( append && settings.oFeatures.bSortMulti ) { 65793 65793 // Are we already doing some kind of sort on this column? 65794 65794 var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') ); 65795 65795 65796 65796 if ( sortIdx !== -1 ) { 65797 65797 // Yes, modify the sort 65798 65798 nextSortIdx = next( sorting[sortIdx], true ); 65799 65799 65800 65800 if ( nextSortIdx === null && sorting.length === 1 ) { 65801 65801 nextSortIdx = 0; // can't remove sorting completely 65802 65802 } 65803 65803 65804 65804 if ( nextSortIdx === null ) { 65805 65805 sorting.splice( sortIdx, 1 ); … … 65819 65819 // Single column - already sorting on this column, modify the sort 65820 65820 nextSortIdx = next( sorting[0] ); 65821 65821 65822 65822 sorting.length = 1; 65823 65823 sorting[0][1] = asSorting[ nextSortIdx ]; … … 65830 65830 sorting[0]._idx = 0; 65831 65831 } 65832 65832 65833 65833 // Run the sort by calling a full redraw 65834 65834 _fnReDraw( settings ); 65835 65835 65836 65836 // callback used for async user interaction 65837 65837 if ( typeof callback == 'function' ) { … … 65839 65839 } 65840 65840 } 65841 65842 65841 65842 65843 65843 /** 65844 65844 * Attach a sort handler (click) to a node … … 65852 65852 { 65853 65853 var col = settings.aoColumns[ colIdx ]; 65854 65854 65855 65855 _fnBindAction( attachTo, {}, function (e) { 65856 65856 /* If the column is not sortable - don't to anything */ … … 65858 65858 return; 65859 65859 } 65860 65860 65861 65861 // If processing is enabled use a timeout to allow the processing 65862 65862 // display to be shown - otherwise to it synchronously 65863 65863 if ( settings.oFeatures.bProcessing ) { 65864 65864 _fnProcessingDisplay( settings, true ); 65865 65865 65866 65866 setTimeout( function() { 65867 65867 _fnSortListener( settings, colIdx, e.shiftKey, callback ); 65868 65868 65869 65869 // In server-side processing, the draw callback will remove the 65870 65870 // processing display … … 65879 65879 } ); 65880 65880 } 65881 65882 65881 65882 65883 65883 /** 65884 65884 * Set the sorting classes on table's body, Note: it is safe to call this function … … 65894 65894 var features = settings.oFeatures; 65895 65895 var i, ien, colIdx; 65896 65896 65897 65897 if ( features.bSort && features.bSortClasses ) { 65898 65898 // Remove old sorting classes 65899 65899 for ( i=0, ien=oldSort.length ; i<ien ; i++ ) { 65900 65900 colIdx = oldSort[i].src; 65901 65901 65902 65902 // Remove column sorting 65903 65903 $( _pluck( settings.aoData, 'anCells', colIdx ) ) 65904 65904 .removeClass( sortClass + (i<2 ? i+1 : 3) ); 65905 65905 } 65906 65906 65907 65907 // Add new column sorting 65908 65908 for ( i=0, ien=sort.length ; i<ien ; i++ ) { 65909 65909 colIdx = sort[i].src; 65910 65910 65911 65911 $( _pluck( settings.aoData, 'anCells', colIdx ) ) 65912 65912 .addClass( sortClass + (i<2 ? i+1 : 3) ); 65913 65913 } 65914 65914 } 65915 65915 65916 65916 settings.aLastSort = sort; 65917 65917 } 65918 65919 65918 65919 65920 65920 // Get the data to sort a column, be it from cache, fresh (populating the 65921 65921 // cache), or from a sort formatter … … 65926 65926 var customSort = DataTable.ext.order[ column.sSortDataType ]; 65927 65927 var customData; 65928 65928 65929 65929 if ( customSort ) { 65930 65930 customData = customSort.call( settings.oInstance, settings, idx, … … 65932 65932 ); 65933 65933 } 65934 65934 65935 65935 // Use / populate cache 65936 65936 var row, cellData; 65937 65937 var formatter = DataTable.ext.type.order[ column.sType+"-pre" ]; 65938 65938 65939 65939 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 65940 65940 row = settings.aoData[i]; 65941 65941 65942 65942 if ( ! row._aSortData ) { 65943 65943 row._aSortData = []; 65944 65944 } 65945 65945 65946 65946 if ( ! row._aSortData[idx] || customSort ) { 65947 65947 cellData = customSort ? 65948 65948 customData[i] : // If there was a custom sort function, use data from there 65949 65949 _fnGetCellData( settings, i, idx, 'sort' ); 65950 65950 65951 65951 row._aSortData[ idx ] = formatter ? 65952 65952 formatter( cellData ) : … … 65955 65955 } 65956 65956 } 65957 65958 65959 65957 65958 65959 65960 65960 /** 65961 65961 * Save the state of a table … … 65969 65969 return; 65970 65970 } 65971 65971 65972 65972 /* Store the interesting variables */ 65973 65973 var state = { … … 65984 65984 } ) 65985 65985 }; 65986 65986 65987 65987 _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] ); 65988 65988 65989 65989 settings.oSavedState = state; 65990 65990 settings.fnStateSaveCallback.call( settings.oInstance, settings, state ); 65991 65991 } 65992 65993 65992 65993 65994 65994 /** 65995 65995 * Attempt to load a saved table state … … 66008 66008 return; 66009 66009 } 66010 66010 66011 66011 // Allow custom and plug-in manipulation functions to alter the saved data set and 66012 66012 // cancelling of loading by returning false … … 66016 66016 return; 66017 66017 } 66018 66018 66019 66019 // Reject old data 66020 66020 var duration = settings.iStateDuration; … … 66023 66023 return; 66024 66024 } 66025 66025 66026 66026 // Number of columns have changed - all bets are off, no restore of settings 66027 66027 if ( s.columns && columns.length !== s.columns.length ) { … … 66029 66029 return; 66030 66030 } 66031 66031 66032 66032 // Store the saved state so it might be accessed at any time 66033 66033 settings.oLoadedState = $.extend( true, {}, s ); 66034 66034 66035 66035 // Restore key features - todo - for 1.11 this needs to be done by 66036 66036 // subscribed events … … 66042 66042 settings._iDisplayLength = s.length; 66043 66043 } 66044 66044 66045 66045 // Order 66046 66046 if ( s.order !== undefined ) { … … 66053 66053 } ); 66054 66054 } 66055 66055 66056 66056 // Search 66057 66057 if ( s.search !== undefined ) { 66058 66058 $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) ); 66059 66059 } 66060 66060 66061 66061 // Columns 66062 66062 // … … 66064 66064 for ( i=0, ien=s.columns.length ; i<ien ; i++ ) { 66065 66065 var col = s.columns[i]; 66066 66066 66067 66067 // Visibility 66068 66068 if ( col.visible !== undefined ) { 66069 66069 columns[i].bVisible = col.visible; 66070 66070 } 66071 66071 66072 66072 // Search 66073 66073 if ( col.search !== undefined ) { … … 66076 66076 } 66077 66077 } 66078 66078 66079 66079 _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] ); 66080 66080 callback(); 66081 66081 }; 66082 66082 66083 66083 if ( ! settings.oFeatures.bStateSave ) { 66084 66084 callback(); 66085 66085 return; 66086 66086 } 66087 66087 66088 66088 var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded ); 66089 66089 66090 66090 if ( state !== undefined ) { 66091 66091 loaded( state ); … … 66093 66093 // otherwise, wait for the loaded callback to be executed 66094 66094 } 66095 66096 66095 66096 66097 66097 /** 66098 66098 * Return the settings object for a particular table … … 66105 66105 var settings = DataTable.settings; 66106 66106 var idx = $.inArray( table, _pluck( settings, 'nTable' ) ); 66107 66107 66108 66108 return idx !== -1 ? 66109 66109 settings[ idx ] : 66110 66110 null; 66111 66111 } 66112 66113 66112 66113 66114 66114 /** 66115 66115 * Log an error message … … 66124 66124 msg = 'DataTables warning: '+ 66125 66125 (settings ? 'table id='+settings.sTableId+' - ' : '')+msg; 66126 66126 66127 66127 if ( tn ) { 66128 66128 msg += '. For more information about this error, please see '+ 66129 66129 'http://datatables.net/tn/'+tn; 66130 66130 } 66131 66131 66132 66132 if ( ! level ) { 66133 66133 // Backwards compatibility pre 1.10 66134 66134 var ext = DataTable.ext; 66135 66135 var type = ext.sErrMode || ext.errMode; 66136 66136 66137 66137 if ( settings ) { 66138 66138 _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] ); 66139 66139 } 66140 66140 66141 66141 if ( type == 'alert' ) { 66142 66142 alert( msg ); … … 66153 66153 } 66154 66154 } 66155 66156 66155 66156 66157 66157 /** 66158 66158 * See if a property is defined on one object, if so assign it to the other object … … 66174 66174 } 66175 66175 } ); 66176 66176 66177 66177 return; 66178 66178 } 66179 66179 66180 66180 if ( mappedName === undefined ) { 66181 66181 mappedName = name; 66182 66182 } 66183 66183 66184 66184 if ( src[name] !== undefined ) { 66185 66185 ret[mappedName] = src[name]; 66186 66186 } 66187 66187 } 66188 66189 66188 66189 66190 66190 /** 66191 66191 * Extend objects - very similar to jQuery.extend, but deep copy objects, and … … 66208 66208 { 66209 66209 var val; 66210 66210 66211 66211 for ( var prop in extender ) { 66212 66212 if ( extender.hasOwnProperty(prop) ) { 66213 66213 val = extender[prop]; 66214 66214 66215 66215 if ( $.isPlainObject( val ) ) { 66216 66216 if ( ! $.isPlainObject( out[prop] ) ) { … … 66227 66227 } 66228 66228 } 66229 66229 66230 66230 return out; 66231 66231 } 66232 66233 66232 66233 66234 66234 /** 66235 66235 * Bind an event handers to allow a click or return key to activate the callback. … … 66259 66259 } ); 66260 66260 } 66261 66262 66261 66262 66263 66263 /** 66264 66264 * Register a callback function. Easily allows a callback function to be added to … … 66280 66280 } 66281 66281 } 66282 66283 66282 66283 66284 66284 /** 66285 66285 * Fire callback functions and trigger events. Note that the loop over the … … 66299 66299 { 66300 66300 var ret = []; 66301 66301 66302 66302 if ( callbackArr ) { 66303 66303 ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) { … … 66305 66305 } ); 66306 66306 } 66307 66307 66308 66308 if ( eventName !== null ) { 66309 66309 var e = $.Event( eventName+'.dt' ); 66310 66310 66311 66311 $(settings.nTable).trigger( e, args ); 66312 66312 66313 66313 ret.push( e.result ); 66314 66314 } 66315 66315 66316 66316 return ret; 66317 66317 } 66318 66319 66318 66319 66320 66320 function _fnLengthOverflow ( settings ) 66321 66321 { … … 66324 66324 end = settings.fnDisplayEnd(), 66325 66325 len = settings._iDisplayLength; 66326 66326 66327 66327 /* If we have space to show extra rows (backing up from the end point - then do so */ 66328 66328 if ( start >= end ) … … 66330 66330 start = end - len; 66331 66331 } 66332 66332 66333 66333 // Keep the start record on the current page 66334 66334 start -= (start % len); 66335 66335 66336 66336 if ( len === -1 || start < 0 ) 66337 66337 { 66338 66338 start = 0; 66339 66339 } 66340 66340 66341 66341 settings._iDisplayStart = start; 66342 66342 } 66343 66344 66343 66344 66345 66345 function _fnRenderer( settings, type ) 66346 66346 { 66347 66347 var renderer = settings.renderer; 66348 66348 var host = DataTable.ext.renderer[type]; 66349 66349 66350 66350 if ( $.isPlainObject( renderer ) && renderer[type] ) { 66351 66351 // Specific renderer for this type. If available use it, otherwise use … … 66358 66358 return host[renderer] || host._; 66359 66359 } 66360 66360 66361 66361 // Use the default 66362 66362 return host._; 66363 66363 } 66364 66365 66364 66365 66366 66366 /** 66367 66367 * Detect the data source being used for the table. Used to simplify the code … … 66382 66382 return 'dom'; 66383 66383 } 66384 66385 66386 66387 66384 66385 66386 66387 66388 66388 /** 66389 66389 * Computed structure of the DataTables API, defined by the options passed to … … 66423 66423 */ 66424 66424 var __apiStruct = []; 66425 66426 66425 66426 66427 66427 /** 66428 66428 * `Array.prototype` reference. … … 66432 66432 */ 66433 66433 var __arrayProto = Array.prototype; 66434 66435 66434 66435 66436 66436 /** 66437 66437 * Abstraction for `context` parameter of the `Api` constructor to allow it to … … 66461 66461 return el.nTable; 66462 66462 } ); 66463 66463 66464 66464 if ( ! mixed ) { 66465 66465 return []; … … 66485 66485 jq = mixed; 66486 66486 } 66487 66487 66488 66488 if ( jq ) { 66489 66489 return jq.map( function(i) { … … 66493 66493 } 66494 66494 }; 66495 66496 66495 66496 66497 66497 /** 66498 66498 * DataTables API class - used to control and interface with one or more … … 66554 66554 return new _Api( context, data ); 66555 66555 } 66556 66556 66557 66557 var settings = []; 66558 66558 var ctxSettings = function ( o ) { … … 66562 66562 } 66563 66563 }; 66564 66564 66565 66565 if ( $.isArray( context ) ) { 66566 66566 for ( var i=0, ien=context.length ; i<ien ; i++ ) { … … 66571 66571 ctxSettings( context ); 66572 66572 } 66573 66573 66574 66574 // Remove duplicates 66575 66575 this.context = _unique( settings ); 66576 66576 66577 66577 // Initial data 66578 66578 if ( data ) { 66579 66579 $.merge( this, data ); 66580 66580 } 66581 66581 66582 66582 // selector 66583 66583 this.selector = { … … 66586 66586 opts: null 66587 66587 }; 66588 66588 66589 66589 _Api.extend( this, this, __apiStruct ); 66590 66590 }; 66591 66591 66592 66592 DataTable.Api = _Api; 66593 66593 66594 66594 // Don't destroy the existing prototype, just extend it. Required for jQuery 2's 66595 66595 // isPlainObject. … … 66599 66599 return this.count() !== 0; 66600 66600 }, 66601 66602 66601 66602 66603 66603 concat: __arrayProto.concat, 66604 66605 66604 66605 66606 66606 context: [], // array of table settings objects 66607 66608 66607 66608 66609 66609 count: function () 66610 66610 { 66611 66611 return this.flatten().length; 66612 66612 }, 66613 66614 66613 66614 66615 66615 each: function ( fn ) 66616 66616 { … … 66618 66618 fn.call( this, this[i], i, this ); 66619 66619 } 66620 66620 66621 66621 return this; 66622 66622 }, 66623 66624 66623 66624 66625 66625 eq: function ( idx ) 66626 66626 { 66627 66627 var ctx = this.context; 66628 66628 66629 66629 return ctx.length > idx ? 66630 66630 new _Api( ctx[idx], this[idx] ) : 66631 66631 null; 66632 66632 }, 66633 66634 66633 66634 66635 66635 filter: function ( fn ) 66636 66636 { 66637 66637 var a = []; 66638 66638 66639 66639 if ( __arrayProto.filter ) { 66640 66640 a = __arrayProto.filter.call( this, fn, this ); … … 66648 66648 } 66649 66649 } 66650 66650 66651 66651 return new _Api( this.context, a ); 66652 66652 }, 66653 66654 66653 66654 66655 66655 flatten: function () 66656 66656 { … … 66658 66658 return new _Api( this.context, a.concat.apply( a, this.toArray() ) ); 66659 66659 }, 66660 66661 66660 66661 66662 66662 join: __arrayProto.join, 66663 66664 66663 66664 66665 66665 indexOf: __arrayProto.indexOf || function (obj, start) 66666 66666 { … … 66672 66672 return -1; 66673 66673 }, 66674 66674 66675 66675 iterator: function ( flatten, type, fn, alwaysNew ) { 66676 66676 var … … 66680 66680 rows, items, item, 66681 66681 selector = this.selector; 66682 66682 66683 66683 // Argument shifting 66684 66684 if ( typeof flatten === 'string' ) { … … 66688 66688 flatten = false; 66689 66689 } 66690 66690 66691 66691 for ( i=0, ien=context.length ; i<ien ; i++ ) { 66692 66692 var apiInst = new _Api( context[i] ); 66693 66693 66694 66694 if ( type === 'table' ) { 66695 66695 ret = fn.call( apiInst, context[i], i ); 66696 66696 66697 66697 if ( ret !== undefined ) { 66698 66698 a.push( ret ); … … 66702 66702 // this has same length as context - one entry for each table 66703 66703 ret = fn.call( apiInst, context[i], this[i], i ); 66704 66704 66705 66705 if ( ret !== undefined ) { 66706 66706 a.push( ret ); … … 66711 66711 // 'this' is an array of column indexes for each context 66712 66712 items = this[i]; 66713 66713 66714 66714 if ( type === 'column-rows' ) { 66715 66715 rows = _selector_row_indexes( context[i], selector.opts ); 66716 66716 } 66717 66717 66718 66718 for ( j=0, jen=items.length ; j<jen ; j++ ) { 66719 66719 item = items[j]; 66720 66720 66721 66721 if ( type === 'cell' ) { 66722 66722 ret = fn.call( apiInst, context[i], item.row, item.column, i, j ); … … 66725 66725 ret = fn.call( apiInst, context[i], item, i, j, rows ); 66726 66726 } 66727 66727 66728 66728 if ( ret !== undefined ) { 66729 66729 a.push( ret ); … … 66732 66732 } 66733 66733 } 66734 66734 66735 66735 if ( a.length || alwaysNew ) { 66736 66736 var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a ); … … 66743 66743 return this; 66744 66744 }, 66745 66746 66745 66746 66747 66747 lastIndexOf: __arrayProto.lastIndexOf || function (obj, start) 66748 66748 { … … 66750 66750 return this.indexOf.apply( this.toArray.reverse(), arguments ); 66751 66751 }, 66752 66753 66752 66753 66754 66754 length: 0, 66755 66756 66755 66756 66757 66757 map: function ( fn ) 66758 66758 { 66759 66759 var a = []; 66760 66760 66761 66761 if ( __arrayProto.map ) { 66762 66762 a = __arrayProto.map.call( this, fn, this ); … … 66768 66768 } 66769 66769 } 66770 66770 66771 66771 return new _Api( this.context, a ); 66772 66772 }, 66773 66774 66773 66774 66775 66775 pluck: function ( prop ) 66776 66776 { … … 66779 66779 } ); 66780 66780 }, 66781 66781 66782 66782 pop: __arrayProto.pop, 66783 66784 66783 66784 66785 66785 push: __arrayProto.push, 66786 66787 66786 66787 66788 66788 // Does not return an API instance 66789 66789 reduce: __arrayProto.reduce || function ( fn, init ) … … 66791 66791 return _fnReduce( this, fn, init, 0, this.length, 1 ); 66792 66792 }, 66793 66794 66793 66794 66795 66795 reduceRight: __arrayProto.reduceRight || function ( fn, init ) 66796 66796 { 66797 66797 return _fnReduce( this, fn, init, this.length-1, -1, -1 ); 66798 66798 }, 66799 66800 66799 66800 66801 66801 reverse: __arrayProto.reverse, 66802 66803 66802 66803 66804 66804 // Object with rows, columns and opts 66805 66805 selector: null, 66806 66807 66806 66807 66808 66808 shift: __arrayProto.shift, 66809 66810 66809 66810 66811 66811 slice: function () { 66812 66812 return new _Api( this.context, this ); 66813 66813 }, 66814 66815 66814 66815 66816 66816 sort: __arrayProto.sort, // ? name - order? 66817 66818 66817 66818 66819 66819 splice: __arrayProto.splice, 66820 66821 66820 66821 66822 66822 toArray: function () 66823 66823 { 66824 66824 return __arrayProto.slice.call( this ); 66825 66825 }, 66826 66827 66826 66827 66828 66828 to$: function () 66829 66829 { 66830 66830 return $( this ); 66831 66831 }, 66832 66833 66832 66833 66834 66834 toJQuery: function () 66835 66835 { 66836 66836 return $( this ); 66837 66837 }, 66838 66839 66838 66839 66840 66840 unique: function () 66841 66841 { 66842 66842 return new _Api( this.context, _unique(this) ); 66843 66843 }, 66844 66845 66844 66845 66846 66846 unshift: __arrayProto.unshift 66847 66847 } ); 66848 66849 66848 66849 66850 66850 _Api.extend = function ( scope, obj, ext ) 66851 66851 { … … 66854 66854 return; 66855 66855 } 66856 66856 66857 66857 var 66858 66858 i, ien, … … 66861 66861 return function () { 66862 66862 var ret = fn.apply( scope, arguments ); 66863 66863 66864 66864 // Method extension 66865 66865 _Api.extend( ret, ret, struc.methodExt ); … … 66867 66867 }; 66868 66868 }; 66869 66869 66870 66870 for ( i=0, ien=ext.length ; i<ien ; i++ ) { 66871 66871 struct = ext[i]; 66872 66872 66873 66873 // Value 66874 66874 obj[ struct.name ] = struct.type === 'function' ? … … 66877 66877 {} : 66878 66878 struct.val; 66879 66879 66880 66880 obj[ struct.name ].__dt_wrapper = true; 66881 66881 66882 66882 // Property extension 66883 66883 _Api.extend( scope, obj[ struct.name ], struct.propExt ); 66884 66884 } 66885 66885 }; 66886 66887 66886 66887 66888 66888 // @todo - Is there need for an augment function? 66889 66889 // _Api.augment = function ( inst, name ) … … 66891 66891 // // Find src object in the structure from the name 66892 66892 // var parts = name.split('.'); 66893 66893 66894 66894 // _Api.extend( inst, obj ); 66895 66895 // }; 66896 66897 66896 66897 66898 66898 // [ 66899 66899 // { … … 66918 66918 // } 66919 66919 // ] 66920 66920 66921 66921 _Api.register = _api_register = function ( name, val ) 66922 66922 { … … 66927 66927 return; 66928 66928 } 66929 66929 66930 66930 var 66931 66931 i, ien, … … 66933 66933 struct = __apiStruct, 66934 66934 key, method; 66935 66935 66936 66936 var find = function ( src, name ) { 66937 66937 for ( var i=0, ien=src.length ; i<ien ; i++ ) { … … 66942 66942 return null; 66943 66943 }; 66944 66944 66945 66945 for ( i=0, ien=heir.length ; i<ien ; i++ ) { 66946 66946 method = heir[i].indexOf('()') !== -1; … … 66948 66948 heir[i].replace('()', '') : 66949 66949 heir[i]; 66950 66950 66951 66951 var src = find( struct, key ); 66952 66952 if ( ! src ) { … … 66960 66960 struct.push( src ); 66961 66961 } 66962 66962 66963 66963 if ( i === ien-1 ) { 66964 66964 src.val = val; … … 66976 66976 } 66977 66977 }; 66978 66978 66979 66979 _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) { 66980 66980 _Api.register( pluralName, val ); 66981 66981 66982 66982 _Api.register( singularName, function () { 66983 66983 var ret = val.apply( this, arguments ); 66984 66984 66985 66985 if ( ret === this ) { 66986 66986 // Returned item is the API instance that was passed in, return it … … 66996 66996 undefined; 66997 66997 } 66998 66998 66999 66999 // Non-API return - just fire it back 67000 67000 return ret; 67001 67001 } ); 67002 67002 }; 67003 67004 67003 67004 67005 67005 /** 67006 67006 * Selector for HTML tables. Apply the given selector to the give array of … … 67018 67018 return [ a[ selector ] ]; 67019 67019 } 67020 67020 67021 67021 // Perform a jQuery selector on the table nodes 67022 67022 var nodes = $.map( a, function (el, i) { 67023 67023 return el.nTable; 67024 67024 } ); 67025 67025 67026 67026 return $(nodes) 67027 67027 .filter( selector ) … … 67033 67033 .toArray(); 67034 67034 }; 67035 67036 67037 67035 67036 67037 67038 67038 /** 67039 67039 * Context selector for the API's context (i.e. the tables the API instance … … 67053 67053 this; 67054 67054 } ); 67055 67056 67055 67056 67057 67057 _api_register( 'table()', function ( selector ) { 67058 67058 var tables = this.tables( selector ); 67059 67059 var ctx = tables.context; 67060 67060 67061 67061 // Truncate to the first matched table 67062 67062 return ctx.length ? … … 67064 67064 tables; 67065 67065 } ); 67066 67067 67066 67067 67068 67068 _api_registerPlural( 'tables().nodes()', 'table().node()' , function () { 67069 67069 return this.iterator( 'table', function ( ctx ) { … … 67071 67071 }, 1 ); 67072 67072 } ); 67073 67074 67073 67074 67075 67075 _api_registerPlural( 'tables().body()', 'table().body()' , function () { 67076 67076 return this.iterator( 'table', function ( ctx ) { … … 67078 67078 }, 1 ); 67079 67079 } ); 67080 67081 67080 67081 67082 67082 _api_registerPlural( 'tables().header()', 'table().header()' , function () { 67083 67083 return this.iterator( 'table', function ( ctx ) { … … 67085 67085 }, 1 ); 67086 67086 } ); 67087 67088 67087 67088 67089 67089 _api_registerPlural( 'tables().footer()', 'table().footer()' , function () { 67090 67090 return this.iterator( 'table', function ( ctx ) { … … 67092 67092 }, 1 ); 67093 67093 } ); 67094 67095 67094 67095 67096 67096 _api_registerPlural( 'tables().containers()', 'table().container()' , function () { 67097 67097 return this.iterator( 'table', function ( ctx ) { … … 67099 67099 }, 1 ); 67100 67100 } ); 67101 67102 67103 67101 67102 67103 67104 67104 /** 67105 67105 * Redraw the tables in the current context. … … 67116 67116 true; 67117 67117 } 67118 67118 67119 67119 _fnReDraw( settings, paging===false ); 67120 67120 } 67121 67121 } ); 67122 67122 } ); 67123 67124 67125 67123 67124 67125 67126 67126 /** 67127 67127 * Get the current page index. … … 67147 67147 return this.page.info().page; // not an expensive call 67148 67148 } 67149 67149 67150 67150 // else, have an action to take on all tables 67151 67151 return this.iterator( 'table', function ( settings ) { … … 67153 67153 } ); 67154 67154 } ); 67155 67156 67155 67156 67157 67157 /** 67158 67158 * Paging information for the first table in the current context. … … 67177 67177 return undefined; 67178 67178 } 67179 67179 67180 67180 var 67181 67181 settings = this.context[0], … … 67184 67184 visRecords = settings.fnRecordsDisplay(), 67185 67185 all = len === -1; 67186 67186 67187 67187 return { 67188 67188 "page": all ? 0 : Math.floor( start / len ), … … 67196 67196 }; 67197 67197 } ); 67198 67199 67198 67199 67200 67200 /** 67201 67201 * Get the current page length. … … 67218 67218 undefined; 67219 67219 } 67220 67220 67221 67221 // else, set the page length 67222 67222 return this.iterator( 'table', function ( settings ) { … … 67224 67224 } ); 67225 67225 } ); 67226 67227 67228 67226 67227 67228 67229 67229 var __reload = function ( settings, holdPosition, callback ) { 67230 67230 // Use the draw event to trigger a callback 67231 67231 if ( callback ) { 67232 67232 var api = new _Api( settings ); 67233 67233 67234 67234 api.one( 'draw', function () { 67235 67235 callback( api.ajax.json() ); 67236 67236 } ); 67237 67237 } 67238 67238 67239 67239 if ( _fnDataSource( settings ) == 'ssp' ) { 67240 67240 _fnReDraw( settings, holdPosition ); … … 67242 67242 else { 67243 67243 _fnProcessingDisplay( settings, true ); 67244 67244 67245 67245 // Cancel an existing request 67246 67246 var xhr = settings.jqXHR; … … 67248 67248 xhr.abort(); 67249 67249 } 67250 67250 67251 67251 // Trigger xhr 67252 67252 _fnBuildAjax( settings, [], function( json ) { 67253 67253 _fnClearTable( settings ); 67254 67254 67255 67255 var data = _fnAjaxDataSrc( settings, json ); 67256 67256 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 67257 67257 _fnAddData( settings, data[i] ); 67258 67258 } 67259 67259 67260 67260 _fnReDraw( settings, holdPosition ); 67261 67261 _fnProcessingDisplay( settings, false ); … … 67263 67263 } 67264 67264 }; 67265 67266 67265 67266 67267 67267 /** 67268 67268 * Get the JSON response from the last Ajax request that DataTables made to the … … 67274 67274 _api_register( 'ajax.json()', function () { 67275 67275 var ctx = this.context; 67276 67276 67277 67277 if ( ctx.length > 0 ) { 67278 67278 return ctx[0].json; 67279 67279 } 67280 67280 67281 67281 // else return undefined; 67282 67282 } ); 67283 67284 67283 67284 67285 67285 /** 67286 67286 * Get the data submitted in the last Ajax request … … 67288 67288 _api_register( 'ajax.params()', function () { 67289 67289 var ctx = this.context; 67290 67290 67291 67291 if ( ctx.length > 0 ) { 67292 67292 return ctx[0].oAjaxData; 67293 67293 } 67294 67294 67295 67295 // else return undefined; 67296 67296 } ); 67297 67298 67297 67298 67299 67299 /** 67300 67300 * Reload tables from the Ajax data source. Note that this function will … … 67311 67311 } ); 67312 67312 } ); 67313 67314 67313 67314 67315 67315 /** 67316 67316 * Get the current Ajax URL. Note that this returns the URL from the first … … 67327 67327 _api_register( 'ajax.url()', function ( url ) { 67328 67328 var ctx = this.context; 67329 67329 67330 67330 if ( url === undefined ) { 67331 67331 // get … … 67334 67334 } 67335 67335 ctx = ctx[0]; 67336 67336 67337 67337 return ctx.ajax ? 67338 67338 $.isPlainObject( ctx.ajax ) ? … … 67341 67341 ctx.sAjaxSource; 67342 67342 } 67343 67343 67344 67344 // set 67345 67345 return this.iterator( 'table', function ( settings ) { … … 67355 67355 } ); 67356 67356 } ); 67357 67358 67357 67358 67359 67359 /** 67360 67360 * Load data from the newly set Ajax URL. Note that this method is only … … 67373 67373 } ); 67374 67374 } ); 67375 67376 67377 67378 67375 67376 67377 67378 67379 67379 var _selector_run = function ( type, selector, selectFn, settings, opts ) 67380 67380 { … … 67383 67383 a, i, ien, j, jen, 67384 67384 selectorType = typeof selector; 67385 67385 67386 67386 // Can't just check for isArray here, as an API or jQuery instance might be 67387 67387 // given with their array like look … … 67389 67389 selector = [ selector ]; 67390 67390 } 67391 67391 67392 67392 for ( i=0, ien=selector.length ; i<ien ; i++ ) { 67393 67393 // Only split on simple strings - complex expressions will be jQuery selectors … … 67395 67395 selector[i].split(',') : 67396 67396 [ selector[i] ]; 67397 67397 67398 67398 for ( j=0, jen=a.length ; j<jen ; j++ ) { 67399 67399 res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] ); 67400 67400 67401 67401 if ( res && res.length ) { 67402 67402 out = out.concat( res ); … … 67404 67404 } 67405 67405 } 67406 67406 67407 67407 // selector extensions 67408 67408 var ext = _ext.selector[ type ]; … … 67412 67412 } 67413 67413 } 67414 67414 67415 67415 return _unique( out ); 67416 67416 }; 67417 67418 67417 67418 67419 67419 var _selector_opts = function ( opts ) 67420 67420 { … … 67422 67422 opts = {}; 67423 67423 } 67424 67424 67425 67425 // Backwards compatibility for 1.9- which used the terminology filter rather 67426 67426 // than search … … 67428 67428 opts.search = opts.filter; 67429 67429 } 67430 67430 67431 67431 return $.extend( { 67432 67432 search: 'none', … … 67435 67435 }, opts ); 67436 67436 }; 67437 67438 67437 67438 67439 67439 var _selector_first = function ( inst ) 67440 67440 { … … 67448 67448 inst.length = 1; 67449 67449 inst.context = [ inst.context[i] ]; 67450 67450 67451 67451 return inst; 67452 67452 } 67453 67453 } 67454 67454 67455 67455 // Not found - return an empty instance 67456 67456 inst.length = 0; 67457 67457 return inst; 67458 67458 }; 67459 67460 67459 67460 67461 67461 var _selector_row_indexes = function ( settings, opts ) 67462 67462 { … … 67465 67465 displayFiltered = settings.aiDisplay, 67466 67466 displayMaster = settings.aiDisplayMaster; 67467 67467 67468 67468 var 67469 67469 search = opts.search, // none, applied, removed 67470 67470 order = opts.order, // applied, current, index (original - compatibility with 1.9) 67471 67471 page = opts.page; // all, current 67472 67472 67473 67473 if ( _fnDataSource( settings ) == 'ssp' ) { 67474 67474 // In server-side processing mode, most options are irrelevant since … … 67498 67498 // O(n+m) solution by creating a hash map 67499 67499 var displayFilteredMap = {}; 67500 67500 67501 67501 for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) { 67502 67502 displayFilteredMap[displayFiltered[i]] = null; 67503 67503 } 67504 67504 67505 67505 a = $.map( displayMaster, function (el) { 67506 67506 return ! displayFilteredMap.hasOwnProperty(el) ? … … 67517 67517 else { // applied | removed 67518 67518 tmp = $.inArray( i, displayFiltered ); 67519 67519 67520 67520 if ((tmp === -1 && search == 'removed') || 67521 67521 (tmp >= 0 && search == 'applied') ) … … 67526 67526 } 67527 67527 } 67528 67528 67529 67529 return a; 67530 67530 }; 67531 67532 67531 67532 67533 67533 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 67534 67534 * Rows … … 67548 67548 var i, ien; 67549 67549 var aoData = settings.aoData; 67550 67550 67551 67551 // Short cut - selector is a number and no options provided (default is 67552 67552 // all records, so no need to check if the index is in there, since it … … 67555 67555 return [ selInt ]; 67556 67556 } 67557 67557 67558 67558 if ( ! rows ) { 67559 67559 rows = _selector_row_indexes( settings, opts ); 67560 67560 } 67561 67561 67562 67562 if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) { 67563 67563 // Selector - integer … … 67568 67568 return rows; 67569 67569 } 67570 67570 67571 67571 // Selector - function 67572 67572 if ( typeof sel === 'function' ) { … … 67576 67576 } ); 67577 67577 } 67578 67578 67579 67579 // Selector - node 67580 67580 if ( sel.nodeName ) { 67581 67581 var rowIdx = sel._DT_RowIndex; // Property added by DT for fast lookup 67582 67582 var cellIdx = sel._DT_CellIndex; 67583 67583 67584 67584 if ( rowIdx !== undefined ) { 67585 67585 // Make sure that the row is actually still present in the table … … 67600 67600 } 67601 67601 } 67602 67602 67603 67603 // ID selector. Want to always be able to select rows by id, regardless 67604 67604 // of if the tr element has been created or not, so can't rely upon … … 67616 67616 return [ rowObj.idx ]; 67617 67617 } 67618 67618 67619 67619 // need to fall through to jQuery in case there is DOM id that 67620 67620 // matches 67621 67621 } 67622 67622 67623 67623 // Get nodes in the order from the `rows` array with null values removed 67624 67624 var nodes = _removeEmpty( 67625 67625 _pluck_order( settings.aoData, rows, 'nTr' ) 67626 67626 ); 67627 67627 67628 67628 // Selector - jQuery selector string, array of nodes or jQuery object/ 67629 67629 // As jQuery's .filter() allows jQuery objects to be passed in filter, … … 67636 67636 .toArray(); 67637 67637 }; 67638 67638 67639 67639 return _selector_run( 'row', selector, run, settings, opts ); 67640 67640 }; 67641 67642 67641 67642 67643 67643 _api_register( 'rows()', function ( selector, opts ) { 67644 67644 // argument shifting … … 67650 67650 selector = ''; 67651 67651 } 67652 67652 67653 67653 opts = _selector_opts( opts ); 67654 67654 67655 67655 var inst = this.iterator( 'table', function ( settings ) { 67656 67656 return __row_selector( settings, selector, opts ); 67657 67657 }, 1 ); 67658 67658 67659 67659 // Want argument shifting here and in __row_selector? 67660 67660 inst.selector.rows = selector; 67661 67661 inst.selector.opts = opts; 67662 67662 67663 67663 return inst; 67664 67664 } ); 67665 67665 67666 67666 _api_register( 'rows().nodes()', function () { 67667 67667 return this.iterator( 'row', function ( settings, row ) { … … 67669 67669 }, 1 ); 67670 67670 } ); 67671 67671 67672 67672 _api_register( 'rows().data()', function () { 67673 67673 return this.iterator( true, 'rows', function ( settings, rows ) { … … 67675 67675 }, 1 ); 67676 67676 } ); 67677 67677 67678 67678 _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) { 67679 67679 return this.iterator( 'row', function ( settings, row ) { … … 67682 67682 }, 1 ); 67683 67683 } ); 67684 67684 67685 67685 _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) { 67686 67686 return this.iterator( 'row', function ( settings, row ) { … … 67688 67688 } ); 67689 67689 } ); 67690 67690 67691 67691 _api_registerPlural( 'rows().indexes()', 'row().index()', function () { 67692 67692 return this.iterator( 'row', function ( settings, row ) { … … 67694 67694 }, 1 ); 67695 67695 } ); 67696 67696 67697 67697 _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) { 67698 67698 var a = []; 67699 67699 var context = this.context; 67700 67700 67701 67701 // `iterator` will drop undefined values, but in this case we want them 67702 67702 for ( var i=0, ien=context.length ; i<ien ; i++ ) { … … 67706 67706 } 67707 67707 } 67708 67708 67709 67709 return new _Api( context, a ); 67710 67710 } ); 67711 67711 67712 67712 _api_registerPlural( 'rows().remove()', 'row().remove()', function () { 67713 67713 var that = this; 67714 67714 67715 67715 this.iterator( 'row', function ( settings, row, thatIdx ) { 67716 67716 var data = settings.aoData; … … 67718 67718 var i, ien, j, jen; 67719 67719 var loopRow, loopCells; 67720 67720 67721 67721 data.splice( row, 1 ); 67722 67722 67723 67723 // Update the cached indexes 67724 67724 for ( i=0, ien=data.length ; i<ien ; i++ ) { 67725 67725 loopRow = data[i]; 67726 67726 loopCells = loopRow.anCells; 67727 67727 67728 67728 // Rows 67729 67729 if ( loopRow.nTr !== null ) { 67730 67730 loopRow.nTr._DT_RowIndex = i; 67731 67731 } 67732 67732 67733 67733 // Cells 67734 67734 if ( loopCells !== null ) { … … 67738 67738 } 67739 67739 } 67740 67740 67741 67741 // Delete from the display arrays 67742 67742 _fnDeleteIndex( settings.aiDisplayMaster, row ); 67743 67743 _fnDeleteIndex( settings.aiDisplay, row ); 67744 67744 _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes 67745 67745 67746 67746 // For server-side processing tables - subtract the deleted row from the count 67747 67747 if ( settings._iRecordsDisplay > 0 ) { 67748 67748 settings._iRecordsDisplay--; 67749 67749 } 67750 67750 67751 67751 // Check for an 'overflow' they case for displaying the table 67752 67752 _fnLengthOverflow( settings ); 67753 67753 67754 67754 // Remove the row's ID reference if there is one 67755 67755 var id = settings.rowIdFn( rowData._aData ); … … 67758 67758 } 67759 67759 } ); 67760 67760 67761 67761 this.iterator( 'table', function ( settings ) { 67762 67762 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { … … 67764 67764 } 67765 67765 } ); 67766 67766 67767 67767 return this; 67768 67768 } ); 67769 67770 67769 67770 67771 67771 _api_register( 'rows.add()', function ( rows ) { 67772 67772 var newRows = this.iterator( 'table', function ( settings ) { 67773 67773 var row, i, ien; 67774 67774 var out = []; 67775 67775 67776 67776 for ( i=0, ien=rows.length ; i<ien ; i++ ) { 67777 67777 row = rows[i]; 67778 67778 67779 67779 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) { 67780 67780 out.push( _fnAddTr( settings, row )[0] ); … … 67784 67784 } 67785 67785 } 67786 67786 67787 67787 return out; 67788 67788 }, 1 ); 67789 67789 67790 67790 // Return an Api.rows() extended instance, so rows().nodes() etc can be used 67791 67791 var modRows = this.rows( -1 ); 67792 67792 modRows.pop(); 67793 67793 $.merge( modRows, newRows ); 67794 67794 67795 67795 return modRows; 67796 67796 } ); 67797 67798 67799 67800 67801 67797 67798 67799 67800 67801 67802 67802 /** 67803 67803 * … … 67806 67806 return _selector_first( this.rows( selector, opts ) ); 67807 67807 } ); 67808 67809 67808 67809 67810 67810 _api_register( 'row().data()', function ( data ) { 67811 67811 var ctx = this.context; 67812 67812 67813 67813 if ( data === undefined ) { 67814 67814 // Get … … 67817 67817 undefined; 67818 67818 } 67819 67819 67820 67820 // Set 67821 67821 var row = ctx[0].aoData[ this[0] ]; 67822 67822 row._aData = data; 67823 67823 67824 67824 // If the DOM has an id, and the data source is an array 67825 67825 if ( $.isArray( data ) && row.nTr.id ) { 67826 67826 _fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id ); 67827 67827 } 67828 67828 67829 67829 // Automatically invalidate 67830 67830 _fnInvalidate( ctx[0], this[0], 'data' ); 67831 67831 67832 67832 return this; 67833 67833 } ); 67834 67835 67834 67835 67836 67836 _api_register( 'row().node()', function () { 67837 67837 var ctx = this.context; 67838 67838 67839 67839 return ctx.length && this.length ? 67840 67840 ctx[0].aoData[ this[0] ].nTr || null : 67841 67841 null; 67842 67842 } ); 67843 67844 67843 67844 67845 67845 _api_register( 'row.add()', function ( row ) { 67846 67846 // Allow a jQuery object to be passed in - only a single row is added from … … 67849 67849 row = row[0]; 67850 67850 } 67851 67851 67852 67852 var rows = this.iterator( 'table', function ( settings ) { 67853 67853 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) { … … 67856 67856 return _fnAddData( settings, row ); 67857 67857 } ); 67858 67858 67859 67859 // Return an Api.rows() extended instance, with the newly added row selected 67860 67860 return this.row( rows[0] ); 67861 67861 } ); 67862 67863 67864 67862 67863 67864 67865 67865 var __details_add = function ( ctx, row, data, klass ) 67866 67866 { … … 67875 67875 return; 67876 67876 } 67877 67877 67878 67878 // If we get a TR element, then just add it directly - up to the dev 67879 67879 // to add the correct number of columns etc … … 67888 67888 .html( r ) 67889 67889 [0].colSpan = _fnVisbleColumns( ctx ); 67890 67890 67891 67891 rows.push( created[0] ); 67892 67892 } 67893 67893 }; 67894 67894 67895 67895 addRow( data, klass ); 67896 67896 67897 67897 if ( row._details ) { 67898 67898 row._details.detach(); 67899 67899 } 67900 67900 67901 67901 row._details = $(rows); 67902 67902 67903 67903 // If the children were already shown, that state should be retained 67904 67904 if ( row._detailsShow ) { … … 67906 67906 } 67907 67907 }; 67908 67909 67908 67909 67910 67910 var __details_remove = function ( api, idx ) 67911 67911 { 67912 67912 var ctx = api.context; 67913 67913 67914 67914 if ( ctx.length ) { 67915 67915 var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ]; 67916 67916 67917 67917 if ( row && row._details ) { 67918 67918 row._details.remove(); 67919 67919 67920 67920 row._detailsShow = undefined; 67921 67921 row._details = undefined; … … 67923 67923 } 67924 67924 }; 67925 67926 67925 67926 67927 67927 var __details_display = function ( api, show ) { 67928 67928 var ctx = api.context; 67929 67929 67930 67930 if ( ctx.length && api.length ) { 67931 67931 var row = ctx[0].aoData[ api[0] ]; 67932 67932 67933 67933 if ( row._details ) { 67934 67934 row._detailsShow = show; 67935 67935 67936 67936 if ( show ) { 67937 67937 row._details.insertAfter( row.nTr ); … … 67940 67940 row._details.detach(); 67941 67941 } 67942 67942 67943 67943 __details_events( ctx[0] ); 67944 67944 } 67945 67945 } 67946 67946 }; 67947 67948 67947 67948 67949 67949 var __details_events = function ( settings ) 67950 67950 { … … 67955 67955 var destroyEvent = 'destroy'+namespace; 67956 67956 var data = settings.aoData; 67957 67957 67958 67958 api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent ); 67959 67959 67960 67960 if ( _pluck( data, '_details' ).length > 0 ) { 67961 67961 // On each draw, insert the required elements into the document … … 67964 67964 return; 67965 67965 } 67966 67966 67967 67967 api.rows( {page:'current'} ).eq(0).each( function (idx) { 67968 67968 // Internal data grab 67969 67969 var row = data[ idx ]; 67970 67970 67971 67971 if ( row._detailsShow ) { 67972 67972 row._details.insertAfter( row.nTr ); … … 67974 67974 } ); 67975 67975 } ); 67976 67976 67977 67977 // Column visibility change - update the colspan 67978 67978 api.on( colvisEvent, function ( e, ctx, idx, vis ) { … … 67980 67980 return; 67981 67981 } 67982 67982 67983 67983 // Update the colspan for the details rows (note, only if it already has 67984 67984 // a colspan) 67985 67985 var row, visible = _fnVisbleColumns( ctx ); 67986 67986 67987 67987 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 67988 67988 row = data[i]; 67989 67989 67990 67990 if ( row._details ) { 67991 67991 row._details.children('td[colspan]').attr('colspan', visible ); … … 67993 67993 } 67994 67994 } ); 67995 67995 67996 67996 // Table destroyed - nuke any child rows 67997 67997 api.on( destroyEvent, function ( e, ctx ) { … … 67999 67999 return; 68000 68000 } 68001 68001 68002 68002 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 68003 68003 if ( data[i]._details ) { … … 68008 68008 } 68009 68009 }; 68010 68010 68011 68011 // Strings for the method names to help minification 68012 68012 var _emp = ''; 68013 68013 var _child_obj = _emp+'row().child'; 68014 68014 var _child_mth = _child_obj+'()'; 68015 68015 68016 68016 // data can be: 68017 68017 // tr … … 68020 68020 _api_register( _child_mth, function ( data, klass ) { 68021 68021 var ctx = this.context; 68022 68022 68023 68023 if ( data === undefined ) { 68024 68024 // get … … 68039 68039 __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass ); 68040 68040 } 68041 68041 68042 68042 return this; 68043 68043 } ); 68044 68045 68044 68045 68046 68046 _api_register( [ 68047 68047 _child_obj+'.show()', … … 68051 68051 return this; 68052 68052 } ); 68053 68054 68053 68054 68055 68055 _api_register( [ 68056 68056 _child_obj+'.hide()', … … 68060 68060 return this; 68061 68061 } ); 68062 68063 68062 68063 68064 68064 _api_register( [ 68065 68065 _child_obj+'.remove()', … … 68069 68069 return this; 68070 68070 } ); 68071 68072 68071 68072 68073 68073 _api_register( _child_obj+'.isShown()', function () { 68074 68074 var ctx = this.context; 68075 68075 68076 68076 if ( ctx.length && this.length ) { 68077 68077 // _detailsShown as false or undefined will fall through to return false … … 68080 68080 return false; 68081 68081 } ); 68082 68083 68084 68082 68083 68084 68085 68085 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 68086 68086 * Columns … … 68093 68093 * 68094 68094 */ 68095 68095 68096 68096 // can be an array of these items, comma separated list, or an array of comma 68097 68097 // separated lists 68098 68098 68099 68099 var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/; 68100 68101 68100 68101 68102 68102 // r1 and r2 are redundant - but it means that the parameters match for the 68103 68103 // iterator callback in columns().data() … … 68109 68109 return a; 68110 68110 }; 68111 68112 68111 68112 68113 68113 var __column_selector = function ( settings, selector, opts ) 68114 68114 { … … 68117 68117 names = _pluck( columns, 'sName' ), 68118 68118 nodes = _pluck( columns, 'nTh' ); 68119 68119 68120 68120 var run = function ( s ) { 68121 68121 var selInt = _intVal( s ); 68122 68122 68123 68123 // Selector - all 68124 68124 if ( s === '' ) { 68125 68125 return _range( columns.length ); 68126 68126 } 68127 68127 68128 68128 // Selector - index 68129 68129 if ( selInt !== null ) { … … 68133 68133 ]; 68134 68134 } 68135 68135 68136 68136 // Selector = function 68137 68137 if ( typeof s === 'function' ) { 68138 68138 var rows = _selector_row_indexes( settings, opts ); 68139 68139 68140 68140 return $.map( columns, function (col, idx) { 68141 68141 return s( … … 68146 68146 } ); 68147 68147 } 68148 68148 68149 68149 // jQuery or string selector 68150 68150 var match = typeof s === 'string' ? 68151 68151 s.match( __re_column_selector ) : 68152 68152 ''; 68153 68153 68154 68154 if ( match ) { 68155 68155 switch( match[2] ) { … … 68167 68167 // Counting from the left 68168 68168 return [ _fnVisibleToColumnIndex( settings, idx ) ]; 68169 68169 68170 68170 case 'name': 68171 68171 // match by name. `names` is column index complete and in order … … 68173 68173 return name === match[1] ? i : null; 68174 68174 } ); 68175 68175 68176 68176 default: 68177 68177 return []; 68178 68178 } 68179 68179 } 68180 68180 68181 68181 // Cell in the table body 68182 68182 if ( s.nodeName && s._DT_CellIndex ) { 68183 68183 return [ s._DT_CellIndex.column ]; 68184 68184 } 68185 68185 68186 68186 // jQuery selector on the TH elements for the columns 68187 68187 var jqResult = $( nodes ) … … 68191 68191 } ) 68192 68192 .toArray(); 68193 68193 68194 68194 if ( jqResult.length || ! s.nodeName ) { 68195 68195 return jqResult; 68196 68196 } 68197 68197 68198 68198 // Otherwise a node which might have a `dt-column` data attribute, or be 68199 68199 // a child or such an element … … 68203 68203 []; 68204 68204 }; 68205 68205 68206 68206 return _selector_run( 'column', selector, run, settings, opts ); 68207 68207 }; 68208 68209 68208 68209 68210 68210 var __setColumnVis = function ( settings, column, vis ) { 68211 68211 var … … 68214 68214 data = settings.aoData, 68215 68215 row, cells, i, ien, tr; 68216 68216 68217 68217 // Get 68218 68218 if ( vis === undefined ) { 68219 68219 return col.bVisible; 68220 68220 } 68221 68221 68222 68222 // Set 68223 68223 // No change … … 68225 68225 return; 68226 68226 } 68227 68227 68228 68228 if ( vis ) { 68229 68229 // Insert column 68230 68230 // Need to decide if we should use appendChild or insertBefore 68231 68231 var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 ); 68232 68232 68233 68233 for ( i=0, ien=data.length ; i<ien ; i++ ) { 68234 68234 tr = data[i].nTr; 68235 68235 cells = data[i].anCells; 68236 68236 68237 68237 if ( tr ) { 68238 68238 // insertBefore can act like appendChild if 2nd arg is null … … 68245 68245 $( _pluck( settings.aoData, 'anCells', column ) ).detach(); 68246 68246 } 68247 68247 68248 68248 // Common actions 68249 68249 col.bVisible = vis; 68250 68250 }; 68251 68252 68251 68252 68253 68253 _api_register( 'columns()', function ( selector, opts ) { 68254 68254 // argument shifting … … 68260 68260 selector = ''; 68261 68261 } 68262 68262 68263 68263 opts = _selector_opts( opts ); 68264 68264 68265 68265 var inst = this.iterator( 'table', function ( settings ) { 68266 68266 return __column_selector( settings, selector, opts ); 68267 68267 }, 1 ); 68268 68268 68269 68269 // Want argument shifting here and in _row_selector? 68270 68270 inst.selector.cols = selector; 68271 68271 inst.selector.opts = opts; 68272 68272 68273 68273 return inst; 68274 68274 } ); 68275 68275 68276 68276 _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) { 68277 68277 return this.iterator( 'column', function ( settings, column ) { … … 68279 68279 }, 1 ); 68280 68280 } ); 68281 68281 68282 68282 _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) { 68283 68283 return this.iterator( 'column', function ( settings, column ) { … … 68285 68285 }, 1 ); 68286 68286 } ); 68287 68287 68288 68288 _api_registerPlural( 'columns().data()', 'column().data()', function () { 68289 68289 return this.iterator( 'column-rows', __columnData, 1 ); 68290 68290 } ); 68291 68291 68292 68292 _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () { 68293 68293 return this.iterator( 'column', function ( settings, column ) { … … 68295 68295 }, 1 ); 68296 68296 } ); 68297 68297 68298 68298 _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) { 68299 68299 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) { … … 68303 68303 }, 1 ); 68304 68304 } ); 68305 68305 68306 68306 _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () { 68307 68307 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) { … … 68309 68309 }, 1 ); 68310 68310 } ); 68311 68311 68312 68312 _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) { 68313 68313 var that = this; … … 68318 68318 __setColumnVis( settings, column, vis ); 68319 68319 } ); 68320 68320 68321 68321 // Group the column visibility changes 68322 68322 if ( vis !== undefined ) { … … 68325 68325 _fnDrawHead( settings, settings.aoHeader ); 68326 68326 _fnDrawHead( settings, settings.aoFooter ); 68327 68327 68328 68328 // Update colspan for no records display. Child rows and extensions will use their own 68329 68329 // listeners to do this - only need to update the empty table item here … … 68331 68331 $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings)); 68332 68332 } 68333 68333 68334 68334 _fnSaveState( settings ); 68335 68335 68336 68336 // Second loop once the first is done for events 68337 68337 that.iterator( 'column', function ( settings, column ) { 68338 68338 _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] ); 68339 68339 } ); 68340 68340 68341 68341 if ( calc === undefined || calc ) { 68342 68342 that.columns.adjust(); … … 68344 68344 }); 68345 68345 } 68346 68346 68347 68347 return ret; 68348 68348 } ); 68349 68349 68350 68350 _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) { 68351 68351 return this.iterator( 'column', function ( settings, column ) { … … 68355 68355 }, 1 ); 68356 68356 } ); 68357 68357 68358 68358 _api_register( 'columns.adjust()', function () { 68359 68359 return this.iterator( 'table', function ( settings ) { … … 68361 68361 }, 1 ); 68362 68362 } ); 68363 68363 68364 68364 _api_register( 'column.index()', function ( type, idx ) { 68365 68365 if ( this.context.length !== 0 ) { 68366 68366 var ctx = this.context[0]; 68367 68367 68368 68368 if ( type === 'fromVisible' || type === 'toData' ) { 68369 68369 return _fnVisibleToColumnIndex( ctx, idx ); … … 68374 68374 } 68375 68375 } ); 68376 68376 68377 68377 _api_register( 'column()', function ( selector, opts ) { 68378 68378 return _selector_first( this.columns( selector, opts ) ); 68379 68379 } ); 68380 68381 68382 68380 68381 68382 68383 68383 var __cell_selector = function ( settings, selector, opts ) 68384 68384 { … … 68390 68390 var columns = settings.aoColumns.length; 68391 68391 var a, i, ien, j, o, host; 68392 68392 68393 68393 var run = function ( s ) { 68394 68394 var fnSelector = typeof s === 'function'; 68395 68395 68396 68396 if ( s === null || s === undefined || fnSelector ) { 68397 68397 // All cells and function selectors 68398 68398 a = []; 68399 68399 68400 68400 for ( i=0, ien=rows.length ; i<ien ; i++ ) { 68401 68401 row = rows[i]; 68402 68402 68403 68403 for ( j=0 ; j<columns ; j++ ) { 68404 68404 o = { … … 68406 68406 column: j 68407 68407 }; 68408 68408 68409 68409 if ( fnSelector ) { 68410 68410 // Selector - function 68411 68411 host = data[ row ]; 68412 68412 68413 68413 if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) { 68414 68414 a.push( o ); … … 68421 68421 } 68422 68422 } 68423 68423 68424 68424 return a; 68425 68425 } 68426 68426 68427 68427 // Selector - index 68428 68428 if ( $.isPlainObject( s ) ) { … … 68432 68432 []; 68433 68433 } 68434 68434 68435 68435 // Selector - jQuery filtered cells 68436 68436 var jqResult = allCells … … 68443 68443 } ) 68444 68444 .toArray(); 68445 68445 68446 68446 if ( jqResult.length || ! s.nodeName ) { 68447 68447 return jqResult; 68448 68448 } 68449 68449 68450 68450 // Otherwise the selector is a node, and there is one last option - the 68451 68451 // element might be a child of an element which has dt-row and dt-column … … 68459 68459 []; 68460 68460 }; 68461 68461 68462 68462 return _selector_run( 'cell', selector, run, settings, opts ); 68463 68463 }; 68464 68465 68466 68467 68464 68465 68466 68467 68468 68468 _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) { 68469 68469 // Argument shifting … … 68485 68485 columnSelector = null; 68486 68486 } 68487 68487 68488 68488 // Cell selector 68489 68489 if ( columnSelector === null || columnSelector === undefined ) { … … 68492 68492 } ); 68493 68493 } 68494 68494 68495 68495 // The default built in options need to apply to row and columns 68496 68496 var internalOpts = opts ? { … … 68499 68499 search: opts.search 68500 68500 } : {}; 68501 68501 68502 68502 // Row + column selector 68503 68503 var columns = this.columns( columnSelector, internalOpts ); 68504 68504 var rows = this.rows( rowSelector, internalOpts ); 68505 68505 var i, ien, j, jen; 68506 68506 68507 68507 var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) { 68508 68508 var a = []; 68509 68509 68510 68510 for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) { 68511 68511 for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) { … … 68516 68516 } 68517 68517 } 68518 68518 68519 68519 return a; 68520 68520 }, 1 ); 68521 68521 68522 68522 // There is currently only one extension which uses a cell selector extension 68523 68523 // It is a _major_ performance drag to run this if it isn't needed, so this is … … 68526 68526 this.cells( cellsNoOpts, opts ) : 68527 68527 cellsNoOpts; 68528 68528 68529 68529 $.extend( cells.selector, { 68530 68530 cols: columnSelector, … … 68532 68532 opts: opts 68533 68533 } ); 68534 68534 68535 68535 return cells; 68536 68536 } ); 68537 68538 68537 68538 68539 68539 _api_registerPlural( 'cells().nodes()', 'cell().node()', function () { 68540 68540 return this.iterator( 'cell', function ( settings, row, column ) { 68541 68541 var data = settings.aoData[ row ]; 68542 68542 68543 68543 return data && data.anCells ? 68544 68544 data.anCells[ column ] : … … 68546 68546 }, 1 ); 68547 68547 } ); 68548 68549 68548 68549 68550 68550 _api_register( 'cells().data()', function () { 68551 68551 return this.iterator( 'cell', function ( settings, row, column ) { … … 68553 68553 }, 1 ); 68554 68554 } ); 68555 68556 68555 68556 68557 68557 _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) { 68558 68558 type = type === 'search' ? '_aFilterData' : '_aSortData'; 68559 68559 68560 68560 return this.iterator( 'cell', function ( settings, row, column ) { 68561 68561 return settings.aoData[ row ][ type ][ column ]; 68562 68562 }, 1 ); 68563 68563 } ); 68564 68565 68564 68565 68566 68566 _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) { 68567 68567 return this.iterator( 'cell', function ( settings, row, column ) { … … 68569 68569 }, 1 ); 68570 68570 } ); 68571 68572 68571 68572 68573 68573 _api_registerPlural( 'cells().indexes()', 'cell().index()', function () { 68574 68574 return this.iterator( 'cell', function ( settings, row, column ) { … … 68580 68580 }, 1 ); 68581 68581 } ); 68582 68583 68582 68583 68584 68584 _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) { 68585 68585 return this.iterator( 'cell', function ( settings, row, column ) { … … 68587 68587 } ); 68588 68588 } ); 68589 68590 68591 68589 68590 68591 68592 68592 _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) { 68593 68593 return _selector_first( this.cells( rowSelector, columnSelector, opts ) ); 68594 68594 } ); 68595 68596 68595 68596 68597 68597 _api_register( 'cell().data()', function ( data ) { 68598 68598 var ctx = this.context; 68599 68599 var cell = this[0]; 68600 68600 68601 68601 if ( data === undefined ) { 68602 68602 // Get … … 68605 68605 undefined; 68606 68606 } 68607 68607 68608 68608 // Set 68609 68609 _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data ); 68610 68610 _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column ); 68611 68611 68612 68612 return this; 68613 68613 } ); 68614 68615 68616 68614 68615 68616 68617 68617 /** 68618 68618 * Get current ordering (sorting) that has been applied to the table. … … 68645 68645 _api_register( 'order()', function ( order, dir ) { 68646 68646 var ctx = this.context; 68647 68647 68648 68648 if ( order === undefined ) { 68649 68649 // get … … 68652 68652 undefined; 68653 68653 } 68654 68654 68655 68655 // set 68656 68656 if ( typeof order === 'number' ) { … … 68663 68663 } 68664 68664 // otherwise a 2D array was passed in 68665 68665 68666 68666 return this.iterator( 'table', function ( settings ) { 68667 68667 settings.aaSorting = order.slice(); 68668 68668 } ); 68669 68669 } ); 68670 68671 68670 68671 68672 68672 /** 68673 68673 * Attach a sort listener to an element for a given column … … 68685 68685 } ); 68686 68686 } ); 68687 68688 68687 68688 68689 68689 _api_register( 'order.fixed()', function ( set ) { 68690 68690 if ( ! set ) { … … 68693 68693 ctx[0].aaSortingFixed : 68694 68694 undefined; 68695 68695 68696 68696 return $.isArray( fixed ) ? 68697 68697 { pre: fixed } : 68698 68698 fixed; 68699 68699 } 68700 68700 68701 68701 return this.iterator( 'table', function ( settings ) { 68702 68702 settings.aaSortingFixed = $.extend( true, {}, set ); 68703 68703 } ); 68704 68704 } ); 68705 68706 68705 68706 68707 68707 // Order by the selected column(s) 68708 68708 _api_register( [ … … 68711 68711 ], function ( dir ) { 68712 68712 var that = this; 68713 68713 68714 68714 return this.iterator( 'table', function ( settings, i ) { 68715 68715 var sort = []; 68716 68716 68717 68717 $.each( that[i], function (j, col) { 68718 68718 sort.push( [ col, dir ] ); 68719 68719 } ); 68720 68720 68721 68721 settings.aaSorting = sort; 68722 68722 } ); 68723 68723 } ); 68724 68725 68726 68724 68725 68726 68727 68727 _api_register( 'search()', function ( input, regex, smart, caseInsen ) { 68728 68728 var ctx = this.context; 68729 68729 68730 68730 if ( input === undefined ) { 68731 68731 // get … … 68734 68734 undefined; 68735 68735 } 68736 68736 68737 68737 // set 68738 68738 return this.iterator( 'table', function ( settings ) { … … 68740 68740 return; 68741 68741 } 68742 68742 68743 68743 _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, { 68744 68744 "sSearch": input+"", … … 68749 68749 } ); 68750 68750 } ); 68751 68752 68751 68752 68753 68753 _api_registerPlural( 68754 68754 'columns().search()', … … 68757 68757 return this.iterator( 'column', function ( settings, column ) { 68758 68758 var preSearch = settings.aoPreSearchCols; 68759 68759 68760 68760 if ( input === undefined ) { 68761 68761 // get 68762 68762 return preSearch[ column ].sSearch; 68763 68763 } 68764 68764 68765 68765 // set 68766 68766 if ( ! settings.oFeatures.bFilter ) { 68767 68767 return; 68768 68768 } 68769 68769 68770 68770 $.extend( preSearch[ column ], { 68771 68771 "sSearch": input+"", … … 68774 68774 "bCaseInsensitive": caseInsen === null ? true : caseInsen 68775 68775 } ); 68776 68776 68777 68777 _fnFilterComplete( settings, settings.oPreviousSearch, 1 ); 68778 68778 } ); 68779 68779 } 68780 68780 ); 68781 68781 68782 68782 /* 68783 68783 * State API methods 68784 68784 */ 68785 68785 68786 68786 _api_register( 'state()', function () { 68787 68787 return this.context.length ? … … 68789 68789 null; 68790 68790 } ); 68791 68792 68791 68792 68793 68793 _api_register( 'state.clear()', function () { 68794 68794 return this.iterator( 'table', function ( settings ) { … … 68797 68797 } ); 68798 68798 } ); 68799 68800 68799 68800 68801 68801 _api_register( 'state.loaded()', function () { 68802 68802 return this.context.length ? … … 68804 68804 null; 68805 68805 } ); 68806 68807 68806 68807 68808 68808 _api_register( 'state.save()', function () { 68809 68809 return this.iterator( 'table', function ( settings ) { … … 68811 68811 } ); 68812 68812 } ); 68813 68814 68815 68813 68814 68815 68816 68816 /** 68817 68817 * Provide a common method for plug-ins to check the version of DataTables being … … 68834 68834 var aThat = version.split('.'); 68835 68835 var iThis, iThat; 68836 68836 68837 68837 for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) { 68838 68838 iThis = parseInt( aThis[i], 10 ) || 0; 68839 68839 iThat = parseInt( aThat[i], 10 ) || 0; 68840 68840 68841 68841 // Parts are the same, keep comparing 68842 68842 if (iThis === iThat) { 68843 68843 continue; 68844 68844 } 68845 68845 68846 68846 // Parts are different, return immediately 68847 68847 return iThis > iThat; 68848 68848 } 68849 68849 68850 68850 return true; 68851 68851 }; 68852 68853 68852 68853 68854 68854 /** 68855 68855 * Check if a `<table>` node is a DataTable table already or not. … … 68871 68871 var t = $(table).get(0); 68872 68872 var is = false; 68873 68873 68874 68874 if ( table instanceof DataTable.Api ) { 68875 68875 return true; 68876 68876 } 68877 68877 68878 68878 $.each( DataTable.settings, function (i, o) { 68879 68879 var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null; 68880 68880 var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null; 68881 68881 68882 68882 if ( o.nTable === t || head === t || foot === t ) { 68883 68883 is = true; 68884 68884 } 68885 68885 } ); 68886 68886 68887 68887 return is; 68888 68888 }; 68889 68890 68889 68890 68891 68891 /** 68892 68892 * Get all DataTable tables that have been initialised - optionally you can … … 68908 68908 { 68909 68909 var api = false; 68910 68910 68911 68911 if ( $.isPlainObject( visible ) ) { 68912 68912 api = visible.api; 68913 68913 visible = visible.visible; 68914 68914 } 68915 68915 68916 68916 var a = $.map( DataTable.settings, function (o) { 68917 68917 if ( !visible || (visible && $(o.nTable).is(':visible')) ) { … … 68919 68919 } 68920 68920 } ); 68921 68921 68922 68922 return api ? 68923 68923 new _Api( a ) : 68924 68924 a; 68925 68925 }; 68926 68927 68926 68927 68928 68928 /** 68929 68929 * Convert from camel case parameters to Hungarian notation. This is made public … … 68940 68940 */ 68941 68941 DataTable.camelToHungarian = _fnCamelToHungarian; 68942 68943 68944 68942 68943 68944 68945 68945 /** 68946 68946 * … … 68950 68950 rows = this.rows( opts ).nodes(), // Get all rows 68951 68951 jqRows = $(rows); 68952 68952 68953 68953 return $( [].concat( 68954 68954 jqRows.filter( selector ).toArray(), … … 68956 68956 ) ); 68957 68957 } ); 68958 68959 68958 68959 68960 68960 // jQuery functions to operate on the tables 68961 68961 $.each( [ 'on', 'one', 'off' ], function (i, key) { 68962 68962 _api_register( key+'()', function ( /* event, handler */ ) { 68963 68963 var args = Array.prototype.slice.call(arguments); 68964 68964 68965 68965 // Add the `dt` namespace automatically if it isn't already present 68966 68966 args[0] = $.map( args[0].split( /\s/ ), function ( e ) { … … 68969 68969 e; 68970 68970 } ).join( ' ' ); 68971 68971 68972 68972 var inst = $( this.tables().nodes() ); 68973 68973 inst[key].apply( inst, args ); … … 68975 68975 } ); 68976 68976 } ); 68977 68978 68977 68978 68979 68979 _api_register( 'clear()', function () { 68980 68980 return this.iterator( 'table', function ( settings ) { … … 68982 68982 } ); 68983 68983 } ); 68984 68985 68984 68985 68986 68986 _api_register( 'settings()', function () { 68987 68987 return new _Api( this.context, this.context ); 68988 68988 } ); 68989 68990 68989 68990 68991 68991 _api_register( 'init()', function () { 68992 68992 var ctx = this.context; 68993 68993 return ctx.length ? ctx[0].oInit : null; 68994 68994 } ); 68995 68996 68995 68996 68997 68997 _api_register( 'data()', function () { 68998 68998 return this.iterator( 'table', function ( settings ) { … … 69000 69000 } ).flatten(); 69001 69001 } ); 69002 69003 69002 69003 69004 69004 _api_register( 'destroy()', function ( remove ) { 69005 69005 remove = remove || false; 69006 69006 69007 69007 return this.iterator( 'table', function ( settings ) { 69008 69008 var orig = settings.nTableWrapper.parentNode; … … 69017 69017 var rows = $.map( settings.aoData, function (r) { return r.nTr; } ); 69018 69018 var i, ien; 69019 69019 69020 69020 // Flag to note that the table is currently being destroyed - no action 69021 69021 // should be taken 69022 69022 settings.bDestroying = true; 69023 69023 69024 69024 // Fire off the destroy callbacks for plug-ins etc 69025 69025 _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] ); 69026 69026 69027 69027 // If not being removed from the document, make all columns visible 69028 69028 if ( ! remove ) { 69029 69029 new _Api( settings ).columns().visible( true ); 69030 69030 } 69031 69031 69032 69032 // Blitz all `DT` namespaced events (these are internal events, the 69033 69033 // lowercase, `dt` events are user subscribed and they are responsible … … 69035 69035 jqWrapper.off('.DT').find(':not(tbody *)').off('.DT'); 69036 69036 $(window).off('.DT-'+settings.sInstance); 69037 69037 69038 69038 // When scrolling we had to break the table up - restore it 69039 69039 if ( table != thead.parentNode ) { … … 69041 69041 jqTable.append( thead ); 69042 69042 } 69043 69043 69044 69044 if ( tfoot && table != tfoot.parentNode ) { 69045 69045 jqTable.children('tfoot').detach(); 69046 69046 jqTable.append( tfoot ); 69047 69047 } 69048 69048 69049 69049 settings.aaSorting = []; 69050 69050 settings.aaSortingFixed = []; 69051 69051 _fnSortingClasses( settings ); 69052 69052 69053 69053 $( rows ).removeClass( settings.asStripeClasses.join(' ') ); 69054 69054 69055 69055 $('th, td', thead).removeClass( classes.sSortable+' '+ 69056 69056 classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone 69057 69057 ); 69058 69058 69059 69059 // Add the TR elements back into the table in their original order 69060 69060 jqTbody.children().detach(); 69061 69061 jqTbody.append( rows ); 69062 69062 69063 69063 // Remove the DataTables generated nodes, events and classes 69064 69064 var removedMethod = remove ? 'remove' : 'detach'; 69065 69065 jqTable[ removedMethod ](); 69066 69066 jqWrapper[ removedMethod ](); 69067 69067 69068 69068 // If we need to reattach the table to the document 69069 69069 if ( ! remove && orig ) { 69070 69070 // insertBefore acts like appendChild if !arg[1] 69071 69071 orig.insertBefore( table, settings.nTableReinsertBefore ); 69072 69072 69073 69073 // Restore the width of the original table - was read from the style property, 69074 69074 // so we can restore directly to that … … 69076 69076 .css( 'width', settings.sDestroyWidth ) 69077 69077 .removeClass( classes.sTable ); 69078 69078 69079 69079 // If the were originally stripe classes - then we add them back here. 69080 69080 // Note this is not fool proof (for example if not all rows had stripe 69081 69081 // classes - but it's a good effort without getting carried away 69082 69082 ien = settings.asDestroyStripes.length; 69083 69083 69084 69084 if ( ien ) { 69085 69085 jqTbody.children().each( function (i) { … … 69088 69088 } 69089 69089 } 69090 69090 69091 69091 /* Remove the settings object from the settings array */ 69092 69092 var idx = $.inArray( settings, DataTable.settings ); … … 69096 69096 } ); 69097 69097 } ); 69098 69099 69098 69099 69100 69100 // Add the `every()` method for rows, columns and cells in a compact form 69101 69101 $.each( [ 'column', 'row', 'cell' ], function ( i, type ) { … … 69103 69103 var opts = this.selector.opts; 69104 69104 var api = this; 69105 69105 69106 69106 return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) { 69107 69107 // Rows and columns: … … 69126 69126 } ); 69127 69127 } ); 69128 69129 69128 69129 69130 69130 // i18n method for extensions to be able to use the language object from the 69131 69131 // DataTable … … 69133 69133 var ctx = this.context[0]; 69134 69134 var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage ); 69135 69135 69136 69136 if ( resolved === undefined ) { 69137 69137 resolved = def; 69138 69138 } 69139 69139 69140 69140 if ( plural !== undefined && $.isPlainObject( resolved ) ) { 69141 69141 resolved = resolved[ plural ] !== undefined ? … … 69143 69143 resolved._; 69144 69144 } 69145 69145 69146 69146 return resolved.replace( '%d', plural ); // nb: plural might be undefined, 69147 69147 } ); … … 69177 69177 */ 69178 69178 DataTable.models = {}; 69179 69180 69181 69179 69180 69181 69182 69182 /** 69183 69183 * Template object for the way in which DataTables holds information about … … 69192 69192 */ 69193 69193 "bCaseInsensitive": true, 69194 69194 69195 69195 /** 69196 69196 * Applied search term … … 69199 69199 */ 69200 69200 "sSearch": "", 69201 69201 69202 69202 /** 69203 69203 * Flag to indicate if the search term should be interpreted as a … … 69208 69208 */ 69209 69209 "bRegex": false, 69210 69210 69211 69211 /** 69212 69212 * Flag to indicate if DataTables is to use its smart filtering or not. … … 69216 69216 "bSmart": true 69217 69217 }; 69218 69219 69220 69221 69218 69219 69220 69221 69222 69222 /** 69223 69223 * Template object for the way in which DataTables holds information about … … 69233 69233 */ 69234 69234 "nTr": null, 69235 69235 69236 69236 /** 69237 69237 * Array of TD elements for each row. This is null until the row has been … … 69241 69241 */ 69242 69242 "anCells": null, 69243 69243 69244 69244 /** 69245 69245 * Data object from the original data source for the row. This is either … … 69252 69252 */ 69253 69253 "_aData": [], 69254 69254 69255 69255 /** 69256 69256 * Sorting data cache - this array is ostensibly the same length as the … … 69266 69266 */ 69267 69267 "_aSortData": null, 69268 69268 69269 69269 /** 69270 69270 * Per cell filtering data cache. As per the sort data cache, used to … … 69275 69275 */ 69276 69276 "_aFilterData": null, 69277 69277 69278 69278 /** 69279 69279 * Filtering data cache. This is the same as the cell filtering cache, but … … 69286 69286 */ 69287 69287 "_sFilterRow": null, 69288 69288 69289 69289 /** 69290 69290 * Cache of the class name that DataTables has applied to the row, so we … … 69296 69296 */ 69297 69297 "_sRowStripe": "", 69298 69298 69299 69299 /** 69300 69300 * Denote if the original data source was from the DOM, or the data source … … 69307 69307 */ 69308 69308 "src": null, 69309 69309 69310 69310 /** 69311 69311 * Index in the aoData array. This saves an indexOf lookup when we have the … … 69317 69317 "idx": -1 69318 69318 }; 69319 69320 69319 69320 69321 69321 /** 69322 69322 * Template object for the column information object in DataTables. This object … … 69338 69338 */ 69339 69339 "idx": null, 69340 69340 69341 69341 /** 69342 69342 * A list of the columns that sorting should occur on when this column … … 69349 69349 */ 69350 69350 "aDataSort": null, 69351 69351 69352 69352 /** 69353 69353 * Define the sorting directions that are applied to the column, in sequence … … 69359 69359 */ 69360 69360 "asSorting": null, 69361 69361 69362 69362 /** 69363 69363 * Flag to indicate if the column is searchable, and thus should be included … … 69366 69366 */ 69367 69367 "bSearchable": null, 69368 69368 69369 69369 /** 69370 69370 * Flag to indicate if the column is sortable or not. … … 69372 69372 */ 69373 69373 "bSortable": null, 69374 69374 69375 69375 /** 69376 69376 * Flag to indicate if the column is currently visible in the table or not … … 69378 69378 */ 69379 69379 "bVisible": null, 69380 69380 69381 69381 /** 69382 69382 * Store for manual type assignment using the `column.type` option. This … … 69387 69387 */ 69388 69388 "_sManualType": null, 69389 69389 69390 69390 /** 69391 69391 * Flag to indicate if HTML5 data attributes should be used as the data … … 69396 69396 */ 69397 69397 "_bAttrSrc": false, 69398 69398 69399 69399 /** 69400 69400 * Developer definable function that is called whenever a cell is created (Ajax source, … … 69410 69410 */ 69411 69411 "fnCreatedCell": null, 69412 69412 69413 69413 /** 69414 69414 * Function to get data from a cell in a column. You should <b>never</b> … … 69426 69426 */ 69427 69427 "fnGetData": null, 69428 69428 69429 69429 /** 69430 69430 * Function to set data for a cell in the column. You should <b>never</b> … … 69439 69439 */ 69440 69440 "fnSetData": null, 69441 69441 69442 69442 /** 69443 69443 * Property to read the value for the cells in the column from the data … … 69448 69448 */ 69449 69449 "mData": null, 69450 69450 69451 69451 /** 69452 69452 * Partner property to mData which is used (only when defined) to get … … 69458 69458 */ 69459 69459 "mRender": null, 69460 69460 69461 69461 /** 69462 69462 * Unique header TH/TD element for this column - this is what the sorting … … 69466 69466 */ 69467 69467 "nTh": null, 69468 69468 69469 69469 /** 69470 69470 * Unique footer TH/TD element for this column (if there is one). Not used … … 69475 69475 */ 69476 69476 "nTf": null, 69477 69477 69478 69478 /** 69479 69479 * The class to apply to all TD elements in the table's TBODY for the column … … 69482 69482 */ 69483 69483 "sClass": null, 69484 69484 69485 69485 /** 69486 69486 * When DataTables calculates the column widths to assign to each column, … … 69495 69495 */ 69496 69496 "sContentPadding": null, 69497 69497 69498 69498 /** 69499 69499 * Allows a default value to be given for a column's data, and will be used … … 69504 69504 */ 69505 69505 "sDefaultContent": null, 69506 69506 69507 69507 /** 69508 69508 * Name for the column, allowing reference to the column by name as well as … … 69511 69511 */ 69512 69512 "sName": null, 69513 69513 69514 69514 /** 69515 69515 * Custom sorting data type - defines which of the available plug-ins in … … 69519 69519 */ 69520 69520 "sSortDataType": 'std', 69521 69521 69522 69522 /** 69523 69523 * Class to be applied to the header element when sorting on this column … … 69526 69526 */ 69527 69527 "sSortingClass": null, 69528 69528 69529 69529 /** 69530 69530 * Class to be applied to the header element when sorting on this column - … … 69534 69534 */ 69535 69535 "sSortingClassJUI": null, 69536 69536 69537 69537 /** 69538 69538 * Title of the column - what is seen in the TH element (nTh). … … 69540 69540 */ 69541 69541 "sTitle": null, 69542 69542 69543 69543 /** 69544 69544 * Column sorting and filtering type … … 69547 69547 */ 69548 69548 "sType": null, 69549 69549 69550 69550 /** 69551 69551 * Width of the column … … 69554 69554 */ 69555 69555 "sWidth": null, 69556 69556 69557 69557 /** 69558 69558 * Width of the column when it was first "encountered" … … 69562 69562 "sWidthOrig": null 69563 69563 }; 69564 69565 69564 69565 69566 69566 /* 69567 69567 * Developer note: The properties of the object below are given in Hungarian … … 69579 69579 * installs (therefore is on-hold until v2). 69580 69580 */ 69581 69581 69582 69582 /** 69583 69583 * Initialisation options that can be given to DataTables at initialisation … … 69646 69646 */ 69647 69647 "aaData": null, 69648 69649 69648 69649 69650 69650 /** 69651 69651 * If ordering is enabled, then DataTables will perform a first pass sort on … … 69676 69676 */ 69677 69677 "aaSorting": [[0,'asc']], 69678 69679 69678 69679 69680 69680 /** 69681 69681 * This parameter is basically identical to the `sorting` parameter, but … … 69699 69699 */ 69700 69700 "aaSortingFixed": [], 69701 69702 69701 69702 69703 69703 /** 69704 69704 * DataTables can be instructed to load data to display in the table from a … … 69856 69856 */ 69857 69857 "ajax": null, 69858 69859 69858 69859 69860 69860 /** 69861 69861 * This parameter allows you to readily specify the entries in the length drop … … 69882 69882 */ 69883 69883 "aLengthMenu": [ 10, 25, 50, 100 ], 69884 69885 69884 69885 69886 69886 /** 69887 69887 * The `columns` option in the initialisation parameter allows you to define … … 69897 69897 */ 69898 69898 "aoColumns": null, 69899 69899 69900 69900 /** 69901 69901 * Very similar to `columns`, `columnDefs` allows you to target a specific … … 69918 69918 */ 69919 69919 "aoColumnDefs": null, 69920 69921 69920 69921 69922 69922 /** 69923 69923 * Basically the same as `search`, this parameter defines the individual column … … 69945 69945 */ 69946 69946 "aoSearchCols": [], 69947 69948 69947 69948 69949 69949 /** 69950 69950 * An array of CSS classes that should be applied to displayed rows. This … … 69966 69966 */ 69967 69967 "asStripeClasses": null, 69968 69969 69968 69969 69970 69970 /** 69971 69971 * Enable or disable automatic column width calculation. This can be disabled … … 69986 69986 */ 69987 69987 "bAutoWidth": true, 69988 69989 69988 69989 69990 69990 /** 69991 69991 * Deferred rendering can provide DataTables with a huge speed boost when you … … 70009 70009 */ 70010 70010 "bDeferRender": false, 70011 70012 70011 70012 70013 70013 /** 70014 70014 * Replace a DataTable which matches the given selector and replace it with … … 70037 70037 */ 70038 70038 "bDestroy": false, 70039 70040 70039 70040 70041 70041 /** 70042 70042 * Enable or disable filtering of data. Filtering in DataTables is "smart" in … … 70061 70061 */ 70062 70062 "bFilter": true, 70063 70064 70063 70064 70065 70065 /** 70066 70066 * Enable or disable the table information display. This shows information … … 70081 70081 */ 70082 70082 "bInfo": true, 70083 70084 70083 70084 70085 70085 /** 70086 70086 * Allows the end user to select the size of a formatted page from a select … … 70100 70100 */ 70101 70101 "bLengthChange": true, 70102 70103 70102 70103 70104 70104 /** 70105 70105 * Enable or disable pagination. … … 70118 70118 */ 70119 70119 "bPaginate": true, 70120 70121 70120 70121 70122 70122 /** 70123 70123 * Enable or disable the display of a 'processing' indicator when the table is … … 70139 70139 */ 70140 70140 "bProcessing": false, 70141 70142 70141 70142 70143 70143 /** 70144 70144 * Retrieve the DataTables object for the given selector. Note that if the … … 70177 70177 */ 70178 70178 "bRetrieve": false, 70179 70180 70179 70180 70181 70181 /** 70182 70182 * When vertical (y) scrolling is enabled, DataTables will force the height of … … 70201 70201 */ 70202 70202 "bScrollCollapse": false, 70203 70204 70203 70204 70205 70205 /** 70206 70206 * Configure DataTables to use server-side processing. Note that the … … 70223 70223 */ 70224 70224 "bServerSide": false, 70225 70226 70225 70226 70227 70227 /** 70228 70228 * Enable or disable sorting of columns. Sorting of individual columns can be … … 70242 70242 */ 70243 70243 "bSort": true, 70244 70245 70244 70245 70246 70246 /** 70247 70247 * Enable or display DataTables' ability to sort multiple columns at the … … 70262 70262 */ 70263 70263 "bSortMulti": true, 70264 70265 70264 70265 70266 70266 /** 70267 70267 * Allows control over whether DataTables should use the top (true) unique … … 70282 70282 */ 70283 70283 "bSortCellsTop": false, 70284 70285 70284 70285 70286 70286 /** 70287 70287 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and … … 70304 70304 */ 70305 70305 "bSortClasses": true, 70306 70307 70306 70307 70308 70308 /** 70309 70309 * Enable or disable state saving. When enabled HTML5 `localStorage` will be … … 70329 70329 */ 70330 70330 "bStateSave": false, 70331 70332 70331 70332 70333 70333 /** 70334 70334 * This function is called when a TR element is created (and all TD child … … 70357 70357 */ 70358 70358 "fnCreatedRow": null, 70359 70360 70359 70360 70361 70361 /** 70362 70362 * This function is called on every 'draw' event, and allows you to … … 70378 70378 */ 70379 70379 "fnDrawCallback": null, 70380 70381 70380 70381 70382 70382 /** 70383 70383 * Identical to fnHeaderCallback() but for the table footer this function … … 70406 70406 */ 70407 70407 "fnFooterCallback": null, 70408 70409 70408 70409 70410 70410 /** 70411 70411 * When rendering large numbers in the information element for the table … … 70441 70441 ); 70442 70442 }, 70443 70444 70443 70444 70445 70445 /** 70446 70446 * This function is called on every 'draw' event, and allows you to … … 70470 70470 */ 70471 70471 "fnHeaderCallback": null, 70472 70473 70472 70473 70474 70474 /** 70475 70475 * The information element can be used to convey information about the current … … 70500 70500 */ 70501 70501 "fnInfoCallback": null, 70502 70503 70502 70503 70504 70504 /** 70505 70505 * Called when the table has been initialised. Normally DataTables will … … 70525 70525 */ 70526 70526 "fnInitComplete": null, 70527 70528 70527 70528 70529 70529 /** 70530 70530 * Called at the very start of each table draw and can be used to cancel the … … 70551 70551 */ 70552 70552 "fnPreDrawCallback": null, 70553 70554 70553 70554 70555 70555 /** 70556 70556 * This function allows you to 'post process' each row after it have been … … 70580 70580 */ 70581 70581 "fnRowCallback": null, 70582 70583 70582 70583 70584 70584 /** 70585 70585 * __Deprecated__ The functionality provided by this parameter has now been … … 70606 70606 */ 70607 70607 "fnServerData": null, 70608 70609 70608 70609 70610 70610 /** 70611 70611 * __Deprecated__ The functionality provided by this parameter has now been … … 70633 70633 */ 70634 70634 "fnServerParams": null, 70635 70636 70635 70636 70637 70637 /** 70638 70638 * Load the table state. With this function you can define from where, and how, the … … 70674 70674 } catch (e) {} 70675 70675 }, 70676 70677 70676 70677 70678 70678 /** 70679 70679 * Callback which allows modification of the saved state prior to loading that state. … … 70712 70712 */ 70713 70713 "fnStateLoadParams": null, 70714 70715 70714 70715 70716 70716 /** 70717 70717 * Callback that is called when the state has been loaded from the state saving method … … 70736 70736 */ 70737 70737 "fnStateLoaded": null, 70738 70739 70738 70739 70740 70740 /** 70741 70741 * Save the table state. This function allows you to define where and how the state … … 70775 70775 } catch (e) {} 70776 70776 }, 70777 70778 70777 70778 70779 70779 /** 70780 70780 * Callback which allows modification of the state to be saved. Called when the table … … 70802 70802 */ 70803 70803 "fnStateSaveParams": null, 70804 70805 70804 70805 70806 70806 /** 70807 70807 * Duration for which the saved state information is considered valid. After this period … … 70822 70822 */ 70823 70823 "iStateDuration": 7200, 70824 70825 70824 70825 70826 70826 /** 70827 70827 * When enabled DataTables will not make a request to the server for the first … … 70866 70866 */ 70867 70867 "iDeferLoading": null, 70868 70869 70868 70869 70870 70870 /** 70871 70871 * Number of rows to display on a single page when using pagination. If … … 70886 70886 */ 70887 70887 "iDisplayLength": 10, 70888 70889 70888 70889 70890 70890 /** 70891 70891 * Define the starting point for data display when using DataTables with … … 70907 70907 */ 70908 70908 "iDisplayStart": 0, 70909 70910 70909 70910 70911 70911 /** 70912 70912 * By default DataTables allows keyboard navigation of the table (sorting, paging, … … 70930 70930 */ 70931 70931 "iTabIndex": 0, 70932 70933 70932 70933 70934 70934 /** 70935 70935 * Classes that DataTables assigns to the various components and features … … 70941 70941 */ 70942 70942 "oClasses": {}, 70943 70944 70943 70944 70945 70945 /** 70946 70946 * All strings that DataTables uses in the user interface that it creates … … 70981 70981 */ 70982 70982 "sSortAscending": ": activate to sort column ascending", 70983 70983 70984 70984 /** 70985 70985 * ARIA label that is added to the table headers when the column may be … … 71005 71005 "sSortDescending": ": activate to sort column descending" 71006 71006 }, 71007 71007 71008 71008 /** 71009 71009 * Pagination string used by DataTables for the built-in pagination … … 71034 71034 */ 71035 71035 "sFirst": "First", 71036 71037 71036 71037 71038 71038 /** 71039 71039 * Text to use when using the 'full_numbers' type of pagination for the … … 71057 71057 */ 71058 71058 "sLast": "Last", 71059 71060 71059 71060 71061 71061 /** 71062 71062 * Text to use for the 'next' pagination button (to take the user to the … … 71080 71080 */ 71081 71081 "sNext": "Next", 71082 71083 71082 71083 71084 71084 /** 71085 71085 * Text to use for the 'previous' pagination button (to take the user to … … 71104 71104 "sPrevious": "Previous" 71105 71105 }, 71106 71106 71107 71107 /** 71108 71108 * This string is shown in preference to `zeroRecords` when the table is … … 71126 71126 */ 71127 71127 "sEmptyTable": "No data available in table", 71128 71129 71128 71129 71130 71130 /** 71131 71131 * This string gives information to the end user about the information … … 71158 71158 */ 71159 71159 "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", 71160 71161 71160 71161 71162 71162 /** 71163 71163 * Display information string for when the table is empty. Typically the … … 71179 71179 */ 71180 71180 "sInfoEmpty": "Showing 0 to 0 of 0 entries", 71181 71182 71181 71182 71183 71183 /** 71184 71184 * When a user filters the information in a table, this string is appended … … 71201 71201 */ 71202 71202 "sInfoFiltered": "(filtered from _MAX_ total entries)", 71203 71204 71203 71204 71205 71205 /** 71206 71206 * If can be useful to append extra information to the info string at times, … … 71224 71224 */ 71225 71225 "sInfoPostFix": "", 71226 71227 71226 71227 71228 71228 /** 71229 71229 * This decimal place operator is a little different from the other … … 71239 71239 * decimal place characters. 71240 71240 * @type string 71241 * @default 71241 * @default 71242 71242 * 71243 71243 * @dtopt Language … … 71255 71255 */ 71256 71256 "sDecimal": "", 71257 71258 71257 71258 71259 71259 /** 71260 71260 * DataTables has a build in number formatter (`formatNumber`) which is … … 71278 71278 */ 71279 71279 "sThousands": ",", 71280 71281 71280 71281 71282 71282 /** 71283 71283 * Detail the action that will be taken when the drop down menu for the … … 71319 71319 */ 71320 71320 "sLengthMenu": "Show _MENU_ entries", 71321 71322 71321 71322 71323 71323 /** 71324 71324 * When using Ajax sourced data and during the first draw when DataTables is … … 71343 71343 */ 71344 71344 "sLoadingRecords": "Loading...", 71345 71346 71345 71346 71347 71347 /** 71348 71348 * Text which is displayed when the table is processing a user action … … 71364 71364 */ 71365 71365 "sProcessing": "Processing...", 71366 71367 71366 71367 71368 71368 /** 71369 71369 * Details the actions that will be taken when the user types into the … … 71399 71399 */ 71400 71400 "sSearch": "Search:", 71401 71402 71401 71402 71403 71403 /** 71404 71404 * Assign a `placeholder` attribute to the search `input` element 71405 71405 * @type string 71406 * @default 71406 * @default 71407 71407 * 71408 71408 * @dtopt Language … … 71410 71410 */ 71411 71411 "sSearchPlaceholder": "", 71412 71413 71412 71413 71414 71414 /** 71415 71415 * All of the language information can be stored in a file on the … … 71435 71435 */ 71436 71436 "sUrl": "", 71437 71438 71437 71438 71439 71439 /** 71440 71440 * Text shown inside the table records when the is no information to be … … 71458 71458 "sZeroRecords": "No matching records found" 71459 71459 }, 71460 71461 71460 71461 71462 71462 /** 71463 71463 * This parameter allows you to have define the global filtering state at … … 71482 71482 */ 71483 71483 "oSearch": $.extend( {}, DataTable.models.oSearch ), 71484 71485 71484 71485 71486 71486 /** 71487 71487 * __Deprecated__ The functionality provided by this parameter has now been … … 71503 71503 */ 71504 71504 "sAjaxDataProp": "data", 71505 71506 71505 71506 71507 71507 /** 71508 71508 * __Deprecated__ The functionality provided by this parameter has now been … … 71522 71522 */ 71523 71523 "sAjaxSource": null, 71524 71525 71524 71525 71526 71526 /** 71527 71527 * This initialisation variable allows you to specify exactly where in the … … 71576 71576 */ 71577 71577 "sDom": "lfrtip", 71578 71579 71578 71579 71580 71580 /** 71581 71581 * Search delay option. This will throttle full table searches that use the … … 71596 71596 */ 71597 71597 "searchDelay": null, 71598 71599 71598 71599 71600 71600 /** 71601 71601 * DataTables features six different built-in options for the buttons to … … 71608 71608 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers 71609 71609 * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers 71610 * 71610 * 71611 71611 * Further methods can be added using {@link DataTable.ext.oPagination}. 71612 71612 * @type string … … 71624 71624 */ 71625 71625 "sPaginationType": "simple_numbers", 71626 71627 71626 71627 71628 71628 /** 71629 71629 * Enable horizontal scrolling. When a table is too wide to fit into a … … 71649 71649 */ 71650 71650 "sScrollX": "", 71651 71652 71651 71652 71653 71653 /** 71654 71654 * This property can be used to force a DataTable to use more width than it … … 71673 71673 */ 71674 71674 "sScrollXInner": "", 71675 71676 71675 71676 71677 71677 /** 71678 71678 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable … … 71697 71697 */ 71698 71698 "sScrollY": "", 71699 71700 71699 71700 71701 71701 /** 71702 71702 * __Deprecated__ The functionality provided by this parameter has now been … … 71715 71715 */ 71716 71716 "sServerMethod": "GET", 71717 71718 71717 71718 71719 71719 /** 71720 71720 * DataTables makes use of renderers when displaying HTML elements for … … 71733 71733 */ 71734 71734 "renderer": null, 71735 71736 71735 71736 71737 71737 /** 71738 71738 * Set the data property name that DataTables should use to get a row's id … … 71745 71745 "rowId": "DT_RowId" 71746 71746 }; 71747 71747 71748 71748 _fnHungarianMap( DataTable.defaults ); 71749 71750 71751 71749 71750 71751 71752 71752 /* 71753 71753 * Developer note - See note in model.defaults.js about the use of Hungarian 71754 71754 * notation and camel case. 71755 71755 */ 71756 71756 71757 71757 /** 71758 71758 * Column options that can be given to DataTables at initialisation time. … … 71800 71800 "aDataSort": null, 71801 71801 "iDataSort": -1, 71802 71803 71802 71803 71804 71804 /** 71805 71805 * You can control the default ordering direction, and even alter the … … 71839 71839 */ 71840 71840 "asSorting": [ 'asc', 'desc' ], 71841 71842 71841 71842 71843 71843 /** 71844 71844 * Enable or disable filtering on the data in this column. … … 71872 71872 */ 71873 71873 "bSearchable": true, 71874 71875 71874 71875 71876 71876 /** 71877 71877 * Enable or disable ordering on this column. … … 71905 71905 */ 71906 71906 "bSortable": true, 71907 71908 71907 71908 71909 71909 /** 71910 71910 * Enable or disable the display of this column. … … 71938 71938 */ 71939 71939 "bVisible": true, 71940 71941 71940 71941 71942 71942 /** 71943 71943 * Developer definable function that is called whenever a cell is created (Ajax source, … … 71970 71970 */ 71971 71971 "fnCreatedCell": null, 71972 71973 71972 71973 71974 71974 /** 71975 71975 * This parameter has been replaced by `data` in DataTables to ensure naming … … 71979 71979 * @name DataTable.defaults.column.dataProp 71980 71980 */ 71981 71982 71981 71982 71983 71983 /** 71984 71984 * This property can be used to read data from any data source property, … … 72151 72151 */ 72152 72152 "mData": null, 72153 72154 72153 72154 72155 72155 /** 72156 72156 * This property is the rendering partner to `data` and it is suggested that … … 72273 72273 */ 72274 72274 "mRender": null, 72275 72276 72275 72276 72277 72277 /** 72278 72278 * Change the cell type created for the column - either TD cells or TH cells. This … … 72297 72297 */ 72298 72298 "sCellType": "td", 72299 72300 72299 72300 72301 72301 /** 72302 72302 * Class to give to each cell in this column. … … 72332 72332 */ 72333 72333 "sClass": "", 72334 72334 72335 72335 /** 72336 72336 * When DataTables calculates the column widths to assign to each column, … … 72365 72365 */ 72366 72366 "sContentPadding": "", 72367 72368 72367 72368 72369 72369 /** 72370 72370 * Allows a default value to be given for a column's data, and will be used … … 72408 72408 */ 72409 72409 "sDefaultContent": null, 72410 72411 72410 72411 72412 72412 /** 72413 72413 * This parameter is only used in DataTables' server-side processing. It can … … 72452 72452 */ 72453 72453 "sName": "", 72454 72455 72454 72455 72456 72456 /** 72457 72457 * Defines a data source type for the ordering which can be used to read … … 72494 72494 */ 72495 72495 "sSortDataType": "std", 72496 72497 72496 72497 72498 72498 /** 72499 72499 * The title of this column. … … 72530 72530 */ 72531 72531 "sTitle": null, 72532 72533 72532 72533 72534 72534 /** 72535 72535 * The type allows you to specify how the data for this column will be … … 72571 72571 */ 72572 72572 "sType": null, 72573 72574 72573 72574 72575 72575 /** 72576 72576 * Defining the width of the column, this parameter may take any CSS value … … 72610 72610 "sWidth": null 72611 72611 }; 72612 72612 72613 72613 _fnHungarianMap( DataTable.defaults.column ); 72614 72615 72616 72614 72615 72616 72617 72617 /** 72618 72618 * DataTables settings object - this holds all the information needed for a … … 72643 72643 */ 72644 72644 "oFeatures": { 72645 72645 72646 72646 /** 72647 72647 * Flag to say if DataTables should automatically try to calculate the … … 72652 72652 */ 72653 72653 "bAutoWidth": null, 72654 72654 72655 72655 /** 72656 72656 * Delay the creation of TR and TD elements until they are actually … … 72663 72663 */ 72664 72664 "bDeferRender": null, 72665 72665 72666 72666 /** 72667 72667 * Enable filtering on the table or not. Note that if this is disabled … … 72673 72673 */ 72674 72674 "bFilter": null, 72675 72675 72676 72676 /** 72677 72677 * Table information element (the 'Showing x of y records' div) enable … … 72682 72682 */ 72683 72683 "bInfo": null, 72684 72684 72685 72685 /** 72686 72686 * Present a user control allowing the end user to change the page size … … 72691 72691 */ 72692 72692 "bLengthChange": null, 72693 72693 72694 72694 /** 72695 72695 * Pagination enabled or not. Note that if this is disabled then length … … 72700 72700 */ 72701 72701 "bPaginate": null, 72702 72702 72703 72703 /** 72704 72704 * Processing indicator enable flag whenever DataTables is enacting a … … 72709 72709 */ 72710 72710 "bProcessing": null, 72711 72711 72712 72712 /** 72713 72713 * Server-side processing enabled flag - when enabled DataTables will … … 72719 72719 */ 72720 72720 "bServerSide": null, 72721 72721 72722 72722 /** 72723 72723 * Sorting enablement flag. … … 72727 72727 */ 72728 72728 "bSort": null, 72729 72729 72730 72730 /** 72731 72731 * Multi-column sorting … … 72735 72735 */ 72736 72736 "bSortMulti": null, 72737 72737 72738 72738 /** 72739 72739 * Apply a class to the columns which are being sorted to provide a … … 72745 72745 */ 72746 72746 "bSortClasses": null, 72747 72747 72748 72748 /** 72749 72749 * State saving enablement flag. … … 72754 72754 "bStateSave": null 72755 72755 }, 72756 72757 72756 72757 72758 72758 /** 72759 72759 * Scrolling settings for a table. … … 72769 72769 */ 72770 72770 "bCollapse": null, 72771 72771 72772 72772 /** 72773 72773 * Width of the scrollbar for the web-browser's platform. Calculated … … 72777 72777 */ 72778 72778 "iBarWidth": 0, 72779 72779 72780 72780 /** 72781 72781 * Viewport width for horizontal scrolling. Horizontal scrolling is … … 72786 72786 */ 72787 72787 "sX": null, 72788 72788 72789 72789 /** 72790 72790 * Width to expand the table to when using x-scrolling. Typically you … … 72796 72796 */ 72797 72797 "sXInner": null, 72798 72798 72799 72799 /** 72800 72800 * Viewport height for vertical scrolling. Vertical scrolling is disabled … … 72806 72806 "sY": null 72807 72807 }, 72808 72808 72809 72809 /** 72810 72810 * Language information for the table. … … 72821 72821 "fnInfoCallback": null 72822 72822 }, 72823 72823 72824 72824 /** 72825 72825 * Browser support parameters … … 72834 72834 */ 72835 72835 "bScrollOversize": false, 72836 72836 72837 72837 /** 72838 72838 * Determine if the vertical scrollbar is on the right or left of the … … 72843 72843 */ 72844 72844 "bScrollbarLeft": false, 72845 72845 72846 72846 /** 72847 72847 * Flag for if `getBoundingClientRect` is fully supported or not … … 72850 72850 */ 72851 72851 "bBounding": false, 72852 72852 72853 72853 /** 72854 72854 * Browser scrollbar width … … 72858 72858 "barWidth": 0 72859 72859 }, 72860 72861 72860 72861 72862 72862 "ajax": null, 72863 72864 72863 72864 72865 72865 /** 72866 72866 * Array referencing the nodes which are used for the features. The … … 72878 72878 */ 72879 72879 "aanFeatures": [], 72880 72880 72881 72881 /** 72882 72882 * Store data information - see {@link DataTable.models.oRow} for detailed … … 72886 72886 */ 72887 72887 "aoData": [], 72888 72888 72889 72889 /** 72890 72890 * Array of indexes which are in the current display (after filtering etc) … … 72893 72893 */ 72894 72894 "aiDisplay": [], 72895 72895 72896 72896 /** 72897 72897 * Array of indexes for display - no filtering … … 72900 72900 */ 72901 72901 "aiDisplayMaster": [], 72902 72902 72903 72903 /** 72904 72904 * Map of row ids to data indexes … … 72907 72907 */ 72908 72908 "aIds": {}, 72909 72909 72910 72910 /** 72911 72911 * Store information about each column that is in use … … 72914 72914 */ 72915 72915 "aoColumns": [], 72916 72916 72917 72917 /** 72918 72918 * Store information about the table's header … … 72921 72921 */ 72922 72922 "aoHeader": [], 72923 72923 72924 72924 /** 72925 72925 * Store information about the table's footer … … 72928 72928 */ 72929 72929 "aoFooter": [], 72930 72930 72931 72931 /** 72932 72932 * Store the applied global search information in case we want to force a … … 72938 72938 */ 72939 72939 "oPreviousSearch": {}, 72940 72940 72941 72941 /** 72942 72942 * Store the applied search for each column - see … … 72947 72947 */ 72948 72948 "aoPreSearchCols": [], 72949 72949 72950 72950 /** 72951 72951 * Sorting that is applied to the table. Note that the inner arrays are … … 72961 72961 */ 72962 72962 "aaSorting": null, 72963 72963 72964 72964 /** 72965 72965 * Sorting that is always applied to the table (i.e. prefixed in front of … … 72971 72971 */ 72972 72972 "aaSortingFixed": [], 72973 72973 72974 72974 /** 72975 72975 * Classes to use for the striping of a table. … … 72980 72980 */ 72981 72981 "asStripeClasses": null, 72982 72982 72983 72983 /** 72984 72984 * If restoring a table - we should restore its striping classes as well … … 72987 72987 */ 72988 72988 "asDestroyStripes": [], 72989 72989 72990 72990 /** 72991 72991 * If restoring a table - we should restore its width … … 72994 72994 */ 72995 72995 "sDestroyWidth": 0, 72996 72996 72997 72997 /** 72998 72998 * Callback functions array for every time a row is inserted (i.e. on a draw). … … 73001 73001 */ 73002 73002 "aoRowCallback": [], 73003 73003 73004 73004 /** 73005 73005 * Callback functions for the header on each draw. … … 73008 73008 */ 73009 73009 "aoHeaderCallback": [], 73010 73010 73011 73011 /** 73012 73012 * Callback function for the footer on each draw. … … 73015 73015 */ 73016 73016 "aoFooterCallback": [], 73017 73017 73018 73018 /** 73019 73019 * Array of callback functions for draw callback functions … … 73022 73022 */ 73023 73023 "aoDrawCallback": [], 73024 73024 73025 73025 /** 73026 73026 * Array of callback functions for row created function … … 73029 73029 */ 73030 73030 "aoRowCreatedCallback": [], 73031 73031 73032 73032 /** 73033 73033 * Callback functions for just before the table is redrawn. A return of … … 73037 73037 */ 73038 73038 "aoPreDrawCallback": [], 73039 73039 73040 73040 /** 73041 73041 * Callback functions for when the table has been initialised. … … 73044 73044 */ 73045 73045 "aoInitComplete": [], 73046 73047 73046 73047 73048 73048 /** 73049 73049 * Callbacks for modifying the settings to be stored for state saving, prior to … … 73053 73053 */ 73054 73054 "aoStateSaveParams": [], 73055 73055 73056 73056 /** 73057 73057 * Callbacks for modifying the settings that have been stored for state saving … … 73061 73061 */ 73062 73062 "aoStateLoadParams": [], 73063 73063 73064 73064 /** 73065 73065 * Callbacks for operating on the settings object once the saved state has been … … 73069 73069 */ 73070 73070 "aoStateLoaded": [], 73071 73071 73072 73072 /** 73073 73073 * Cache the table ID for quick access … … 73076 73076 */ 73077 73077 "sTableId": "", 73078 73078 73079 73079 /** 73080 73080 * The TABLE node for the main table … … 73083 73083 */ 73084 73084 "nTable": null, 73085 73085 73086 73086 /** 73087 73087 * Permanent ref to the thead element … … 73090 73090 */ 73091 73091 "nTHead": null, 73092 73092 73093 73093 /** 73094 73094 * Permanent ref to the tfoot element - if it exists … … 73097 73097 */ 73098 73098 "nTFoot": null, 73099 73099 73100 73100 /** 73101 73101 * Permanent ref to the tbody element … … 73104 73104 */ 73105 73105 "nTBody": null, 73106 73106 73107 73107 /** 73108 73108 * Cache the wrapper node (contains all DataTables controlled elements) … … 73111 73111 */ 73112 73112 "nTableWrapper": null, 73113 73113 73114 73114 /** 73115 73115 * Indicate if when using server-side processing the loading of data … … 73121 73121 */ 73122 73122 "bDeferLoading": false, 73123 73123 73124 73124 /** 73125 73125 * Indicate if all required information has been read in … … 73128 73128 */ 73129 73129 "bInitialised": false, 73130 73130 73131 73131 /** 73132 73132 * Information about open rows. Each object in the array has the parameters … … 73136 73136 */ 73137 73137 "aoOpenRows": [], 73138 73138 73139 73139 /** 73140 73140 * Dictate the positioning of DataTables' control elements - see … … 73146 73146 */ 73147 73147 "sDom": null, 73148 73148 73149 73149 /** 73150 73150 * Search delay (in mS) … … 73153 73153 */ 73154 73154 "searchDelay": null, 73155 73155 73156 73156 /** 73157 73157 * Which type of pagination should be used. … … 73162 73162 */ 73163 73163 "sPaginationType": "two_button", 73164 73164 73165 73165 /** 73166 73166 * The state duration (for `stateSave`) in seconds. … … 73171 73171 */ 73172 73172 "iStateDuration": 0, 73173 73173 73174 73174 /** 73175 73175 * Array of callback functions for state saving. Each array element is an … … 73186 73186 */ 73187 73187 "aoStateSave": [], 73188 73188 73189 73189 /** 73190 73190 * Array of callback functions for state loading. Each array element is an … … 73199 73199 */ 73200 73200 "aoStateLoad": [], 73201 73201 73202 73202 /** 73203 73203 * State that was saved. Useful for back reference … … 73206 73206 */ 73207 73207 "oSavedState": null, 73208 73208 73209 73209 /** 73210 73210 * State that was loaded. Useful for back reference … … 73213 73213 */ 73214 73214 "oLoadedState": null, 73215 73215 73216 73216 /** 73217 73217 * Source url for AJAX data for the table. … … 73222 73222 */ 73223 73223 "sAjaxSource": null, 73224 73224 73225 73225 /** 73226 73226 * Property from a given object from which to read the table data from. This … … 73232 73232 */ 73233 73233 "sAjaxDataProp": null, 73234 73234 73235 73235 /** 73236 73236 * Note if draw should be blocked while getting data … … 73239 73239 */ 73240 73240 "bAjaxDataGet": true, 73241 73241 73242 73242 /** 73243 73243 * The last jQuery XHR object that was used for server-side data gathering. … … 73248 73248 */ 73249 73249 "jqXHR": null, 73250 73250 73251 73251 /** 73252 73252 * JSON returned from the server in the last Ajax request … … 73255 73255 */ 73256 73256 "json": undefined, 73257 73257 73258 73258 /** 73259 73259 * Data submitted as part of the last Ajax request … … 73262 73262 */ 73263 73263 "oAjaxData": undefined, 73264 73264 73265 73265 /** 73266 73266 * Function to get the server-side data. … … 73270 73270 */ 73271 73271 "fnServerData": null, 73272 73272 73273 73273 /** 73274 73274 * Functions which are called prior to sending an Ajax request so extra … … 73278 73278 */ 73279 73279 "aoServerParams": [], 73280 73280 73281 73281 /** 73282 73282 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if … … 73287 73287 */ 73288 73288 "sServerMethod": null, 73289 73289 73290 73290 /** 73291 73291 * Format numbers for display. … … 73295 73295 */ 73296 73296 "fnFormatNumber": null, 73297 73297 73298 73298 /** 73299 73299 * List of options that can be used for the user selectable length menu. … … 73304 73304 */ 73305 73305 "aLengthMenu": null, 73306 73306 73307 73307 /** 73308 73308 * Counter for the draws that the table does. Also used as a tracker for … … 73312 73312 */ 73313 73313 "iDraw": 0, 73314 73314 73315 73315 /** 73316 73316 * Indicate if a redraw is being done - useful for Ajax … … 73319 73319 */ 73320 73320 "bDrawing": false, 73321 73321 73322 73322 /** 73323 73323 * Draw index (iDraw) of the last error when parsing the returned data … … 73326 73326 */ 73327 73327 "iDrawError": -1, 73328 73328 73329 73329 /** 73330 73330 * Paging display length … … 73333 73333 */ 73334 73334 "_iDisplayLength": 10, 73335 73335 73336 73336 /** 73337 73337 * Paging start point - aiDisplay index … … 73340 73340 */ 73341 73341 "_iDisplayStart": 0, 73342 73342 73343 73343 /** 73344 73344 * Server-side processing - number of records in the result set … … 73351 73351 */ 73352 73352 "_iRecordsTotal": 0, 73353 73353 73354 73354 /** 73355 73355 * Server-side processing - number of records in the current display set … … 73362 73362 */ 73363 73363 "_iRecordsDisplay": 0, 73364 73364 73365 73365 /** 73366 73366 * The classes to use for the table … … 73369 73369 */ 73370 73370 "oClasses": {}, 73371 73371 73372 73372 /** 73373 73373 * Flag attached to the settings object so you can check in the draw … … 73379 73379 */ 73380 73380 "bFiltered": false, 73381 73381 73382 73382 /** 73383 73383 * Flag attached to the settings object so you can check in the draw … … 73389 73389 */ 73390 73390 "bSorted": false, 73391 73391 73392 73392 /** 73393 73393 * Indicate that if multiple rows are in the header and there is more than … … 73399 73399 */ 73400 73400 "bSortCellsTop": null, 73401 73401 73402 73402 /** 73403 73403 * Initialisation object that is used for the table … … 73406 73406 */ 73407 73407 "oInit": null, 73408 73408 73409 73409 /** 73410 73410 * Destroy callback functions - for plug-ins to attach themselves to the … … 73414 73414 */ 73415 73415 "aoDestroyCallback": [], 73416 73417 73416 73417 73418 73418 /** 73419 73419 * Get the number of records in the current record set, before filtering … … 73426 73426 this.aiDisplayMaster.length; 73427 73427 }, 73428 73428 73429 73429 /** 73430 73430 * Get the number of records in the current record set, after filtering … … 73437 73437 this.aiDisplay.length; 73438 73438 }, 73439 73439 73440 73440 /** 73441 73441 * Get the display end point - aiDisplay index … … 73451 73451 features = this.oFeatures, 73452 73452 paginate = features.bPaginate; 73453 73453 73454 73454 if ( features.bServerSide ) { 73455 73455 return paginate === false || len === -1 ? … … 73463 73463 } 73464 73464 }, 73465 73465 73466 73466 /** 73467 73467 * The DataTables object for this table … … 73470 73470 */ 73471 73471 "oInstance": null, 73472 73472 73473 73473 /** 73474 73474 * Unique identifier for each instance of the DataTables object. If there … … 73479 73479 */ 73480 73480 "sInstance": null, 73481 73481 73482 73482 /** 73483 73483 * tabindex attribute value that is added to DataTables control elements, allowing … … 73485 73485 */ 73486 73486 "iTabIndex": 0, 73487 73487 73488 73488 /** 73489 73489 * DIV container for the footer scrolling table if scrolling 73490 73490 */ 73491 73491 "nScrollHead": null, 73492 73492 73493 73493 /** 73494 73494 * DIV container for the footer scrolling table if scrolling 73495 73495 */ 73496 73496 "nScrollFoot": null, 73497 73497 73498 73498 /** 73499 73499 * Last applied sort … … 73502 73502 */ 73503 73503 "aLastSort": [], 73504 73504 73505 73505 /** 73506 73506 * Stored plug-in instances … … 73509 73509 */ 73510 73510 "oPlugins": {}, 73511 73511 73512 73512 /** 73513 73513 * Function used to get a row's id from the row's data … … 73516 73516 */ 73517 73517 "rowIdFn": null, 73518 73518 73519 73519 /** 73520 73520 * Data location where to store a row's id … … 73535 73535 * @extends DataTable.models.ext 73536 73536 */ 73537 73538 73537 73538 73539 73539 /** 73540 73540 * DataTables extensions 73541 * 73541 * 73542 73542 * This namespace acts as a collection area for plug-ins that can be used to 73543 73543 * extend DataTables capabilities. Indeed many of the build in methods … … 73560 73560 */ 73561 73561 buttons: {}, 73562 73563 73562 73563 73564 73564 /** 73565 73565 * Element class names … … 73569 73569 */ 73570 73570 classes: {}, 73571 73572 73571 73572 73573 73573 /** 73574 73574 * DataTables build type (expanded by the download builder) … … 73577 73577 */ 73578 73578 build:"bs4/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.20/af-2.3.4/b-1.6.1/b-colvis-1.6.1/b-flash-1.6.1/b-html5-1.6.1/b-print-1.6.1/cr-1.5.2/fc-3.3.0/fh-3.1.6/kt-2.5.1/r-2.2.3/rg-1.1.1/rr-1.2.6/sc-2.0.1/sp-1.0.1/sl-1.3.1", 73579 73580 73579 73580 73581 73581 /** 73582 73582 * Error reporting. 73583 * 73583 * 73584 73584 * How should DataTables report an error. Can take the value 'alert', 73585 73585 * 'throw', 'none' or a function. … … 73589 73589 */ 73590 73590 errMode: "alert", 73591 73592 73591 73592 73593 73593 /** 73594 73594 * Feature plug-ins. 73595 * 73595 * 73596 73596 * This is an array of objects which describe the feature plug-ins that are 73597 73597 * available to DataTables. These feature plug-ins are then available for 73598 73598 * use through the `dom` initialisation option. 73599 * 73599 * 73600 73600 * Each feature plug-in is described by an object which must have the 73601 73601 * following properties: 73602 * 73602 * 73603 73603 * * `fnInit` - function that is used to initialise the plug-in, 73604 73604 * * `cFeature` - a character so the feature can be enabled by the `dom` … … 73611 73611 * 73612 73612 * And the following return is expected: 73613 * 73613 * 73614 73614 * * {node|null} The element which contains your feature. Note that the 73615 73615 * return may also be void if your plug-in does not require to inject any … … 73629 73629 */ 73630 73630 feature: [], 73631 73632 73631 73632 73633 73633 /** 73634 73634 * Row searching. 73635 * 73635 * 73636 73636 * This method of searching is complimentary to the default type based 73637 73637 * searching, and a lot more comprehensive as it allows you complete control … … 73690 73690 */ 73691 73691 search: [], 73692 73693 73692 73693 73694 73694 /** 73695 73695 * Selector extensions … … 73721 73721 row: [] 73722 73722 }, 73723 73724 73723 73724 73725 73725 /** 73726 73726 * Internal functions, exposed for used in plug-ins. 73727 * 73727 * 73728 73728 * Please note that you should not need to use the internal methods for 73729 73729 * anything other than a plug-in (and even then, try to avoid if possible). … … 73734 73734 */ 73735 73735 internal: {}, 73736 73737 73736 73737 73738 73738 /** 73739 73739 * Legacy configuration options. Enable and disable legacy options that … … 73752 73752 ajax: null 73753 73753 }, 73754 73755 73754 73755 73756 73756 /** 73757 73757 * Pagination plug-in methods. 73758 * 73758 * 73759 73759 * Each entry in this object is a function and defines which buttons should 73760 73760 * be shown by the pagination rendering method that is used for the table: … … 73800 73800 */ 73801 73801 pager: {}, 73802 73803 73802 73803 73804 73804 renderer: { 73805 73805 pageButton: {}, 73806 73806 header: {} 73807 73807 }, 73808 73809 73808 73809 73810 73810 /** 73811 73811 * Ordering plug-ins - custom data source 73812 * 73812 * 73813 73813 * The extension options for ordering of data available here is complimentary 73814 73814 * to the default type based ordering that DataTables typically uses. It 73815 73815 * allows much greater control over the the data that is being used to 73816 73816 * order a column, but is necessarily therefore more complex. 73817 * 73817 * 73818 73818 * This type of ordering is useful if you want to do ordering based on data 73819 73819 * live from the DOM (for example the contents of an 'input' element) rather 73820 73820 * than just the static string that DataTables knows of. 73821 * 73821 * 73822 73822 * The way these plug-ins work is that you create an array of the values you 73823 73823 * wish to be ordering for the column in question and then return that … … 73849 73849 */ 73850 73850 order: {}, 73851 73852 73851 73852 73853 73853 /** 73854 73854 * Type based plug-ins. … … 73903 73903 */ 73904 73904 detect: [], 73905 73906 73905 73906 73907 73907 /** 73908 73908 * Type based search formatting. … … 73914 73914 * Note that is a search is not defined for a column of a given type, 73915 73915 * no search formatting will be performed. 73916 * 73916 * 73917 73917 * Pre-processing of searching data plug-ins - When you assign the sType 73918 73918 * for a column (or have it automatically detected for you by DataTables … … 73942 73942 */ 73943 73943 search: {}, 73944 73945 73944 73945 73946 73946 /** 73947 73947 * Type based ordering. … … 73984 73984 * >0 if the first parameter should be sorted height than the second 73985 73985 * parameter. 73986 * 73986 * 73987 73987 * @type object 73988 73988 * @default {} … … 74010 74010 order: {} 74011 74011 }, 74012 74012 74013 74013 /** 74014 74014 * Unique DataTables instance counter … … 74018 74018 */ 74019 74019 _unique: 0, 74020 74021 74020 74021 74022 74022 // 74023 74023 // Depreciated … … 74026 74026 // version 74027 74027 // 74028 74028 74029 74029 /** 74030 74030 * Version check function. … … 74033 74033 */ 74034 74034 fnVersionCheck: DataTable.fnVersionCheck, 74035 74036 74035 74036 74037 74037 /** 74038 74038 * Index for what 'this' index API functions should use … … 74041 74041 */ 74042 74042 iApiIndex: 0, 74043 74044 74043 74044 74045 74045 /** 74046 74046 * jQuery UI class container … … 74049 74049 */ 74050 74050 oJUIClasses: {}, 74051 74052 74051 74052 74053 74053 /** 74054 74054 * Software version … … 74058 74058 sVersion: DataTable.version 74059 74059 }; 74060 74061 74060 74061 74062 74062 // 74063 74063 // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts … … 74074 74074 oPagination: _ext.pager 74075 74075 } ); 74076 74077 74076 74077 74078 74078 $.extend( DataTable.ext.classes, { 74079 74079 "sTable": "dataTable", 74080 74080 "sNoFooter": "no-footer", 74081 74081 74082 74082 /* Paging buttons */ 74083 74083 "sPageButton": "paginate_button", 74084 74084 "sPageButtonActive": "current", 74085 74085 "sPageButtonDisabled": "disabled", 74086 74086 74087 74087 /* Striping classes */ 74088 74088 "sStripeOdd": "odd", 74089 74089 "sStripeEven": "even", 74090 74090 74091 74091 /* Empty row */ 74092 74092 "sRowEmpty": "dataTables_empty", 74093 74093 74094 74094 /* Features */ 74095 74095 "sWrapper": "dataTables_wrapper", … … 74099 74099 "sLength": "dataTables_length", 74100 74100 "sProcessing": "dataTables_processing", 74101 74101 74102 74102 /* Sorting */ 74103 74103 "sSortAsc": "sorting_asc", … … 74108 74108 "sSortableNone": "sorting_disabled", 74109 74109 "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ 74110 74110 74111 74111 /* Filtering */ 74112 74112 "sFilterInput": "", 74113 74113 74114 74114 /* Page length */ 74115 74115 "sLengthSelect": "", 74116 74116 74117 74117 /* Scrolling */ 74118 74118 "sScrollWrapper": "dataTables_scroll", … … 74122 74122 "sScrollFoot": "dataTables_scrollFoot", 74123 74123 "sScrollFootInner": "dataTables_scrollFootInner", 74124 74124 74125 74125 /* Misc */ 74126 74126 "sHeaderTH": "", 74127 74127 "sFooterTH": "", 74128 74128 74129 74129 // Deprecated 74130 74130 "sSortJUIAsc": "", … … 74138 74138 "sJUIFooter": "" 74139 74139 } ); 74140 74141 74140 74141 74142 74142 var extPagination = DataTable.ext.pager; 74143 74143 74144 74144 function _numbers ( page, pages ) { 74145 74145 var … … 74148 74148 half = Math.floor( buttons / 2 ), 74149 74149 i = 1; 74150 74150 74151 74151 if ( pages <= buttons ) { 74152 74152 numbers = _range( 0, pages ); … … 74169 74169 numbers.splice( 0, 0, 0 ); 74170 74170 } 74171 74171 74172 74172 numbers.DT_el = 'span'; 74173 74173 return numbers; 74174 74174 } 74175 74176 74175 74176 74177 74177 $.extend( extPagination, { 74178 74178 simple: function ( page, pages ) { 74179 74179 return [ 'previous', 'next' ]; 74180 74180 }, 74181 74181 74182 74182 full: function ( page, pages ) { 74183 74183 return [ 'first', 'previous', 'next', 'last' ]; 74184 74184 }, 74185 74185 74186 74186 numbers: function ( page, pages ) { 74187 74187 return [ _numbers(page, pages) ]; 74188 74188 }, 74189 74189 74190 74190 simple_numbers: function ( page, pages ) { 74191 74191 return [ 'previous', _numbers(page, pages), 'next' ]; 74192 74192 }, 74193 74193 74194 74194 full_numbers: function ( page, pages ) { 74195 74195 return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ]; 74196 74196 }, 74197 74197 74198 74198 first_last_numbers: function (page, pages) { 74199 74199 return ['first', _numbers(page, pages), 'last']; 74200 74200 }, 74201 74201 74202 74202 // For testing and plug-ins to use 74203 74203 _numbers: _numbers, 74204 74204 74205 74205 // Number of number buttons (including ellipsis) to show. _Must be odd!_ 74206 74206 numbers_length: 7 74207 74207 } ); 74208 74209 74208 74209 74210 74210 $.extend( true, DataTable.ext.renderer, { 74211 74211 pageButton: { … … 74215 74215 var aria = settings.oLanguage.oAria.paginate || {}; 74216 74216 var btnDisplay, btnClass, counter=0; 74217 74217 74218 74218 var attach = function( container, buttons ) { 74219 74219 var i, ien, node, button, tabIndex; … … 74222 74222 _fnPageChange( settings, e.data.action, true ); 74223 74223 }; 74224 74224 74225 74225 for ( i=0, ien=buttons.length ; i<ien ; i++ ) { 74226 74226 button = buttons[i]; 74227 74227 74228 74228 if ( $.isArray( button ) ) { 74229 74229 var inner = $( '<'+(button.DT_el || 'div')+'/>' ) … … 74235 74235 btnClass = button; 74236 74236 tabIndex = settings.iTabIndex; 74237 74237 74238 74238 switch ( button ) { 74239 74239 case 'ellipsis': 74240 74240 container.append('<span class="ellipsis">…</span>'); 74241 74241 break; 74242 74242 74243 74243 case 'first': 74244 74244 btnDisplay = lang.sFirst; 74245 74245 74246 74246 if ( page === 0 ) { 74247 74247 tabIndex = -1; … … 74249 74249 } 74250 74250 break; 74251 74251 74252 74252 case 'previous': 74253 74253 btnDisplay = lang.sPrevious; 74254 74254 74255 74255 if ( page === 0 ) { 74256 74256 tabIndex = -1; … … 74258 74258 } 74259 74259 break; 74260 74260 74261 74261 case 'next': 74262 74262 btnDisplay = lang.sNext; 74263 74263 74264 74264 if ( page === pages-1 ) { 74265 74265 tabIndex = -1; … … 74267 74267 } 74268 74268 break; 74269 74269 74270 74270 case 'last': 74271 74271 btnDisplay = lang.sLast; 74272 74272 74273 74273 if ( page === pages-1 ) { 74274 74274 tabIndex = -1; … … 74276 74276 } 74277 74277 break; 74278 74278 74279 74279 default: 74280 74280 btnDisplay = button + 1; … … 74283 74283 break; 74284 74284 } 74285 74285 74286 74286 if ( btnDisplay !== null ) { 74287 74287 node = $('<a>', { … … 74297 74297 .html( btnDisplay ) 74298 74298 .appendTo( container ); 74299 74299 74300 74300 _fnBindAction( 74301 74301 node, {action: button}, clickHandler 74302 74302 ); 74303 74303 74304 74304 counter++; 74305 74305 } … … 74307 74307 } 74308 74308 }; 74309 74309 74310 74310 // IE9 throws an 'unknown error' if document.activeElement is used 74311 74311 // inside an iframe or frame. Try / catch the error. Not good for 74312 74312 // accessibility, but neither are frames. 74313 74313 var activeEl; 74314 74314 74315 74315 try { 74316 74316 // Because this approach is destroying and recreating the paging … … 74321 74321 } 74322 74322 catch (e) {} 74323 74323 74324 74324 attach( $(host).empty(), buttons ); 74325 74325 74326 74326 if ( activeEl !== undefined ) { 74327 74327 $(host).find( '[data-dt-idx='+activeEl+']' ).focus(); … … 74330 74330 } 74331 74331 } ); 74332 74333 74334 74332 74333 74334 74335 74335 // Built in type detection. See model.ext.aTypes for information about 74336 74336 // what is required from this methods. … … 74343 74343 return _isNumber( d, decimal ) ? 'num'+decimal : null; 74344 74344 }, 74345 74345 74346 74346 // Dates (only those recognised by the browser's Date.parse) 74347 74347 function ( d, settings ) … … 74356 74356 return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null; 74357 74357 }, 74358 74358 74359 74359 // Formatted numbers 74360 74360 function ( d, settings ) … … 74363 74363 return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null; 74364 74364 }, 74365 74365 74366 74366 // HTML numeric 74367 74367 function ( d, settings ) … … 74370 74370 return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null; 74371 74371 }, 74372 74372 74373 74373 // HTML numeric, formatted 74374 74374 function ( d, settings ) … … 74377 74377 return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null; 74378 74378 }, 74379 74379 74380 74380 // HTML (this is strict checking - there must be html) 74381 74381 function ( d, settings ) … … 74385 74385 } 74386 74386 ] ); 74387 74388 74389 74387 74388 74389 74390 74390 // Filter formatting functions. See model.ext.ofnSearch for information about 74391 74391 // what is required from these methods. 74392 // 74392 // 74393 74393 // Note that additional search methods are added for the html numbers and 74394 74394 // html formatted numbers by `_addNumericSort()` when we know what the decimal 74395 74395 // place is 74396 74397 74396 74397 74398 74398 $.extend( DataTable.ext.type.search, { 74399 74399 html: function ( data ) { … … 74406 74406 ''; 74407 74407 }, 74408 74408 74409 74409 string: function ( data ) { 74410 74410 return _empty(data) ? … … 74415 74415 } 74416 74416 } ); 74417 74418 74419 74417 74418 74419 74420 74420 var __numericReplace = function ( d, decimalPlace, re1, re2 ) { 74421 74421 if ( d !== 0 && (!d || d === '-') ) { 74422 74422 return -Infinity; 74423 74423 } 74424 74424 74425 74425 // If a decimal place other than `.` is used, it needs to be given to the 74426 74426 // function so we can detect it and replace with a `.` which is the only … … 74429 74429 d = _numToDecimal( d, decimalPlace ); 74430 74430 } 74431 74431 74432 74432 if ( d.replace ) { 74433 74433 if ( re1 ) { 74434 74434 d = d.replace( re1, '' ); 74435 74435 } 74436 74436 74437 74437 if ( re2 ) { 74438 74438 d = d.replace( re2, '' ); 74439 74439 } 74440 74440 } 74441 74441 74442 74442 return d * 1; 74443 74443 }; 74444 74445 74444 74445 74446 74446 // Add the numeric 'deformatting' functions for sorting and search. This is done 74447 74447 // in a function to provide an easy ability for the language options to add … … 74454 74454 return __numericReplace( d, decimalPlace ); 74455 74455 }, 74456 74456 74457 74457 // Formatted numbers 74458 74458 "num-fmt": function ( d ) { 74459 74459 return __numericReplace( d, decimalPlace, _re_formatted_numeric ); 74460 74460 }, 74461 74461 74462 74462 // HTML numeric 74463 74463 "html-num": function ( d ) { 74464 74464 return __numericReplace( d, decimalPlace, _re_html ); 74465 74465 }, 74466 74466 74467 74467 // HTML numeric, formatted 74468 74468 "html-num-fmt": function ( d ) { … … 74473 74473 // Add the ordering method 74474 74474 _ext.type.order[ key+decimalPlace+'-pre' ] = fn; 74475 74475 74476 74476 // For HTML types add a search formatter that will strip the HTML 74477 74477 if ( key.match(/^html\-/) ) { … … 74481 74481 ); 74482 74482 } 74483 74484 74483 74484 74485 74485 // Default sort methods 74486 74486 $.extend( _ext.type.order, { … … 74490 74490 return isNaN(ts) ? -Infinity : ts; 74491 74491 }, 74492 74492 74493 74493 // html 74494 74494 "html-pre": function ( a ) { … … 74499 74499 a+''; 74500 74500 }, 74501 74501 74502 74502 // string 74503 74503 "string-pre": function ( a ) { … … 74512 74512 a.toString(); 74513 74513 }, 74514 74514 74515 74515 // string-asc and -desc are retained only for compatibility with the old 74516 74516 // sort methods … … 74518 74518 return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 74519 74519 }, 74520 74520 74521 74521 "string-desc": function ( x, y ) { 74522 74522 return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 74523 74523 } 74524 74524 } ); 74525 74526 74525 74526 74527 74527 // Numeric sorting types - order doesn't matter here 74528 74528 _addNumericSort( '' ); 74529 74530 74529 74530 74531 74531 $.extend( true, DataTable.ext.renderer, { 74532 74532 header: { … … 74541 74541 return; // table, not a nested one 74542 74542 } 74543 74543 74544 74544 var colIdx = column.idx; 74545 74545 74546 74546 cell 74547 74547 .removeClass( … … 74557 74557 } ); 74558 74558 }, 74559 74559 74560 74560 jqueryui: function ( settings, cell, column, classes ) { 74561 74561 $('<div/>') … … 74566 74566 ) 74567 74567 .appendTo( cell ); 74568 74568 74569 74569 // Attach a sort listener to update on sort 74570 74570 $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) { … … 74572 74572 return; 74573 74573 } 74574 74574 74575 74575 var colIdx = column.idx; 74576 74576 74577 74577 cell 74578 74578 .removeClass( classes.sSortAsc +" "+classes.sSortDesc ) … … 74582 74582 column.sSortingClass 74583 74583 ); 74584 74584 74585 74585 cell 74586 74586 .find( 'span.'+classes.sSortIcon ) … … 74601 74601 } 74602 74602 } ); 74603 74603 74604 74604 /* 74605 74605 * Public helper functions. These aren't used internally by DataTables, or … … 74608 74608 * to make working with DataTables a little bit easier. 74609 74609 */ 74610 74610 74611 74611 var __htmlEscapeEntities = function ( d ) { 74612 74612 return typeof d === 'string' ? … … 74614 74614 d; 74615 74615 }; 74616 74616 74617 74617 /** 74618 74618 * Helpers for `columns.render`. … … 74648 74648 return d; 74649 74649 } 74650 74650 74651 74651 var negative = d < 0 ? '-' : ''; 74652 74652 var flo = parseFloat( d ); 74653 74653 74654 74654 // If NaN then there isn't much formatting that we can do - just 74655 74655 // return immediately, escaping any HTML (this was supposed to … … 74658 74658 return __htmlEscapeEntities( d ); 74659 74659 } 74660 74660 74661 74661 flo = flo.toFixed( precision ); 74662 74662 d = Math.abs( flo ); 74663 74663 74664 74664 var intPart = parseInt( d, 10 ); 74665 74665 var floatPart = precision ? 74666 74666 decimal+(d - intPart).toFixed( precision ).substring( 2 ): 74667 74667 ''; 74668 74668 74669 74669 return negative + (prefix||'') + 74670 74670 intPart.toString().replace( … … 74676 74676 }; 74677 74677 }, 74678 74678 74679 74679 text: function () { 74680 74680 return { … … 74684 74684 } 74685 74685 }; 74686 74687 74686 74687 74688 74688 /* 74689 74689 * This is really a good bit rubbish this method of exposing the internal methods 74690 74690 * publicly... - To be fixed in 2.0 using methods on the prototype 74691 74691 */ 74692 74693 74692 74693 74694 74694 /** 74695 74695 * Create a wrapper function for exporting an internal functions to an external API. … … 74707 74707 }; 74708 74708 } 74709 74710 74709 74710 74711 74711 /** 74712 74712 * Reference to internal functions for use by plug-in developers. Note that … … 74810 74810 // added to prevent errors 74811 74811 } ); 74812 74812 74813 74813 74814 74814 // jQuery access … … 75160 75160 75161 75161 // IE9 throws an 'unknown error' if document.activeElement is used 75162 // inside an iframe or frame. 75162 // inside an iframe or frame. 75163 75163 var activeEl; 75164 75164 … … 75241 75241 var _instance = 0; 75242 75242 75243 /** 75243 /** 75244 75244 * AutoFill provides Excel like auto-fill features for a DataTable 75245 75245 * … … 75870 75870 */ 75871 75871 _mousemove: function ( e ) 75872 { 75872 { 75873 75873 var that = this; 75874 75874 var dt = this.s.dt; … … 75976 75976 75977 75977 this._actionSelector( selected ); 75978 75978 75979 75979 // Stop shiftScroll 75980 75980 clearInterval( this.s.scrollInterval ); … … 75986 75986 * Create an array with a range of numbers defined by the start and end 75987 75987 * parameters passed in (inclusive!). 75988 * 75988 * 75989 75989 * @param {integer} start Start 75990 75990 * @param {integer} end End … … 76287 76287 /** 76288 76288 * AutoFill version 76289 * 76289 * 76290 76290 * @static 76291 76291 * @type String … … 76296 76296 /** 76297 76297 * AutoFill defaults 76298 * 76298 * 76299 76299 * @namespace 76300 76300 */ … … 76328 76328 /** 76329 76329 * Classes used by AutoFill that are configurable 76330 * 76330 * 76331 76331 * @namespace 76332 76332 */ … … 76506 76506 // If there is no config set it to an empty object 76507 76507 if ( typeof( config ) === 'undefined' ) { 76508 config = {}; 76508 config = {}; 76509 76509 } 76510 76510 76511 76511 // Allow a boolean true for defaults 76512 76512 if ( config === true ) { … … 76655 76655 var buttons = this.s.buttons.slice(); 76656 76656 var i, ien; 76657 76657 76658 76658 for ( i=0, ien=buttons.length ; i<ien ; i++ ) { 76659 76659 this.remove( buttons[i].node ); … … 77006 77006 77007 77007 $(dt.table().node()).triggerHandler( 'buttons-action.dt', [ 77008 dt.button( button ), dt, button, config 77008 dt.button( button ), dt, button, config 77009 77009 ] ); 77010 77010 }; … … 77476 77476 77477 77477 // Right alignment is enabled on a class, e.g. bootstrap: 77478 // $.fn.dataTable.Buttons.defaults.dom.collection.className += " dropdown-menu-right"; 77478 // $.fn.dataTable.Buttons.defaults.dom.collection.className += " dropdown-menu-right"; 77479 77479 if ( display.hasClass( options.rightAlignClassName ) || options.align === 'button-right' ) { 77480 77480 display.css( 'left', hostPosition.left + hostNode.outerWidth() - collectionWidth ); … … 77551 77551 * Show / hide a background layer behind a collection 77552 77552 * @param {boolean} Flag to indicate if the background should be shown or 77553 * hidden 77553 * hidden 77554 77554 * @param {string} Class to assign to the background 77555 77555 * @static … … 77634 77634 } 77635 77635 }; 77636 77636 77637 77637 process( group ); 77638 77638 … … 78362 78362 } ).toArray() : 78363 78363 null; 78364 78364 78365 78365 // If Select is available on this table, and any rows are selected, limit the export 78366 78366 // to the selected rows. If no rows are selected, all rows will be exported. Specify … … 79501 79501 79502 79502 /** 79503 * Convert XML documents in an object to strings79503 * Convert XML folders in an object to strings 79504 79504 * @param {object} obj XLSX document object 79505 79505 */ … … 80138 80138 80139 80139 extension: '.xlsx', 80140 80140 80141 80141 createEmptyCells: false 80142 80142 } ); … … 81377 81377 $('row:last c', rels).attr( 's', '2' ); // bold 81378 81378 } 81379 81379 81380 81380 dataStartRow = rowPos; 81381 81381 … … 81383 81383 addRow( data.body[n], rowPos ); 81384 81384 } 81385 81385 81386 81386 dataEndRow = rowPos; 81387 81387 … … 83779 83779 * tables and get the index position for the data in the main table. 83780 83780 * @param {node} node TR, TH or TD element to get the information about 83781 * @returns {int} If nNode is given as a TR, then a single index is 83781 * @returns {int} If nNode is given as a TR, then a single index is 83782 83782 * returned, or if given as a cell, an array of [row index, column index 83783 83783 * (visible), column index (all)] is given. … … 85200 85200 return this.s.enable; 85201 85201 }, 85202 85202 85203 85203 /** 85204 * Set header offset 85204 * Set header offset 85205 85205 * 85206 85206 * @param {int} new value for headerOffset … … 85215 85215 return this.c.headerOffset; 85216 85216 }, 85217 85217 85218 85218 /** 85219 85219 * Set footer offset … … 85231 85231 }, 85232 85232 85233 85233 85234 85234 /** 85235 85235 * Recalculate the position of the fixed elements and force them into place … … 85254 85254 * Constructor 85255 85255 */ 85256 85256 85257 85257 /** 85258 85258 * FixedHeader constructor - adding the required event listeners and … … 85415 85415 * 85416 85416 * @param {string} item The `header` or `footer` 85417 * @param {int} scrollLeft DocumentscrollLeft85417 * @param {int} scrollLeft Folder scrollLeft 85418 85418 * @private 85419 85419 */ … … 85439 85439 * * `below` - (Header only) Fixed to the bottom of the table body 85440 85440 * * `above` - (Footer only) Fixed to the top of the table body 85441 * 85441 * 85442 85442 * @param {string} mode Mode that the item should be shown in 85443 85443 * @param {string} item 'header' or 'footer' … … 85458 85458 document.activeElement : 85459 85459 null; 85460 85460 85461 85461 if ( focus ) { 85462 85462 focus.blur(); … … 86404 86404 .indexes() 86405 86405 .indexOf( index.row ); 86406 86406 86407 86407 // Don't focus rows that were filtered out. 86408 86408 if ( row < 0 ) { … … 87766 87766 } 87767 87767 } 87768 87768 87769 87769 // Show the columns for that break point 87770 87770 var columnsVis = this._columnsVisiblity( breakpoint ); … … 87897 87897 $(clonedTable).addClass( 'dtr-inline collapsed' ); 87898 87898 } 87899 87899 87900 87900 // It is unsafe to insert elements with the same name into the DOM 87901 87901 // multiple times. For example, cloning and inserting a checked radio … … 87906 87906 // our container element, bypassing the height and width (Scroller) 87907 87907 $( clonedTable ).css( 'position', 'relative' ) 87908 87908 87909 87909 var inserted = $('<div/>') 87910 87910 .css( { … … 88635 88635 group = that.c.emptyDataGroup; 88636 88636 } 88637 88637 88638 88638 if ( last === undefined || group !== last ) { 88639 88639 data.push( { … … 88667 88667 var dt = this.s.dt; 88668 88668 var display; 88669 88669 88670 88670 for ( var i=0, ien=groups.length ; i<ien ; i++ ) { 88671 88671 var group = groups[i]; … … 88710 88710 { 88711 88711 var row; 88712 88712 88713 88713 if ( display === null || display === '' ) { 88714 88714 display = this.c.emptyDataGroup; … … 88718 88718 return null; 88719 88719 } 88720 88720 88721 88721 if ( typeof display === 'object' && display.nodeName && display.nodeName.toLowerCase() === 'tr') { 88722 88722 row = $(display); … … 88935 88935 * * `new $.fn.dataTable.RowReorder( table, opts )` after DataTables 88936 88936 * initialisation. 88937 * 88937 * 88938 88938 * @class 88939 88939 * @param {object} settings DataTables settings object for the host table … … 88990 88990 windowHeight: 0, 88991 88991 88992 /** @type {integer} Documentouter height cached value */88992 /** @type {integer} Folder outer height cached value */ 88993 88993 documentOuterHeight: 0, 88994 88994 … … 89080 89080 * Private methods 89081 89081 */ 89082 89082 89083 89083 /** 89084 89084 * Cache the measurements that RowReorder needs in the mouse move handler … … 89395 89395 } 89396 89396 } 89397 89397 89398 89398 // Create event args 89399 89399 var eventArgs = [ fullDiff, { … … 89404 89404 originalEvent: e 89405 89405 } ]; 89406 89406 89407 89407 // Emit event 89408 89408 this._emitEvent( 'row-reorder', eventArgs ); … … 89773 89773 * @global 89774 89774 * @param {object} dt DataTables settings object or API instance 89775 * @param {object} [opts={}] Configuration object for FixedColumns. Options 89775 * @param {object} [opts={}] Configuration object for FixedColumns. Options 89776 89776 * are defined by {@link Scroller.defaults} 89777 89777 * … … 90011 90011 pageInfo: function() 90012 90012 { 90013 var 90013 var 90014 90014 dt = this.s.dt, 90015 90015 iScrollTop = this.dom.scroller.scrollTop, … … 90324 90324 } 90325 90325 } 90326 90326 90327 90327 $('div.'+dt.oClasses.sScrollBody, container).append( nTable ); 90328 90328 … … 90453 90453 * 90454 90454 * @param {string} dir Domain transform direction, `virtualToPhysical` or 90455 * `physicalToVirtual` 90455 * `physicalToVirtual` 90456 90456 * @returns {number} Calculated transform 90457 90457 * @private … … 92294 92294 */ 92295 92295 SearchPanes.prototype.clearSelections = function () { 92296 // Load in all of the searchBoxes in the documents92296 // Load in all of the searchBoxes in the folders 92297 92297 var searches = this.dom.container.find(this.classes.search); 92298 92298 // For each searchBox set the input text to be empty and then trigger … … 93064 93064 blurable = opts.blurable; 93065 93065 } 93066 93066 93067 93067 if ( opts.toggleable !== undefined ) { 93068 93068 toggleable = opts.toggleable; … … 93161 93161 ``` 93162 93162 { 93163 items:string - Can be `rows`, `columns` or `cells`. Defines what item 93163 items:string - Can be `rows`, `columns` or `cells`. Defines what item 93164 93164 will be selected if the user is allowed to activate row 93165 93165 selection using the mouse. … … 93200 93200 * click first in cell 1-1 and then shift click in 2-2 - cells 1-2 and 2-1 93201 93201 * should also be selected (and not 1-3, 1-4. etc) 93202 * 93202 * 93203 93203 * @param {DataTable.Api} dt DataTable 93204 93204 * @param {object} idx Cell index to select to … … 93217 93217 start = tmp; 93218 93218 } 93219 93219 93220 93220 var record = false; 93221 93221 return dt.columns( ':visible' ).indexes().filter( function (i) { … … 93223 93223 record = true; 93224 93224 } 93225 93225 93226 93226 if ( i === end ) { // not else if, as start might === end 93227 93227 record = false; … … 93248 93248 record = true; 93249 93249 } 93250 93250 93251 93251 if ( i === end ) { 93252 93252 record = false; … … 93444 93444 * Update the information element of the DataTable showing information about the 93445 93445 * items selected. This is done by adding tags to the existing text 93446 * 93446 * 93447 93447 * @param {DataTable.Api} api DataTable to update 93448 93448 * @private … … 93508 93508 // was selected before the element was created. This will happen with the 93509 93509 // `deferRender` option enabled. 93510 // 93510 // 93511 93511 // This method of attaching to `aoRowCreatedCallback` is a hack until 93512 93512 // DataTables has proper events for row manipulation If you are reviewing … … 93633 93633 if ( force || ctx._select.style === 'single' ) { 93634 93634 var api = new DataTable.Api( ctx ); 93635 93635 93636 93636 api.rows( { selected: true } ).deselect(); 93637 93637 api.columns( { selected: true } ).deselect(); … … 93655 93655 var toggleable = dt.select.toggleable(); 93656 93656 var isSelected = dt[type]( idx, { selected: true } ).any(); 93657 93657 93658 93658 if ( isSelected && ! toggleable ) { 93659 93659 return; … … 93851 93851 var dt = new DataTable.Api( ctx ); 93852 93852 disableMouseSelection( dt ); 93853 93853 93854 93854 if ( style !== 'api' ) { 93855 93855 enableMouseSelection( dt );
Note:
See TracChangeset
for help on using the changeset viewer.