jquery.dataTables.js 360 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839
  1. /**
  2. * @summary DataTables
  3. * @description Paginate, search and sort HTML tables
  4. * @version 1.9.1
  5. * @file jquery.dataTables.js
  6. * @author Allan Jardine (www.sprymedia.co.uk)
  7. * @contact www.sprymedia.co.uk/contact
  8. *
  9. * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved.
  10. *
  11. * This source file is free software, under either the GPL v2 license or a
  12. * BSD style license, available at:
  13. * http://datatables.net/license_gpl2
  14. * http://datatables.net/license_bsd
  15. *
  16. * This source file is distributed in the hope that it will be useful, but
  17. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  18. * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
  19. *
  20. * For details please refer to: http://www.datatables.net
  21. */
  22. /*jslint evil: true, undef: true, browser: true */
  23. /*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros*/
  24. (/** @lends <global> */function($, window, document, undefined) {
  25. /**
  26. * DataTables is a plug-in for the jQuery Javascript library. It is a
  27. * highly flexible tool, based upon the foundations of progressive
  28. * enhancement, which will add advanced interaction controls to any
  29. * HTML table. For a full list of features please refer to
  30. * <a href="http://datatables.net">DataTables.net</a>.
  31. *
  32. * Note that the <i>DataTable</i> object is not a global variable but is
  33. * aliased to <i>jQuery.fn.DataTable</i> and <i>jQuery.fn.dataTable</i> through which
  34. * it may be accessed.
  35. *
  36. * @class
  37. * @param {object} [oInit={}] Configuration object for DataTables. Options
  38. * are defined by {@link DataTable.defaults}
  39. * @requires jQuery 1.3+
  40. *
  41. * @example
  42. * // Basic initialisation
  43. * $(document).ready( function {
  44. * $('#example').dataTable();
  45. * } );
  46. *
  47. * @example
  48. * // Initialisation with configuration options - in this case, disable
  49. * // pagination and sorting.
  50. * $(document).ready( function {
  51. * $('#example').dataTable( {
  52. * "bPaginate": false,
  53. * "bSort": false
  54. * } );
  55. * } );
  56. */
  57. var DataTable = function( oInit )
  58. {
  59. /**
  60. * Add a column to the list used for the table with default values
  61. * @param {object} oSettings dataTables settings object
  62. * @param {node} nTh The th element for this column
  63. * @memberof DataTable#oApi
  64. */
  65. function _fnAddColumn( oSettings, nTh )
  66. {
  67. var oDefaults = DataTable.defaults.columns;
  68. var iCol = oSettings.aoColumns.length;
  69. var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
  70. "sSortingClass": oSettings.oClasses.sSortable,
  71. "sSortingClassJUI": oSettings.oClasses.sSortJUI,
  72. "nTh": nTh ? nTh : document.createElement('th'),
  73. "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
  74. "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
  75. "mDataProp": oDefaults.mDataProp ? oDefaults.oDefaults : iCol
  76. } );
  77. oSettings.aoColumns.push( oCol );
  78. /* Add a column specific filter */
  79. if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null )
  80. {
  81. oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch );
  82. }
  83. else
  84. {
  85. var oPre = oSettings.aoPreSearchCols[ iCol ];
  86. /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */
  87. if ( oPre.bRegex === undefined )
  88. {
  89. oPre.bRegex = true;
  90. }
  91. if ( oPre.bSmart === undefined )
  92. {
  93. oPre.bSmart = true;
  94. }
  95. if ( oPre.bCaseInsensitive === undefined )
  96. {
  97. oPre.bCaseInsensitive = true;
  98. }
  99. }
  100. /* Use the column options function to initialise classes etc */
  101. _fnColumnOptions( oSettings, iCol, null );
  102. }
  103. /**
  104. * Apply options for a column
  105. * @param {object} oSettings dataTables settings object
  106. * @param {int} iCol column index to consider
  107. * @param {object} oOptions object with sType, bVisible and bSearchable
  108. * @memberof DataTable#oApi
  109. */
  110. function _fnColumnOptions( oSettings, iCol, oOptions )
  111. {
  112. var oCol = oSettings.aoColumns[ iCol ];
  113. /* User specified column options */
  114. if ( oOptions !== undefined && oOptions !== null )
  115. {
  116. if ( oOptions.sType !== undefined )
  117. {
  118. oCol.sType = oOptions.sType;
  119. oCol._bAutoType = false;
  120. }
  121. $.extend( oCol, oOptions );
  122. _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
  123. /* iDataSort to be applied (backwards compatibility), but aDataSort will take
  124. * priority if defined
  125. */
  126. if ( oOptions.iDataSort !== undefined )
  127. {
  128. oCol.aDataSort = [ oOptions.iDataSort ];
  129. }
  130. _fnMap( oCol, oOptions, "aDataSort" );
  131. }
  132. /* Cache the data get and set functions for speed */
  133. oCol.fnGetData = _fnGetObjectDataFn( oCol.mDataProp );
  134. oCol.fnSetData = _fnSetObjectDataFn( oCol.mDataProp );
  135. /* Feature sorting overrides column specific when off */
  136. if ( !oSettings.oFeatures.bSort )
  137. {
  138. oCol.bSortable = false;
  139. }
  140. /* Check that the class assignment is correct for sorting */
  141. if ( !oCol.bSortable ||
  142. ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) )
  143. {
  144. oCol.sSortingClass = oSettings.oClasses.sSortableNone;
  145. oCol.sSortingClassJUI = "";
  146. }
  147. else if ( oCol.bSortable ||
  148. ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) )
  149. {
  150. oCol.sSortingClass = oSettings.oClasses.sSortable;
  151. oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI;
  152. }
  153. else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 )
  154. {
  155. oCol.sSortingClass = oSettings.oClasses.sSortableAsc;
  156. oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed;
  157. }
  158. else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 )
  159. {
  160. oCol.sSortingClass = oSettings.oClasses.sSortableDesc;
  161. oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed;
  162. }
  163. }
  164. /**
  165. * Adjust the table column widths for new data. Note: you would probably want to
  166. * do a redraw after calling this function!
  167. * @param {object} oSettings dataTables settings object
  168. * @memberof DataTable#oApi
  169. */
  170. function _fnAdjustColumnSizing ( oSettings )
  171. {
  172. /* Not interested in doing column width calculation if autowidth is disabled */
  173. if ( oSettings.oFeatures.bAutoWidth === false )
  174. {
  175. return false;
  176. }
  177. _fnCalculateColumnWidths( oSettings );
  178. for ( var i=0 , iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  179. {
  180. oSettings.aoColumns[i].nTh.style.width = oSettings.aoColumns[i].sWidth;
  181. }
  182. }
  183. /**
  184. * Covert the index of a visible column to the index in the data array (take account
  185. * of hidden columns)
  186. * @param {object} oSettings dataTables settings object
  187. * @param {int} iMatch Visible column index to lookup
  188. * @returns {int} i the data index
  189. * @memberof DataTable#oApi
  190. */
  191. function _fnVisibleToColumnIndex( oSettings, iMatch )
  192. {
  193. var iColumn = -1;
  194. for ( var i=0 ; i<oSettings.aoColumns.length ; i++ )
  195. {
  196. if ( oSettings.aoColumns[i].bVisible === true )
  197. {
  198. iColumn++;
  199. }
  200. if ( iColumn == iMatch )
  201. {
  202. return i;
  203. }
  204. }
  205. return null;
  206. }
  207. /**
  208. * Covert the index of an index in the data array and convert it to the visible
  209. * column index (take account of hidden columns)
  210. * @param {int} iMatch Column index to lookup
  211. * @param {object} oSettings dataTables settings object
  212. * @returns {int} i the data index
  213. * @memberof DataTable#oApi
  214. */
  215. function _fnColumnIndexToVisible( oSettings, iMatch )
  216. {
  217. var iVisible = -1;
  218. for ( var i=0 ; i<oSettings.aoColumns.length ; i++ )
  219. {
  220. if ( oSettings.aoColumns[i].bVisible === true )
  221. {
  222. iVisible++;
  223. }
  224. if ( i == iMatch )
  225. {
  226. return oSettings.aoColumns[i].bVisible === true ? iVisible : null;
  227. }
  228. }
  229. return null;
  230. }
  231. /**
  232. * Get the number of visible columns
  233. * @returns {int} i the number of visible columns
  234. * @param {object} oS dataTables settings object
  235. * @memberof DataTable#oApi
  236. */
  237. function _fnVisbleColumns( oS )
  238. {
  239. var iVis = 0;
  240. for ( var i=0 ; i<oS.aoColumns.length ; i++ )
  241. {
  242. if ( oS.aoColumns[i].bVisible === true )
  243. {
  244. iVis++;
  245. }
  246. }
  247. return iVis;
  248. }
  249. /**
  250. * Get the sort type based on an input string
  251. * @param {string} sData data we wish to know the type of
  252. * @returns {string} type (defaults to 'string' if no type can be detected)
  253. * @memberof DataTable#oApi
  254. */
  255. function _fnDetectType( sData )
  256. {
  257. var aTypes = DataTable.ext.aTypes;
  258. var iLen = aTypes.length;
  259. for ( var i=0 ; i<iLen ; i++ )
  260. {
  261. var sType = aTypes[i]( sData );
  262. if ( sType !== null )
  263. {
  264. return sType;
  265. }
  266. }
  267. return 'string';
  268. }
  269. /**
  270. * Figure out how to reorder a display list
  271. * @param {object} oSettings dataTables settings object
  272. * @returns array {int} aiReturn index list for reordering
  273. * @memberof DataTable#oApi
  274. */
  275. function _fnReOrderIndex ( oSettings, sColumns )
  276. {
  277. var aColumns = sColumns.split(',');
  278. var aiReturn = [];
  279. for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  280. {
  281. for ( var j=0 ; j<iLen ; j++ )
  282. {
  283. if ( oSettings.aoColumns[i].sName == aColumns[j] )
  284. {
  285. aiReturn.push( j );
  286. break;
  287. }
  288. }
  289. }
  290. return aiReturn;
  291. }
  292. /**
  293. * Get the column ordering that DataTables expects
  294. * @param {object} oSettings dataTables settings object
  295. * @returns {string} comma separated list of names
  296. * @memberof DataTable#oApi
  297. */
  298. function _fnColumnOrdering ( oSettings )
  299. {
  300. var sNames = '';
  301. for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  302. {
  303. sNames += oSettings.aoColumns[i].sName+',';
  304. }
  305. if ( sNames.length == iLen )
  306. {
  307. return "";
  308. }
  309. return sNames.slice(0, -1);
  310. }
  311. /**
  312. * Take the column definitions and static columns arrays and calculate how
  313. * they relate to column indexes. The callback function will then apply the
  314. * definition found for a column to a suitable configuration object.
  315. * @param {object} oSettings dataTables settings object
  316. * @param {array} aoColDefs The aoColumnDefs array that is to be applied
  317. * @param {array} aoCols The aoColumns array that defines columns individually
  318. * @param {function} fn Callback function - takes two parameters, the calculated
  319. * column index and the definition for that column.
  320. * @memberof DataTable#oApi
  321. */
  322. function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
  323. {
  324. var i, iLen, j, jLen, k, kLen;
  325. // Column definitions with aTargets
  326. if ( aoColDefs )
  327. {
  328. /* Loop over the definitions array - loop in reverse so first instance has priority */
  329. for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
  330. {
  331. /* Each definition can target multiple columns, as it is an array */
  332. var aTargets = aoColDefs[i].aTargets;
  333. if ( !$.isArray( aTargets ) )
  334. {
  335. _fnLog( oSettings, 1, 'aTargets must be an array of targets, not a '+(typeof aTargets) );
  336. }
  337. for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
  338. {
  339. if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
  340. {
  341. /* Add columns that we don't yet know about */
  342. while( oSettings.aoColumns.length <= aTargets[j] )
  343. {
  344. _fnAddColumn( oSettings );
  345. }
  346. /* Integer, basic index */
  347. fn( aTargets[j], aoColDefs[i] );
  348. }
  349. else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
  350. {
  351. /* Negative integer, right to left column counting */
  352. fn( oSettings.aoColumns.length+aTargets[j], aoColDefs[i] );
  353. }
  354. else if ( typeof aTargets[j] === 'string' )
  355. {
  356. /* Class name matching on TH element */
  357. for ( k=0, kLen=oSettings.aoColumns.length ; k<kLen ; k++ )
  358. {
  359. if ( aTargets[j] == "_all" ||
  360. $(oSettings.aoColumns[k].nTh).hasClass( aTargets[j] ) )
  361. {
  362. fn( k, aoColDefs[i] );
  363. }
  364. }
  365. }
  366. }
  367. }
  368. }
  369. // Statically defined columns array
  370. if ( aoCols )
  371. {
  372. for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
  373. {
  374. fn( i, aoCols[i] );
  375. }
  376. }
  377. }
  378. /**
  379. * Add a data array to the table, creating DOM node etc. This is the parallel to
  380. * _fnGatherData, but for adding rows from a Javascript source, rather than a
  381. * DOM source.
  382. * @param {object} oSettings dataTables settings object
  383. * @param {array} aData data array to be added
  384. * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
  385. * @memberof DataTable#oApi
  386. */
  387. function _fnAddData ( oSettings, aDataSupplied )
  388. {
  389. var oCol;
  390. /* Take an independent copy of the data source so we can bash it about as we wish */
  391. var aDataIn = ($.isArray(aDataSupplied)) ?
  392. aDataSupplied.slice() :
  393. $.extend( true, {}, aDataSupplied );
  394. /* Create the object for storing information about this new row */
  395. var iRow = oSettings.aoData.length;
  396. var oData = $.extend( true, {}, DataTable.models.oRow );
  397. oData._aData = aDataIn;
  398. oSettings.aoData.push( oData );
  399. /* Create the cells */
  400. var nTd, sThisType;
  401. for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  402. {
  403. oCol = oSettings.aoColumns[i];
  404. /* Use rendered data for filtering/sorting */
  405. if ( typeof oCol.fnRender === 'function' && oCol.bUseRendered && oCol.mDataProp !== null )
  406. {
  407. _fnSetCellData( oSettings, iRow, i, _fnRender(oSettings, iRow, i) );
  408. }
  409. else
  410. {
  411. _fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
  412. }
  413. /* See if we should auto-detect the column type */
  414. if ( oCol._bAutoType && oCol.sType != 'string' )
  415. {
  416. /* Attempt to auto detect the type - same as _fnGatherData() */
  417. var sVarType = _fnGetCellData( oSettings, iRow, i, 'type' );
  418. if ( sVarType !== null && sVarType !== '' )
  419. {
  420. sThisType = _fnDetectType( sVarType );
  421. if ( oCol.sType === null )
  422. {
  423. oCol.sType = sThisType;
  424. }
  425. else if ( oCol.sType != sThisType && oCol.sType != "html" )
  426. {
  427. /* String is always the 'fallback' option */
  428. oCol.sType = 'string';
  429. }
  430. }
  431. }
  432. }
  433. /* Add to the display array */
  434. oSettings.aiDisplayMaster.push( iRow );
  435. /* Create the DOM imformation */
  436. if ( !oSettings.oFeatures.bDeferRender )
  437. {
  438. _fnCreateTr( oSettings, iRow );
  439. }
  440. return iRow;
  441. }
  442. /**
  443. * Read in the data from the target table from the DOM
  444. * @param {object} oSettings dataTables settings object
  445. * @memberof DataTable#oApi
  446. */
  447. function _fnGatherData( oSettings )
  448. {
  449. var iLoop, i, iLen, j, jLen, jInner,
  450. nTds, nTrs, nTd, aLocalData, iThisIndex,
  451. iRow, iRows, iColumn, iColumns, sNodeName,
  452. oCol, oData;
  453. /*
  454. * Process by row first
  455. * Add the data object for the whole table - storing the tr node. Note - no point in getting
  456. * DOM based data if we are going to go and replace it with Ajax source data.
  457. */
  458. if ( oSettings.bDeferLoading || oSettings.sAjaxSource === null )
  459. {
  460. nTrs = oSettings.nTBody.childNodes;
  461. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  462. {
  463. if ( nTrs[i].nodeName.toUpperCase() == "TR" )
  464. {
  465. iThisIndex = oSettings.aoData.length;
  466. nTrs[i]._DT_RowIndex = iThisIndex;
  467. oSettings.aoData.push( $.extend( true, {}, DataTable.models.oRow, {
  468. "nTr": nTrs[i]
  469. } ) );
  470. oSettings.aiDisplayMaster.push( iThisIndex );
  471. nTds = nTrs[i].childNodes;
  472. jInner = 0;
  473. for ( j=0, jLen=nTds.length ; j<jLen ; j++ )
  474. {
  475. sNodeName = nTds[j].nodeName.toUpperCase();
  476. if ( sNodeName == "TD" || sNodeName == "TH" )
  477. {
  478. _fnSetCellData( oSettings, iThisIndex, jInner, $.trim(nTds[j].innerHTML) );
  479. jInner++;
  480. }
  481. }
  482. }
  483. }
  484. }
  485. /* Gather in the TD elements of the Table - note that this is basically the same as
  486. * fnGetTdNodes, but that function takes account of hidden columns, which we haven't yet
  487. * setup!
  488. */
  489. nTrs = _fnGetTrNodes( oSettings );
  490. nTds = [];
  491. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  492. {
  493. for ( j=0, jLen=nTrs[i].childNodes.length ; j<jLen ; j++ )
  494. {
  495. nTd = nTrs[i].childNodes[j];
  496. sNodeName = nTd.nodeName.toUpperCase();
  497. if ( sNodeName == "TD" || sNodeName == "TH" )
  498. {
  499. nTds.push( nTd );
  500. }
  501. }
  502. }
  503. /* Now process by column */
  504. for ( iColumn=0, iColumns=oSettings.aoColumns.length ; iColumn<iColumns ; iColumn++ )
  505. {
  506. oCol = oSettings.aoColumns[iColumn];
  507. /* Get the title of the column - unless there is a user set one */
  508. if ( oCol.sTitle === null )
  509. {
  510. oCol.sTitle = oCol.nTh.innerHTML;
  511. }
  512. var
  513. bAutoType = oCol._bAutoType,
  514. bRender = typeof oCol.fnRender === 'function',
  515. bClass = oCol.sClass !== null,
  516. bVisible = oCol.bVisible,
  517. nCell, sThisType, sRendered, sValType;
  518. /* A single loop to rule them all (and be more efficient) */
  519. if ( bAutoType || bRender || bClass || !bVisible )
  520. {
  521. for ( iRow=0, iRows=oSettings.aoData.length ; iRow<iRows ; iRow++ )
  522. {
  523. oData = oSettings.aoData[iRow];
  524. nCell = nTds[ (iRow*iColumns) + iColumn ];
  525. /* Type detection */
  526. if ( bAutoType && oCol.sType != 'string' )
  527. {
  528. sValType = _fnGetCellData( oSettings, iRow, iColumn, 'type' );
  529. if ( sValType !== '' )
  530. {
  531. sThisType = _fnDetectType( sValType );
  532. if ( oCol.sType === null )
  533. {
  534. oCol.sType = sThisType;
  535. }
  536. else if ( oCol.sType != sThisType &&
  537. oCol.sType != "html" )
  538. {
  539. /* String is always the 'fallback' option */
  540. oCol.sType = 'string';
  541. }
  542. }
  543. }
  544. if ( typeof oCol.mDataProp === 'function' )
  545. {
  546. nCell.innerHTML = _fnGetCellData( oSettings, iRow, iColumn, 'display' );
  547. }
  548. /* Rendering */
  549. if ( bRender )
  550. {
  551. sRendered = _fnRender( oSettings, iRow, iColumn );
  552. nCell.innerHTML = sRendered;
  553. if ( oCol.bUseRendered )
  554. {
  555. /* Use the rendered data for filtering/sorting */
  556. _fnSetCellData( oSettings, iRow, iColumn, sRendered );
  557. }
  558. }
  559. /* Classes */
  560. if ( bClass )
  561. {
  562. nCell.className += ' '+oCol.sClass;
  563. }
  564. /* Column visability */
  565. if ( !bVisible )
  566. {
  567. oData._anHidden[iColumn] = nCell;
  568. nCell.parentNode.removeChild( nCell );
  569. }
  570. else
  571. {
  572. oData._anHidden[iColumn] = null;
  573. }
  574. if ( oCol.fnCreatedCell )
  575. {
  576. oCol.fnCreatedCell.call( oSettings.oInstance,
  577. nCell, _fnGetCellData( oSettings, iRow, iColumn, 'display' ), oData._aData, iRow, iColumn
  578. );
  579. }
  580. }
  581. }
  582. }
  583. /* Row created callbacks */
  584. if ( oSettings.aoRowCreatedCallback.length !== 0 )
  585. {
  586. for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
  587. {
  588. oData = oSettings.aoData[i];
  589. _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [oData.nTr, oData._aData, i] );
  590. }
  591. }
  592. }
  593. /**
  594. * Take a TR element and convert it to an index in aoData
  595. * @param {object} oSettings dataTables settings object
  596. * @param {node} n the TR element to find
  597. * @returns {int} index if the node is found, null if not
  598. * @memberof DataTable#oApi
  599. */
  600. function _fnNodeToDataIndex( oSettings, n )
  601. {
  602. return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
  603. }
  604. /**
  605. * Take a TD element and convert it into a column data index (not the visible index)
  606. * @param {object} oSettings dataTables settings object
  607. * @param {int} iRow The row number the TD/TH can be found in
  608. * @param {node} n The TD/TH element to find
  609. * @returns {int} index if the node is found, -1 if not
  610. * @memberof DataTable#oApi
  611. */
  612. function _fnNodeToColumnIndex( oSettings, iRow, n )
  613. {
  614. var anCells = _fnGetTdNodes( oSettings, iRow );
  615. for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  616. {
  617. if ( anCells[i] === n )
  618. {
  619. return i;
  620. }
  621. }
  622. return -1;
  623. }
  624. /**
  625. * Get an array of data for a given row from the internal data cache
  626. * @param {object} oSettings dataTables settings object
  627. * @param {int} iRow aoData row id
  628. * @param {string} sSpecific data get type ('type' 'filter' 'sort')
  629. * @returns {array} Data array
  630. * @memberof DataTable#oApi
  631. */
  632. function _fnGetRowData( oSettings, iRow, sSpecific )
  633. {
  634. var out = [];
  635. for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  636. {
  637. out.push( _fnGetCellData( oSettings, iRow, i, sSpecific ) );
  638. }
  639. return out;
  640. }
  641. /**
  642. * Get the data for a given cell from the internal cache, taking into account data mapping
  643. * @param {object} oSettings dataTables settings object
  644. * @param {int} iRow aoData row id
  645. * @param {int} iCol Column index
  646. * @param {string} sSpecific data get type ('display', 'type' 'filter' 'sort')
  647. * @returns {*} Cell data
  648. * @memberof DataTable#oApi
  649. */
  650. function _fnGetCellData( oSettings, iRow, iCol, sSpecific )
  651. {
  652. var sData;
  653. var oCol = oSettings.aoColumns[iCol];
  654. var oData = oSettings.aoData[iRow]._aData;
  655. if ( (sData=oCol.fnGetData( oData, sSpecific )) === undefined )
  656. {
  657. if ( oSettings.iDrawError != oSettings.iDraw && oCol.sDefaultContent === null )
  658. {
  659. _fnLog( oSettings, 0, "Requested unknown parameter "+
  660. (typeof oCol.mDataProp=='function' ? '{mDataprop function}' : "'"+oCol.mDataProp+"'")+
  661. " from the data source for row "+iRow );
  662. oSettings.iDrawError = oSettings.iDraw;
  663. }
  664. return oCol.sDefaultContent;
  665. }
  666. /* When the data source is null, we can use default column data */
  667. if ( sData === null && oCol.sDefaultContent !== null )
  668. {
  669. sData = oCol.sDefaultContent;
  670. }
  671. else if ( typeof sData === 'function' )
  672. {
  673. /* If the data source is a function, then we run it and use the return */
  674. return sData();
  675. }
  676. if ( sSpecific == 'display' && sData === null )
  677. {
  678. return '';
  679. }
  680. return sData;
  681. }
  682. /**
  683. * Set the value for a specific cell, into the internal data cache
  684. * @param {object} oSettings dataTables settings object
  685. * @param {int} iRow aoData row id
  686. * @param {int} iCol Column index
  687. * @param {*} val Value to set
  688. * @memberof DataTable#oApi
  689. */
  690. function _fnSetCellData( oSettings, iRow, iCol, val )
  691. {
  692. var oCol = oSettings.aoColumns[iCol];
  693. var oData = oSettings.aoData[iRow]._aData;
  694. oCol.fnSetData( oData, val );
  695. }
  696. /**
  697. * Return a function that can be used to get data from a source object, taking
  698. * into account the ability to use nested objects as a source
  699. * @param {string|int|function} mSource The data source for the object
  700. * @returns {function} Data get function
  701. * @memberof DataTable#oApi
  702. */
  703. function _fnGetObjectDataFn( mSource )
  704. {
  705. if ( mSource === null )
  706. {
  707. /* Give an empty string for rendering / sorting etc */
  708. return function (data, type) {
  709. return null;
  710. };
  711. }
  712. else if ( typeof mSource === 'function' )
  713. {
  714. return function (data, type) {
  715. return mSource( data, type );
  716. };
  717. }
  718. else if ( typeof mSource === 'string' && mSource.indexOf('.') != -1 )
  719. {
  720. /* If there is a . in the source string then the data source is in a
  721. * nested object so we loop over the data for each level to get the next
  722. * level down. On each loop we test for undefined, and if found immediatly
  723. * return. This allows entire objects to be missing and sDefaultContent to
  724. * be used if defined, rather than throwing an error
  725. */
  726. var a = mSource.split('.');
  727. return function (data, type) {
  728. for ( var i=0, iLen=a.length ; i<iLen ; i++ )
  729. {
  730. data = data[ a[i] ];
  731. if ( data === undefined )
  732. {
  733. return undefined;
  734. }
  735. }
  736. return data;
  737. };
  738. }
  739. else
  740. {
  741. /* Array or flat object mapping */
  742. return function (data, type) {
  743. return data[mSource];
  744. };
  745. }
  746. }
  747. /**
  748. * Return a function that can be used to set data from a source object, taking
  749. * into account the ability to use nested objects as a source
  750. * @param {string|int|function} mSource The data source for the object
  751. * @returns {function} Data set function
  752. * @memberof DataTable#oApi
  753. */
  754. function _fnSetObjectDataFn( mSource )
  755. {
  756. if ( mSource === null )
  757. {
  758. /* Nothing to do when the data source is null */
  759. return function (data, val) {};
  760. }
  761. else if ( typeof mSource === 'function' )
  762. {
  763. return function (data, val) {
  764. mSource( data, 'set', val );
  765. };
  766. }
  767. else if ( typeof mSource === 'string' && mSource.indexOf('.') != -1 )
  768. {
  769. /* Like the get, we need to get data from a nested object. */
  770. var a = mSource.split('.');
  771. return function (data, val) {
  772. for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
  773. {
  774. data = data[ a[i] ];
  775. if ( data === undefined )
  776. {
  777. return;
  778. }
  779. }
  780. data[ a[a.length-1] ] = val;
  781. };
  782. }
  783. else
  784. {
  785. /* Array or flat object mapping */
  786. return function (data, val) {
  787. data[mSource] = val;
  788. };
  789. }
  790. }
  791. /**
  792. * Return an array with the full table data
  793. * @param {object} oSettings dataTables settings object
  794. * @returns array {array} aData Master data array
  795. * @memberof DataTable#oApi
  796. */
  797. function _fnGetDataMaster ( oSettings )
  798. {
  799. var aData = [];
  800. var iLen = oSettings.aoData.length;
  801. for ( var i=0 ; i<iLen; i++ )
  802. {
  803. aData.push( oSettings.aoData[i]._aData );
  804. }
  805. return aData;
  806. }
  807. /**
  808. * Nuke the table
  809. * @param {object} oSettings dataTables settings object
  810. * @memberof DataTable#oApi
  811. */
  812. function _fnClearTable( oSettings )
  813. {
  814. oSettings.aoData.splice( 0, oSettings.aoData.length );
  815. oSettings.aiDisplayMaster.splice( 0, oSettings.aiDisplayMaster.length );
  816. oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length );
  817. _fnCalculateEnd( oSettings );
  818. }
  819. /**
  820. * Take an array of integers (index array) and remove a target integer (value - not
  821. * the key!)
  822. * @param {array} a Index array to target
  823. * @param {int} iTarget value to find
  824. * @memberof DataTable#oApi
  825. */
  826. function _fnDeleteIndex( a, iTarget )
  827. {
  828. var iTargetIndex = -1;
  829. for ( var i=0, iLen=a.length ; i<iLen ; i++ )
  830. {
  831. if ( a[i] == iTarget )
  832. {
  833. iTargetIndex = i;
  834. }
  835. else if ( a[i] > iTarget )
  836. {
  837. a[i]--;
  838. }
  839. }
  840. if ( iTargetIndex != -1 )
  841. {
  842. a.splice( iTargetIndex, 1 );
  843. }
  844. }
  845. /**
  846. * Call the developer defined fnRender function for a given cell (row/column) with
  847. * the required parameters and return the result.
  848. * @param {object} oSettings dataTables settings object
  849. * @param {int} iRow aoData index for the row
  850. * @param {int} iCol aoColumns index for the column
  851. * @returns {*} Return of the developer's fnRender function
  852. * @memberof DataTable#oApi
  853. */
  854. function _fnRender( oSettings, iRow, iCol )
  855. {
  856. var oCol = oSettings.aoColumns[iCol];
  857. return oCol.fnRender( {
  858. "iDataRow": iRow,
  859. "iDataColumn": iCol,
  860. "oSettings": oSettings,
  861. "aData": oSettings.aoData[iRow]._aData,
  862. "mDataProp": oCol.mDataProp
  863. }, _fnGetCellData(oSettings, iRow, iCol, 'display') );
  864. }
  865. /**
  866. * Create a new TR element (and it's TD children) for a row
  867. * @param {object} oSettings dataTables settings object
  868. * @param {int} iRow Row to consider
  869. * @memberof DataTable#oApi
  870. */
  871. function _fnCreateTr ( oSettings, iRow )
  872. {
  873. var oData = oSettings.aoData[iRow];
  874. var nTd;
  875. if ( oData.nTr === null )
  876. {
  877. oData.nTr = document.createElement('tr');
  878. /* Use a private property on the node to allow reserve mapping from the node
  879. * to the aoData array for fast look up
  880. */
  881. oData.nTr._DT_RowIndex = iRow;
  882. /* Special parameters can be given by the data source to be used on the row */
  883. if ( oData._aData.DT_RowId )
  884. {
  885. oData.nTr.id = oData._aData.DT_RowId;
  886. }
  887. if ( oData._aData.DT_RowClass )
  888. {
  889. $(oData.nTr).addClass( oData._aData.DT_RowClass );
  890. }
  891. /* Process each column */
  892. for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  893. {
  894. var oCol = oSettings.aoColumns[i];
  895. nTd = document.createElement( oCol.sCellType );
  896. /* Render if needed - if bUseRendered is true then we already have the rendered
  897. * value in the data source - so can just use that
  898. */
  899. nTd.innerHTML = (typeof oCol.fnRender === 'function' && (!oCol.bUseRendered || oCol.mDataProp === null)) ?
  900. _fnRender( oSettings, iRow, i ) :
  901. _fnGetCellData( oSettings, iRow, i, 'display' );
  902. /* Add user defined class */
  903. if ( oCol.sClass !== null )
  904. {
  905. nTd.className = oCol.sClass;
  906. }
  907. if ( oCol.bVisible )
  908. {
  909. oData.nTr.appendChild( nTd );
  910. oData._anHidden[i] = null;
  911. }
  912. else
  913. {
  914. oData._anHidden[i] = nTd;
  915. }
  916. if ( oCol.fnCreatedCell )
  917. {
  918. oCol.fnCreatedCell.call( oSettings.oInstance,
  919. nTd, _fnGetCellData( oSettings, iRow, i, 'display' ), oData._aData, iRow, i
  920. );
  921. }
  922. }
  923. _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [oData.nTr, oData._aData, iRow] );
  924. }
  925. }
  926. /**
  927. * Create the HTML header for the table
  928. * @param {object} oSettings dataTables settings object
  929. * @memberof DataTable#oApi
  930. */
  931. function _fnBuildHead( oSettings )
  932. {
  933. var i, nTh, iLen, j, jLen;
  934. var iThs = oSettings.nTHead.getElementsByTagName('th').length;
  935. var iCorrector = 0;
  936. var jqChildren;
  937. /* If there is a header in place - then use it - otherwise it's going to get nuked... */
  938. if ( iThs !== 0 )
  939. {
  940. /* We've got a thead from the DOM, so remove hidden columns and apply width to vis cols */
  941. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  942. {
  943. nTh = oSettings.aoColumns[i].nTh;
  944. nTh.setAttribute('role', 'columnheader');
  945. if ( oSettings.aoColumns[i].bSortable )
  946. {
  947. nTh.setAttribute('tabindex', oSettings.iTabIndex);
  948. nTh.setAttribute('aria-controls', oSettings.sTableId);
  949. }
  950. if ( oSettings.aoColumns[i].sClass !== null )
  951. {
  952. $(nTh).addClass( oSettings.aoColumns[i].sClass );
  953. }
  954. /* Set the title of the column if it is user defined (not what was auto detected) */
  955. if ( oSettings.aoColumns[i].sTitle != nTh.innerHTML )
  956. {
  957. nTh.innerHTML = oSettings.aoColumns[i].sTitle;
  958. }
  959. }
  960. }
  961. else
  962. {
  963. /* We don't have a header in the DOM - so we are going to have to create one */
  964. var nTr = document.createElement( "tr" );
  965. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  966. {
  967. nTh = oSettings.aoColumns[i].nTh;
  968. nTh.innerHTML = oSettings.aoColumns[i].sTitle;
  969. nTh.setAttribute('tabindex', '0');
  970. if ( oSettings.aoColumns[i].sClass !== null )
  971. {
  972. $(nTh).addClass( oSettings.aoColumns[i].sClass );
  973. }
  974. nTr.appendChild( nTh );
  975. }
  976. $(oSettings.nTHead).html( '' )[0].appendChild( nTr );
  977. _fnDetectHeader( oSettings.aoHeader, oSettings.nTHead );
  978. }
  979. /* ARIA role for the rows */
  980. $(oSettings.nTHead).children('tr').attr('role', 'row');
  981. /* Add the extra markup needed by jQuery UI's themes */
  982. if ( oSettings.bJUI )
  983. {
  984. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  985. {
  986. nTh = oSettings.aoColumns[i].nTh;
  987. var nDiv = document.createElement('div');
  988. nDiv.className = oSettings.oClasses.sSortJUIWrapper;
  989. $(nTh).contents().appendTo(nDiv);
  990. var nSpan = document.createElement('span');
  991. nSpan.className = oSettings.oClasses.sSortIcon;
  992. nDiv.appendChild( nSpan );
  993. nTh.appendChild( nDiv );
  994. }
  995. }
  996. if ( oSettings.oFeatures.bSort )
  997. {
  998. for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
  999. {
  1000. if ( oSettings.aoColumns[i].bSortable !== false )
  1001. {
  1002. _fnSortAttachListener( oSettings, oSettings.aoColumns[i].nTh, i );
  1003. }
  1004. else
  1005. {
  1006. $(oSettings.aoColumns[i].nTh).addClass( oSettings.oClasses.sSortableNone );
  1007. }
  1008. }
  1009. }
  1010. /* Deal with the footer - add classes if required */
  1011. if ( oSettings.oClasses.sFooterTH !== "" )
  1012. {
  1013. $(oSettings.nTFoot).children('tr').children('th').addClass( oSettings.oClasses.sFooterTH );
  1014. }
  1015. /* Cache the footer elements */
  1016. if ( oSettings.nTFoot !== null )
  1017. {
  1018. var anCells = _fnGetUniqueThs( oSettings, null, oSettings.aoFooter );
  1019. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  1020. {
  1021. if ( anCells[i] )
  1022. {
  1023. oSettings.aoColumns[i].nTf = anCells[i];
  1024. if ( oSettings.aoColumns[i].sClass )
  1025. {
  1026. $(anCells[i]).addClass( oSettings.aoColumns[i].sClass );
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. /**
  1033. * Draw the header (or footer) element based on the column visibility states. The
  1034. * methodology here is to use the layout array from _fnDetectHeader, modified for
  1035. * the instantaneous column visibility, to construct the new layout. The grid is
  1036. * traversed over cell at a time in a rows x columns grid fashion, although each
  1037. * cell insert can cover multiple elements in the grid - which is tracks using the
  1038. * aApplied array. Cell inserts in the grid will only occur where there isn't
  1039. * already a cell in that position.
  1040. * @param {object} oSettings dataTables settings object
  1041. * @param array {objects} aoSource Layout array from _fnDetectHeader
  1042. * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
  1043. * @memberof DataTable#oApi
  1044. */
  1045. function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
  1046. {
  1047. var i, iLen, j, jLen, k, kLen, n, nLocalTr;
  1048. var aoLocal = [];
  1049. var aApplied = [];
  1050. var iColumns = oSettings.aoColumns.length;
  1051. var iRowspan, iColspan;
  1052. if ( bIncludeHidden === undefined )
  1053. {
  1054. bIncludeHidden = false;
  1055. }
  1056. /* Make a copy of the master layout array, but without the visible columns in it */
  1057. for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
  1058. {
  1059. aoLocal[i] = aoSource[i].slice();
  1060. aoLocal[i].nTr = aoSource[i].nTr;
  1061. /* Remove any columns which are currently hidden */
  1062. for ( j=iColumns-1 ; j>=0 ; j-- )
  1063. {
  1064. if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
  1065. {
  1066. aoLocal[i].splice( j, 1 );
  1067. }
  1068. }
  1069. /* Prep the applied array - it needs an element for each row */
  1070. aApplied.push( [] );
  1071. }
  1072. for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
  1073. {
  1074. nLocalTr = aoLocal[i].nTr;
  1075. /* All cells are going to be replaced, so empty out the row */
  1076. if ( nLocalTr )
  1077. {
  1078. while( (n = nLocalTr.firstChild) )
  1079. {
  1080. nLocalTr.removeChild( n );
  1081. }
  1082. }
  1083. for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
  1084. {
  1085. iRowspan = 1;
  1086. iColspan = 1;
  1087. /* Check to see if there is already a cell (row/colspan) covering our target
  1088. * insert point. If there is, then there is nothing to do.
  1089. */
  1090. if ( aApplied[i][j] === undefined )
  1091. {
  1092. nLocalTr.appendChild( aoLocal[i][j].cell );
  1093. aApplied[i][j] = 1;
  1094. /* Expand the cell to cover as many rows as needed */
  1095. while ( aoLocal[i+iRowspan] !== undefined &&
  1096. aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
  1097. {
  1098. aApplied[i+iRowspan][j] = 1;
  1099. iRowspan++;
  1100. }
  1101. /* Expand the cell to cover as many columns as needed */
  1102. while ( aoLocal[i][j+iColspan] !== undefined &&
  1103. aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
  1104. {
  1105. /* Must update the applied array over the rows for the columns */
  1106. for ( k=0 ; k<iRowspan ; k++ )
  1107. {
  1108. aApplied[i+k][j+iColspan] = 1;
  1109. }
  1110. iColspan++;
  1111. }
  1112. /* Do the actual expansion in the DOM */
  1113. aoLocal[i][j].cell.rowSpan = iRowspan;
  1114. aoLocal[i][j].cell.colSpan = iColspan;
  1115. }
  1116. }
  1117. }
  1118. }
  1119. /**
  1120. * Insert the required TR nodes into the table for display
  1121. * @param {object} oSettings dataTables settings object
  1122. * @memberof DataTable#oApi
  1123. */
  1124. function _fnDraw( oSettings )
  1125. {
  1126. var i, iLen, n;
  1127. var anRows = [];
  1128. var iRowCount = 0;
  1129. var iStripes = oSettings.asStripeClasses.length;
  1130. var iOpenRows = oSettings.aoOpenRows.length;
  1131. /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
  1132. var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
  1133. if ( $.inArray( false, aPreDraw ) !== -1 )
  1134. {
  1135. _fnProcessingDisplay( oSettings, false );
  1136. return;
  1137. }
  1138. oSettings.bDrawing = true;
  1139. /* Check and see if we have an initial draw position from state saving */
  1140. if ( oSettings.iInitDisplayStart !== undefined && oSettings.iInitDisplayStart != -1 )
  1141. {
  1142. if ( oSettings.oFeatures.bServerSide )
  1143. {
  1144. oSettings._iDisplayStart = oSettings.iInitDisplayStart;
  1145. }
  1146. else
  1147. {
  1148. oSettings._iDisplayStart = (oSettings.iInitDisplayStart >= oSettings.fnRecordsDisplay()) ?
  1149. 0 : oSettings.iInitDisplayStart;
  1150. }
  1151. oSettings.iInitDisplayStart = -1;
  1152. _fnCalculateEnd( oSettings );
  1153. }
  1154. /* Server-side processing draw intercept */
  1155. if ( oSettings.bDeferLoading )
  1156. {
  1157. oSettings.bDeferLoading = false;
  1158. oSettings.iDraw++;
  1159. }
  1160. else if ( !oSettings.oFeatures.bServerSide )
  1161. {
  1162. oSettings.iDraw++;
  1163. }
  1164. else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
  1165. {
  1166. return;
  1167. }
  1168. if ( oSettings.aiDisplay.length !== 0 )
  1169. {
  1170. var iStart = oSettings._iDisplayStart;
  1171. var iEnd = oSettings._iDisplayEnd;
  1172. if ( oSettings.oFeatures.bServerSide )
  1173. {
  1174. iStart = 0;
  1175. iEnd = oSettings.aoData.length;
  1176. }
  1177. for ( var j=iStart ; j<iEnd ; j++ )
  1178. {
  1179. var aoData = oSettings.aoData[ oSettings.aiDisplay[j] ];
  1180. if ( aoData.nTr === null )
  1181. {
  1182. _fnCreateTr( oSettings, oSettings.aiDisplay[j] );
  1183. }
  1184. var nRow = aoData.nTr;
  1185. /* Remove the old striping classes and then add the new one */
  1186. if ( iStripes !== 0 )
  1187. {
  1188. var sStripe = oSettings.asStripeClasses[ iRowCount % iStripes ];
  1189. if ( aoData._sRowStripe != sStripe )
  1190. {
  1191. $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
  1192. aoData._sRowStripe = sStripe;
  1193. }
  1194. }
  1195. /* Row callback functions - might want to manipule the row */
  1196. _fnCallbackFire( oSettings, 'aoRowCallback', null,
  1197. [nRow, oSettings.aoData[ oSettings.aiDisplay[j] ]._aData, iRowCount, j] );
  1198. anRows.push( nRow );
  1199. iRowCount++;
  1200. /* If there is an open row - and it is attached to this parent - attach it on redraw */
  1201. if ( iOpenRows !== 0 )
  1202. {
  1203. for ( var k=0 ; k<iOpenRows ; k++ )
  1204. {
  1205. if ( nRow == oSettings.aoOpenRows[k].nParent )
  1206. {
  1207. anRows.push( oSettings.aoOpenRows[k].nTr );
  1208. break;
  1209. }
  1210. }
  1211. }
  1212. }
  1213. }
  1214. else
  1215. {
  1216. /* Table is empty - create a row with an empty message in it */
  1217. anRows[ 0 ] = document.createElement( 'tr' );
  1218. if ( oSettings.asStripeClasses[0] )
  1219. {
  1220. anRows[ 0 ].className = oSettings.asStripeClasses[0];
  1221. }
  1222. var oLang = oSettings.oLanguage;
  1223. var sZero = oLang.sZeroRecords;
  1224. if ( oSettings.iDraw == 1 && oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide )
  1225. {
  1226. sZero = oLang.sLoadingRecords;
  1227. }
  1228. else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
  1229. {
  1230. sZero = oLang.sEmptyTable;
  1231. }
  1232. var nTd = document.createElement( 'td' );
  1233. nTd.setAttribute( 'valign', "top" );
  1234. nTd.colSpan = _fnVisbleColumns( oSettings );
  1235. nTd.className = oSettings.oClasses.sRowEmpty;
  1236. nTd.innerHTML = _fnInfoMacros( oSettings, sZero );
  1237. anRows[ iRowCount ].appendChild( nTd );
  1238. }
  1239. /* Header and footer callbacks */
  1240. _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
  1241. _fnGetDataMaster( oSettings ), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ] );
  1242. _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
  1243. _fnGetDataMaster( oSettings ), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ] );
  1244. /*
  1245. * Need to remove any old row from the display - note we can't just empty the tbody using
  1246. * $().html('') since this will unbind the jQuery event handlers (even although the node
  1247. * still exists!) - equally we can't use innerHTML, since IE throws an exception.
  1248. */
  1249. var
  1250. nAddFrag = document.createDocumentFragment(),
  1251. nRemoveFrag = document.createDocumentFragment(),
  1252. nBodyPar, nTrs;
  1253. if ( oSettings.nTBody )
  1254. {
  1255. nBodyPar = oSettings.nTBody.parentNode;
  1256. nRemoveFrag.appendChild( oSettings.nTBody );
  1257. /* When doing infinite scrolling, only remove child rows when sorting, filtering or start
  1258. * up. When not infinite scroll, always do it.
  1259. */
  1260. if ( !oSettings.oScroll.bInfinite || !oSettings._bInitComplete ||
  1261. oSettings.bSorted || oSettings.bFiltered )
  1262. {
  1263. while( (n = oSettings.nTBody.firstChild) )
  1264. {
  1265. oSettings.nTBody.removeChild( n );
  1266. }
  1267. }
  1268. /* Put the draw table into the dom */
  1269. for ( i=0, iLen=anRows.length ; i<iLen ; i++ )
  1270. {
  1271. nAddFrag.appendChild( anRows[i] );
  1272. }
  1273. oSettings.nTBody.appendChild( nAddFrag );
  1274. if ( nBodyPar !== null )
  1275. {
  1276. nBodyPar.appendChild( oSettings.nTBody );
  1277. }
  1278. }
  1279. /* Call all required callback functions for the end of a draw */
  1280. _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
  1281. /* Draw is complete, sorting and filtering must be as well */
  1282. oSettings.bSorted = false;
  1283. oSettings.bFiltered = false;
  1284. oSettings.bDrawing = false;
  1285. if ( oSettings.oFeatures.bServerSide )
  1286. {
  1287. _fnProcessingDisplay( oSettings, false );
  1288. if ( !oSettings._bInitComplete )
  1289. {
  1290. _fnInitComplete( oSettings );
  1291. }
  1292. }
  1293. }
  1294. /**
  1295. * Redraw the table - taking account of the various features which are enabled
  1296. * @param {object} oSettings dataTables settings object
  1297. * @memberof DataTable#oApi
  1298. */
  1299. function _fnReDraw( oSettings )
  1300. {
  1301. if ( oSettings.oFeatures.bSort )
  1302. {
  1303. /* Sorting will refilter and draw for us */
  1304. _fnSort( oSettings, oSettings.oPreviousSearch );
  1305. }
  1306. else if ( oSettings.oFeatures.bFilter )
  1307. {
  1308. /* Filtering will redraw for us */
  1309. _fnFilterComplete( oSettings, oSettings.oPreviousSearch );
  1310. }
  1311. else
  1312. {
  1313. _fnCalculateEnd( oSettings );
  1314. _fnDraw( oSettings );
  1315. }
  1316. }
  1317. /**
  1318. * Add the options to the page HTML for the table
  1319. * @param {object} oSettings dataTables settings object
  1320. * @memberof DataTable#oApi
  1321. */
  1322. function _fnAddOptionsHtml ( oSettings )
  1323. {
  1324. /*
  1325. * Create a temporary, empty, div which we can later on replace with what we have generated
  1326. * we do it this way to rendering the 'options' html offline - speed :-)
  1327. */
  1328. var nHolding = $('<div></div>')[0];
  1329. oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable );
  1330. /*
  1331. * All DataTables are wrapped in a div
  1332. */
  1333. oSettings.nTableWrapper = $('<div id="'+oSettings.sTableId+'_wrapper" class="'+oSettings.oClasses.sWrapper+'" role="grid"></div>')[0];
  1334. oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
  1335. /* Track where we want to insert the option */
  1336. var nInsertNode = oSettings.nTableWrapper;
  1337. /* Loop over the user set positioning and place the elements as needed */
  1338. var aDom = oSettings.sDom.split('');
  1339. var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j;
  1340. for ( var i=0 ; i<aDom.length ; i++ )
  1341. {
  1342. iPushFeature = 0;
  1343. cOption = aDom[i];
  1344. if ( cOption == '<' )
  1345. {
  1346. /* New container div */
  1347. nNewNode = $('<div></div>')[0];
  1348. /* Check to see if we should append an id and/or a class name to the container */
  1349. cNext = aDom[i+1];
  1350. if ( cNext == "'" || cNext == '"' )
  1351. {
  1352. sAttr = "";
  1353. j = 2;
  1354. while ( aDom[i+j] != cNext )
  1355. {
  1356. sAttr += aDom[i+j];
  1357. j++;
  1358. }
  1359. /* Replace jQuery UI constants */
  1360. if ( sAttr == "H" )
  1361. {
  1362. sAttr = "fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix";
  1363. }
  1364. else if ( sAttr == "F" )
  1365. {
  1366. sAttr = "fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix";
  1367. }
  1368. /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
  1369. * breaks the string into parts and applies them as needed
  1370. */
  1371. if ( sAttr.indexOf('.') != -1 )
  1372. {
  1373. var aSplit = sAttr.split('.');
  1374. nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
  1375. nNewNode.className = aSplit[1];
  1376. }
  1377. else if ( sAttr.charAt(0) == "#" )
  1378. {
  1379. nNewNode.id = sAttr.substr(1, sAttr.length-1);
  1380. }
  1381. else
  1382. {
  1383. nNewNode.className = sAttr;
  1384. }
  1385. i += j; /* Move along the position array */
  1386. }
  1387. nInsertNode.appendChild( nNewNode );
  1388. nInsertNode = nNewNode;
  1389. }
  1390. else if ( cOption == '>' )
  1391. {
  1392. /* End container div */
  1393. nInsertNode = nInsertNode.parentNode;
  1394. }
  1395. else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange )
  1396. {
  1397. /* Length */
  1398. nTmp = _fnFeatureHtmlLength( oSettings );
  1399. iPushFeature = 1;
  1400. }
  1401. else if ( cOption == 'f' && oSettings.oFeatures.bFilter )
  1402. {
  1403. /* Filter */
  1404. nTmp = _fnFeatureHtmlFilter( oSettings );
  1405. iPushFeature = 1;
  1406. }
  1407. else if ( cOption == 'r' && oSettings.oFeatures.bProcessing )
  1408. {
  1409. /* pRocessing */
  1410. nTmp = _fnFeatureHtmlProcessing( oSettings );
  1411. iPushFeature = 1;
  1412. }
  1413. else if ( cOption == 't' )
  1414. {
  1415. /* Table */
  1416. nTmp = _fnFeatureHtmlTable( oSettings );
  1417. iPushFeature = 1;
  1418. }
  1419. else if ( cOption == 'i' && oSettings.oFeatures.bInfo )
  1420. {
  1421. /* Info */
  1422. nTmp = _fnFeatureHtmlInfo( oSettings );
  1423. iPushFeature = 1;
  1424. }
  1425. else if ( cOption == 'p' && oSettings.oFeatures.bPaginate )
  1426. {
  1427. /* Pagination */
  1428. nTmp = _fnFeatureHtmlPaginate( oSettings );
  1429. iPushFeature = 1;
  1430. }
  1431. else if ( DataTable.ext.aoFeatures.length !== 0 )
  1432. {
  1433. /* Plug-in features */
  1434. var aoFeatures = DataTable.ext.aoFeatures;
  1435. for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
  1436. {
  1437. if ( cOption == aoFeatures[k].cFeature )
  1438. {
  1439. nTmp = aoFeatures[k].fnInit( oSettings );
  1440. if ( nTmp )
  1441. {
  1442. iPushFeature = 1;
  1443. }
  1444. break;
  1445. }
  1446. }
  1447. }
  1448. /* Add to the 2D features array */
  1449. if ( iPushFeature == 1 && nTmp !== null )
  1450. {
  1451. if ( typeof oSettings.aanFeatures[cOption] !== 'object' )
  1452. {
  1453. oSettings.aanFeatures[cOption] = [];
  1454. }
  1455. oSettings.aanFeatures[cOption].push( nTmp );
  1456. nInsertNode.appendChild( nTmp );
  1457. }
  1458. }
  1459. /* Built our DOM structure - replace the holding div with what we want */
  1460. nHolding.parentNode.replaceChild( oSettings.nTableWrapper, nHolding );
  1461. }
  1462. /**
  1463. * Use the DOM source to create up an array of header cells. The idea here is to
  1464. * create a layout grid (array) of rows x columns, which contains a reference
  1465. * to the cell that that point in the grid (regardless of col/rowspan), such that
  1466. * any column / row could be removed and the new grid constructed
  1467. * @param array {object} aLayout Array to store the calculated layout in
  1468. * @param {node} nThead The header/footer element for the table
  1469. * @memberof DataTable#oApi
  1470. */
  1471. function _fnDetectHeader ( aLayout, nThead )
  1472. {
  1473. var nTrs = $(nThead).children('tr');
  1474. var nCell;
  1475. var i, j, k, l, iLen, jLen, iColShifted;
  1476. var fnShiftCol = function ( a, i, j ) {
  1477. while ( a[i][j] ) {
  1478. j++;
  1479. }
  1480. return j;
  1481. };
  1482. aLayout.splice( 0, aLayout.length );
  1483. /* We know how many rows there are in the layout - so prep it */
  1484. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  1485. {
  1486. aLayout.push( [] );
  1487. }
  1488. /* Calculate a layout array */
  1489. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  1490. {
  1491. var iColumn = 0;
  1492. /* For every cell in the row... */
  1493. for ( j=0, jLen=nTrs[i].childNodes.length ; j<jLen ; j++ )
  1494. {
  1495. nCell = nTrs[i].childNodes[j];
  1496. if ( nCell.nodeName.toUpperCase() == "TD" ||
  1497. nCell.nodeName.toUpperCase() == "TH" )
  1498. {
  1499. /* Get the col and rowspan attributes from the DOM and sanitise them */
  1500. var iColspan = nCell.getAttribute('colspan') * 1;
  1501. var iRowspan = nCell.getAttribute('rowspan') * 1;
  1502. iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
  1503. iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
  1504. /* There might be colspan cells already in this row, so shift our target
  1505. * accordingly
  1506. */
  1507. iColShifted = fnShiftCol( aLayout, i, iColumn );
  1508. /* If there is col / rowspan, copy the information into the layout grid */
  1509. for ( l=0 ; l<iColspan ; l++ )
  1510. {
  1511. for ( k=0 ; k<iRowspan ; k++ )
  1512. {
  1513. aLayout[i+k][iColShifted+l] = {
  1514. "cell": nCell,
  1515. "unique": iColspan == 1 ? true : false
  1516. };
  1517. aLayout[i+k].nTr = nTrs[i];
  1518. }
  1519. }
  1520. }
  1521. }
  1522. }
  1523. }
  1524. /**
  1525. * Get an array of unique th elements, one for each column
  1526. * @param {object} oSettings dataTables settings object
  1527. * @param {node} nHeader automatically detect the layout from this node - optional
  1528. * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
  1529. * @returns array {node} aReturn list of unique ths
  1530. * @memberof DataTable#oApi
  1531. */
  1532. function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
  1533. {
  1534. var aReturn = [];
  1535. if ( !aLayout )
  1536. {
  1537. aLayout = oSettings.aoHeader;
  1538. if ( nHeader )
  1539. {
  1540. aLayout = [];
  1541. _fnDetectHeader( aLayout, nHeader );
  1542. }
  1543. }
  1544. for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
  1545. {
  1546. for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
  1547. {
  1548. if ( aLayout[i][j].unique &&
  1549. (!aReturn[j] || !oSettings.bSortCellsTop) )
  1550. {
  1551. aReturn[j] = aLayout[i][j].cell;
  1552. }
  1553. }
  1554. }
  1555. return aReturn;
  1556. }
  1557. /**
  1558. * Update the table using an Ajax call
  1559. * @param {object} oSettings dataTables settings object
  1560. * @returns {boolean} Block the table drawing or not
  1561. * @memberof DataTable#oApi
  1562. */
  1563. function _fnAjaxUpdate( oSettings )
  1564. {
  1565. if ( oSettings.bAjaxDataGet )
  1566. {
  1567. oSettings.iDraw++;
  1568. _fnProcessingDisplay( oSettings, true );
  1569. var iColumns = oSettings.aoColumns.length;
  1570. var aoData = _fnAjaxParameters( oSettings );
  1571. _fnServerParams( oSettings, aoData );
  1572. oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aoData,
  1573. function(json) {
  1574. _fnAjaxUpdateDraw( oSettings, json );
  1575. }, oSettings );
  1576. return false;
  1577. }
  1578. else
  1579. {
  1580. return true;
  1581. }
  1582. }
  1583. /**
  1584. * Build up the parameters in an object needed for a server-side processing request
  1585. * @param {object} oSettings dataTables settings object
  1586. * @returns {bool} block the table drawing or not
  1587. * @memberof DataTable#oApi
  1588. */
  1589. function _fnAjaxParameters( oSettings )
  1590. {
  1591. var iColumns = oSettings.aoColumns.length;
  1592. var aoData = [], mDataProp, aaSort, aDataSort;
  1593. var i, j;
  1594. aoData.push( { "name": "sEcho", "value": oSettings.iDraw } );
  1595. aoData.push( { "name": "iColumns", "value": iColumns } );
  1596. aoData.push( { "name": "sColumns", "value": _fnColumnOrdering(oSettings) } );
  1597. aoData.push( { "name": "iDisplayStart", "value": oSettings._iDisplayStart } );
  1598. aoData.push( { "name": "iDisplayLength", "value": oSettings.oFeatures.bPaginate !== false ?
  1599. oSettings._iDisplayLength : -1 } );
  1600. for ( i=0 ; i<iColumns ; i++ )
  1601. {
  1602. mDataProp = oSettings.aoColumns[i].mDataProp;
  1603. aoData.push( { "name": "mDataProp_"+i, "value": typeof(mDataProp)==="function" ? 'function' : mDataProp } );
  1604. }
  1605. /* Filtering */
  1606. if ( oSettings.oFeatures.bFilter !== false )
  1607. {
  1608. aoData.push( { "name": "sSearch", "value": oSettings.oPreviousSearch.sSearch } );
  1609. aoData.push( { "name": "bRegex", "value": oSettings.oPreviousSearch.bRegex } );
  1610. for ( i=0 ; i<iColumns ; i++ )
  1611. {
  1612. aoData.push( { "name": "sSearch_"+i, "value": oSettings.aoPreSearchCols[i].sSearch } );
  1613. aoData.push( { "name": "bRegex_"+i, "value": oSettings.aoPreSearchCols[i].bRegex } );
  1614. aoData.push( { "name": "bSearchable_"+i, "value": oSettings.aoColumns[i].bSearchable } );
  1615. }
  1616. }
  1617. /* Sorting */
  1618. if ( oSettings.oFeatures.bSort !== false )
  1619. {
  1620. var iCounter = 0;
  1621. aaSort = ( oSettings.aaSortingFixed !== null ) ?
  1622. oSettings.aaSortingFixed.concat( oSettings.aaSorting ) :
  1623. oSettings.aaSorting.slice();
  1624. for ( i=0 ; i<aaSort.length ; i++ )
  1625. {
  1626. aDataSort = oSettings.aoColumns[ aaSort[i][0] ].aDataSort;
  1627. for ( j=0 ; j<aDataSort.length ; j++ )
  1628. {
  1629. aoData.push( { "name": "iSortCol_"+iCounter, "value": aDataSort[j] } );
  1630. aoData.push( { "name": "sSortDir_"+iCounter, "value": aaSort[i][1] } );
  1631. iCounter++;
  1632. }
  1633. }
  1634. aoData.push( { "name": "iSortingCols", "value": iCounter } );
  1635. for ( i=0 ; i<iColumns ; i++ )
  1636. {
  1637. aoData.push( { "name": "bSortable_"+i, "value": oSettings.aoColumns[i].bSortable } );
  1638. }
  1639. }
  1640. return aoData;
  1641. }
  1642. /**
  1643. * Add Ajax parameters from plugins
  1644. * @param {object} oSettings dataTables settings object
  1645. * @param array {objects} aoData name/value pairs to send to the server
  1646. * @memberof DataTable#oApi
  1647. */
  1648. function _fnServerParams( oSettings, aoData )
  1649. {
  1650. _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [aoData] );
  1651. }
  1652. /**
  1653. * Data the data from the server (nuking the old) and redraw the table
  1654. * @param {object} oSettings dataTables settings object
  1655. * @param {object} json json data return from the server.
  1656. * @param {string} json.sEcho Tracking flag for DataTables to match requests
  1657. * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
  1658. * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
  1659. * @param {array} json.aaData The data to display on this page
  1660. * @param {string} [json.sColumns] Column ordering (sName, comma separated)
  1661. * @memberof DataTable#oApi
  1662. */
  1663. function _fnAjaxUpdateDraw ( oSettings, json )
  1664. {
  1665. if ( json.sEcho !== undefined )
  1666. {
  1667. /* Protect against old returns over-writing a new one. Possible when you get
  1668. * very fast interaction, and later queires are completed much faster
  1669. */
  1670. if ( json.sEcho*1 < oSettings.iDraw )
  1671. {
  1672. return;
  1673. }
  1674. else
  1675. {
  1676. oSettings.iDraw = json.sEcho * 1;
  1677. }
  1678. }
  1679. if ( !oSettings.oScroll.bInfinite ||
  1680. (oSettings.oScroll.bInfinite && (oSettings.bSorted || oSettings.bFiltered)) )
  1681. {
  1682. _fnClearTable( oSettings );
  1683. }
  1684. oSettings._iRecordsTotal = parseInt(json.iTotalRecords, 10);
  1685. oSettings._iRecordsDisplay = parseInt(json.iTotalDisplayRecords, 10);
  1686. /* Determine if reordering is required */
  1687. var sOrdering = _fnColumnOrdering(oSettings);
  1688. var bReOrder = (json.sColumns !== undefined && sOrdering !== "" && json.sColumns != sOrdering );
  1689. var aiIndex;
  1690. if ( bReOrder )
  1691. {
  1692. aiIndex = _fnReOrderIndex( oSettings, json.sColumns );
  1693. }
  1694. var aData = _fnGetObjectDataFn( oSettings.sAjaxDataProp )( json );
  1695. for ( var i=0, iLen=aData.length ; i<iLen ; i++ )
  1696. {
  1697. if ( bReOrder )
  1698. {
  1699. /* If we need to re-order, then create a new array with the correct order and add it */
  1700. var aDataSorted = [];
  1701. for ( var j=0, jLen=oSettings.aoColumns.length ; j<jLen ; j++ )
  1702. {
  1703. aDataSorted.push( aData[i][ aiIndex[j] ] );
  1704. }
  1705. _fnAddData( oSettings, aDataSorted );
  1706. }
  1707. else
  1708. {
  1709. /* No re-order required, sever got it "right" - just straight add */
  1710. _fnAddData( oSettings, aData[i] );
  1711. }
  1712. }
  1713. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  1714. oSettings.bAjaxDataGet = false;
  1715. _fnDraw( oSettings );
  1716. oSettings.bAjaxDataGet = true;
  1717. _fnProcessingDisplay( oSettings, false );
  1718. }
  1719. /**
  1720. * Generate the node required for filtering text
  1721. * @returns {node} Filter control element
  1722. * @param {object} oSettings dataTables settings object
  1723. * @memberof DataTable#oApi
  1724. */
  1725. function _fnFeatureHtmlFilter ( oSettings )
  1726. {
  1727. var oPreviousSearch = oSettings.oPreviousSearch;
  1728. var sSearchStr = oSettings.oLanguage.sSearch;
  1729. sSearchStr = (sSearchStr.indexOf('_INPUT_') !== -1) ?
  1730. sSearchStr.replace('_INPUT_', '<input type="text" />') :
  1731. sSearchStr==="" ? '<input type="text" />' : sSearchStr+' <input type="text" />';
  1732. var nFilter = document.createElement( 'div' );
  1733. nFilter.className = oSettings.oClasses.sFilter;
  1734. nFilter.innerHTML = '<label>'+sSearchStr+'</label>';
  1735. if ( !oSettings.aanFeatures.f )
  1736. {
  1737. nFilter.id = oSettings.sTableId+'_filter';
  1738. }
  1739. var jqFilter = $('input[type="text"]', nFilter);
  1740. // Store a reference to the input element, so other input elements could be
  1741. // added to the filter wrapper if needed (submit button for example)
  1742. nFilter._DT_Input = jqFilter[0];
  1743. jqFilter.val( oPreviousSearch.sSearch.replace('"','&quot;') );
  1744. jqFilter.bind( 'keyup.DT', function(e) {
  1745. /* Update all other filter input elements for the new display */
  1746. var n = oSettings.aanFeatures.f;
  1747. var val = this.value==="" ? "" : this.value; // mental IE8 fix :-(
  1748. for ( var i=0, iLen=n.length ; i<iLen ; i++ )
  1749. {
  1750. if ( n[i] != $(this).parents('div.dataTables_filter')[0] )
  1751. {
  1752. $(n[i]._DT_Input).val( val );
  1753. }
  1754. }
  1755. /* Now do the filter */
  1756. if ( val != oPreviousSearch.sSearch )
  1757. {
  1758. _fnFilterComplete( oSettings, {
  1759. "sSearch": val,
  1760. "bRegex": oPreviousSearch.bRegex,
  1761. "bSmart": oPreviousSearch.bSmart ,
  1762. "bCaseInsensitive": oPreviousSearch.bCaseInsensitive
  1763. } );
  1764. }
  1765. } );
  1766. jqFilter
  1767. .attr('aria-controls', oSettings.sTableId)
  1768. .bind( 'keypress.DT', function(e) {
  1769. /* Prevent form submission */
  1770. if ( e.keyCode == 13 )
  1771. {
  1772. return false;
  1773. }
  1774. }
  1775. );
  1776. return nFilter;
  1777. }
  1778. /**
  1779. * Filter the table using both the global filter and column based filtering
  1780. * @param {object} oSettings dataTables settings object
  1781. * @param {object} oSearch search information
  1782. * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
  1783. * @memberof DataTable#oApi
  1784. */
  1785. function _fnFilterComplete ( oSettings, oInput, iForce )
  1786. {
  1787. var oPrevSearch = oSettings.oPreviousSearch;
  1788. var aoPrevSearch = oSettings.aoPreSearchCols;
  1789. var fnSaveFilter = function ( oFilter ) {
  1790. /* Save the filtering values */
  1791. oPrevSearch.sSearch = oFilter.sSearch;
  1792. oPrevSearch.bRegex = oFilter.bRegex;
  1793. oPrevSearch.bSmart = oFilter.bSmart;
  1794. oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
  1795. };
  1796. /* In server-side processing all filtering is done by the server, so no point hanging around here */
  1797. if ( !oSettings.oFeatures.bServerSide )
  1798. {
  1799. /* Global filter */
  1800. _fnFilter( oSettings, oInput.sSearch, iForce, oInput.bRegex, oInput.bSmart, oInput.bCaseInsensitive );
  1801. fnSaveFilter( oInput );
  1802. /* Now do the individual column filter */
  1803. for ( var i=0 ; i<oSettings.aoPreSearchCols.length ; i++ )
  1804. {
  1805. _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, aoPrevSearch[i].bRegex,
  1806. aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
  1807. }
  1808. /* Custom filtering */
  1809. _fnFilterCustom( oSettings );
  1810. }
  1811. else
  1812. {
  1813. fnSaveFilter( oInput );
  1814. }
  1815. /* Tell the draw function we have been filtering */
  1816. oSettings.bFiltered = true;
  1817. $(oSettings.oInstance).trigger('filter', oSettings);
  1818. /* Redraw the table */
  1819. oSettings._iDisplayStart = 0;
  1820. _fnCalculateEnd( oSettings );
  1821. _fnDraw( oSettings );
  1822. /* Rebuild search array 'offline' */
  1823. _fnBuildSearchArray( oSettings, 0 );
  1824. }
  1825. /**
  1826. * Apply custom filtering functions
  1827. * @param {object} oSettings dataTables settings object
  1828. * @memberof DataTable#oApi
  1829. */
  1830. function _fnFilterCustom( oSettings )
  1831. {
  1832. var afnFilters = DataTable.ext.afnFiltering;
  1833. for ( var i=0, iLen=afnFilters.length ; i<iLen ; i++ )
  1834. {
  1835. var iCorrector = 0;
  1836. for ( var j=0, jLen=oSettings.aiDisplay.length ; j<jLen ; j++ )
  1837. {
  1838. var iDisIndex = oSettings.aiDisplay[j-iCorrector];
  1839. /* Check if we should use this row based on the filtering function */
  1840. if ( !afnFilters[i]( oSettings, _fnGetRowData( oSettings, iDisIndex, 'filter' ), iDisIndex ) )
  1841. {
  1842. oSettings.aiDisplay.splice( j-iCorrector, 1 );
  1843. iCorrector++;
  1844. }
  1845. }
  1846. }
  1847. }
  1848. /**
  1849. * Filter the table on a per-column basis
  1850. * @param {object} oSettings dataTables settings object
  1851. * @param {string} sInput string to filter on
  1852. * @param {int} iColumn column to filter
  1853. * @param {bool} bRegex treat search string as a regular expression or not
  1854. * @param {bool} bSmart use smart filtering or not
  1855. * @param {bool} bCaseInsensitive Do case insenstive matching or not
  1856. * @memberof DataTable#oApi
  1857. */
  1858. function _fnFilterColumn ( oSettings, sInput, iColumn, bRegex, bSmart, bCaseInsensitive )
  1859. {
  1860. if ( sInput === "" )
  1861. {
  1862. return;
  1863. }
  1864. var iIndexCorrector = 0;
  1865. var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive );
  1866. for ( var i=oSettings.aiDisplay.length-1 ; i>=0 ; i-- )
  1867. {
  1868. var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ),
  1869. oSettings.aoColumns[iColumn].sType );
  1870. if ( ! rpSearch.test( sData ) )
  1871. {
  1872. oSettings.aiDisplay.splice( i, 1 );
  1873. iIndexCorrector++;
  1874. }
  1875. }
  1876. }
  1877. /**
  1878. * Filter the data table based on user input and draw the table
  1879. * @param {object} oSettings dataTables settings object
  1880. * @param {string} sInput string to filter on
  1881. * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0)
  1882. * @param {bool} bRegex treat as a regular expression or not
  1883. * @param {bool} bSmart perform smart filtering or not
  1884. * @param {bool} bCaseInsensitive Do case insenstive matching or not
  1885. * @memberof DataTable#oApi
  1886. */
  1887. function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive )
  1888. {
  1889. var i;
  1890. var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive );
  1891. var oPrevSearch = oSettings.oPreviousSearch;
  1892. /* Check if we are forcing or not - optional parameter */
  1893. if ( !iForce )
  1894. {
  1895. iForce = 0;
  1896. }
  1897. /* Need to take account of custom filtering functions - always filter */
  1898. if ( DataTable.ext.afnFiltering.length !== 0 )
  1899. {
  1900. iForce = 1;
  1901. }
  1902. /*
  1903. * If the input is blank - we want the full data set
  1904. */
  1905. if ( sInput.length <= 0 )
  1906. {
  1907. oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
  1908. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  1909. }
  1910. else
  1911. {
  1912. /*
  1913. * We are starting a new search or the new search string is smaller
  1914. * then the old one (i.e. delete). Search from the master array
  1915. */
  1916. if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length ||
  1917. oPrevSearch.sSearch.length > sInput.length || iForce == 1 ||
  1918. sInput.indexOf(oPrevSearch.sSearch) !== 0 )
  1919. {
  1920. /* Nuke the old display array - we are going to rebuild it */
  1921. oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
  1922. /* Force a rebuild of the search array */
  1923. _fnBuildSearchArray( oSettings, 1 );
  1924. /* Search through all records to populate the search array
  1925. * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1
  1926. * mapping
  1927. */
  1928. for ( i=0 ; i<oSettings.aiDisplayMaster.length ; i++ )
  1929. {
  1930. if ( rpSearch.test(oSettings.asDataSearch[i]) )
  1931. {
  1932. oSettings.aiDisplay.push( oSettings.aiDisplayMaster[i] );
  1933. }
  1934. }
  1935. }
  1936. else
  1937. {
  1938. /* Using old search array - refine it - do it this way for speed
  1939. * Don't have to search the whole master array again
  1940. */
  1941. var iIndexCorrector = 0;
  1942. /* Search the current results */
  1943. for ( i=0 ; i<oSettings.asDataSearch.length ; i++ )
  1944. {
  1945. if ( ! rpSearch.test(oSettings.asDataSearch[i]) )
  1946. {
  1947. oSettings.aiDisplay.splice( i-iIndexCorrector, 1 );
  1948. iIndexCorrector++;
  1949. }
  1950. }
  1951. }
  1952. }
  1953. }
  1954. /**
  1955. * Create an array which can be quickly search through
  1956. * @param {object} oSettings dataTables settings object
  1957. * @param {int} iMaster use the master data array - optional
  1958. * @memberof DataTable#oApi
  1959. */
  1960. function _fnBuildSearchArray ( oSettings, iMaster )
  1961. {
  1962. if ( !oSettings.oFeatures.bServerSide )
  1963. {
  1964. /* Clear out the old data */
  1965. oSettings.asDataSearch.splice( 0, oSettings.asDataSearch.length );
  1966. var aArray = (iMaster && iMaster===1) ?
  1967. oSettings.aiDisplayMaster : oSettings.aiDisplay;
  1968. for ( var i=0, iLen=aArray.length ; i<iLen ; i++ )
  1969. {
  1970. oSettings.asDataSearch[i] = _fnBuildSearchRow( oSettings,
  1971. _fnGetRowData( oSettings, aArray[i], 'filter' ) );
  1972. }
  1973. }
  1974. }
  1975. /**
  1976. * Create a searchable string from a single data row
  1977. * @param {object} oSettings dataTables settings object
  1978. * @param {array} aData Row data array to use for the data to search
  1979. * @memberof DataTable#oApi
  1980. */
  1981. function _fnBuildSearchRow( oSettings, aData )
  1982. {
  1983. var sSearch = '';
  1984. if ( oSettings.__nTmpFilter === undefined )
  1985. {
  1986. oSettings.__nTmpFilter = document.createElement('div');
  1987. }
  1988. var nTmp = oSettings.__nTmpFilter;
  1989. for ( var j=0, jLen=oSettings.aoColumns.length ; j<jLen ; j++ )
  1990. {
  1991. if ( oSettings.aoColumns[j].bSearchable )
  1992. {
  1993. var sData = aData[j];
  1994. sSearch += _fnDataToSearch( sData, oSettings.aoColumns[j].sType )+' ';
  1995. }
  1996. }
  1997. /* If it looks like there is an HTML entity in the string, attempt to decode it */
  1998. if ( sSearch.indexOf('&') !== -1 )
  1999. {
  2000. nTmp.innerHTML = sSearch;
  2001. sSearch = nTmp.textContent ? nTmp.textContent : nTmp.innerText;
  2002. /* IE and Opera appear to put an newline where there is a <br> tag - remove it */
  2003. sSearch = sSearch.replace(/\n/g," ").replace(/\r/g,"");
  2004. }
  2005. return sSearch;
  2006. }
  2007. /**
  2008. * Build a regular expression object suitable for searching a table
  2009. * @param {string} sSearch string to search for
  2010. * @param {bool} bRegex treat as a regular expression or not
  2011. * @param {bool} bSmart perform smart filtering or not
  2012. * @param {bool} bCaseInsensitive Do case insenstive matching or not
  2013. * @returns {RegExp} constructed object
  2014. * @memberof DataTable#oApi
  2015. */
  2016. function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive )
  2017. {
  2018. var asSearch, sRegExpString;
  2019. if ( bSmart )
  2020. {
  2021. /* Generate the regular expression to use. Something along the lines of:
  2022. * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$
  2023. */
  2024. asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' );
  2025. sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$';
  2026. return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" );
  2027. }
  2028. else
  2029. {
  2030. sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch );
  2031. return new RegExp( sSearch, bCaseInsensitive ? "i" : "" );
  2032. }
  2033. }
  2034. /**
  2035. * Convert raw data into something that the user can search on
  2036. * @param {string} sData data to be modified
  2037. * @param {string} sType data type
  2038. * @returns {string} search string
  2039. * @memberof DataTable#oApi
  2040. */
  2041. function _fnDataToSearch ( sData, sType )
  2042. {
  2043. if ( typeof DataTable.ext.ofnSearch[sType] === "function" )
  2044. {
  2045. return DataTable.ext.ofnSearch[sType]( sData );
  2046. }
  2047. else if ( sData === null )
  2048. {
  2049. return '';
  2050. }
  2051. else if ( sType == "html" )
  2052. {
  2053. return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" );
  2054. }
  2055. else if ( typeof sData === "string" )
  2056. {
  2057. return sData.replace(/[\r\n]/g," ");
  2058. }
  2059. return sData;
  2060. }
  2061. /**
  2062. * scape a string stuch that it can be used in a regular expression
  2063. * @param {string} sVal string to escape
  2064. * @returns {string} escaped string
  2065. * @memberof DataTable#oApi
  2066. */
  2067. function _fnEscapeRegex ( sVal )
  2068. {
  2069. var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^' ];
  2070. var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' );
  2071. return sVal.replace(reReplace, '\\$1');
  2072. }
  2073. /**
  2074. * Generate the node required for the info display
  2075. * @param {object} oSettings dataTables settings object
  2076. * @returns {node} Information element
  2077. * @memberof DataTable#oApi
  2078. */
  2079. function _fnFeatureHtmlInfo ( oSettings )
  2080. {
  2081. var nInfo = document.createElement( 'div' );
  2082. nInfo.className = oSettings.oClasses.sInfo;
  2083. /* Actions that are to be taken once only for this feature */
  2084. if ( !oSettings.aanFeatures.i )
  2085. {
  2086. /* Add draw callback */
  2087. oSettings.aoDrawCallback.push( {
  2088. "fn": _fnUpdateInfo,
  2089. "sName": "information"
  2090. } );
  2091. /* Add id */
  2092. nInfo.id = oSettings.sTableId+'_info';
  2093. }
  2094. oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' );
  2095. return nInfo;
  2096. }
  2097. /**
  2098. * Update the information elements in the display
  2099. * @param {object} oSettings dataTables settings object
  2100. * @memberof DataTable#oApi
  2101. */
  2102. function _fnUpdateInfo ( oSettings )
  2103. {
  2104. /* Show information about the table */
  2105. if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 )
  2106. {
  2107. return;
  2108. }
  2109. var
  2110. oLang = oSettings.oLanguage,
  2111. iStart = oSettings._iDisplayStart+1,
  2112. iEnd = oSettings.fnDisplayEnd(),
  2113. iMax = oSettings.fnRecordsTotal(),
  2114. iTotal = oSettings.fnRecordsDisplay(),
  2115. sOut;
  2116. if ( iTotal === 0 && iTotal == iMax )
  2117. {
  2118. /* Empty record set */
  2119. sOut = oLang.sInfoEmpty;
  2120. }
  2121. else if ( iTotal === 0 )
  2122. {
  2123. /* Empty record set after filtering */
  2124. sOut = oLang.sInfoEmpty +' '+ oLang.sInfoFiltered;
  2125. }
  2126. else if ( iTotal == iMax )
  2127. {
  2128. /* Normal record set */
  2129. sOut = oLang.sInfo;
  2130. }
  2131. else
  2132. {
  2133. /* Record set after filtering */
  2134. sOut = oLang.sInfo +' '+ oLang.sInfoFiltered;
  2135. }
  2136. // Convert the macros
  2137. sOut += oLang.sInfoPostFix;
  2138. sOut = _fnInfoMacros( oSettings, sOut );
  2139. if ( oLang.fnInfoCallback !== null )
  2140. {
  2141. sOut = oLang.fnInfoCallback.call( oSettings.oInstance,
  2142. oSettings, iStart, iEnd, iMax, iTotal, sOut );
  2143. }
  2144. var n = oSettings.aanFeatures.i;
  2145. for ( var i=0, iLen=n.length ; i<iLen ; i++ )
  2146. {
  2147. $(n[i]).html( sOut );
  2148. }
  2149. }
  2150. function _fnInfoMacros ( oSettings, str )
  2151. {
  2152. var
  2153. iStart = oSettings._iDisplayStart+1,
  2154. sStart = oSettings.fnFormatNumber( iStart ),
  2155. iEnd = oSettings.fnDisplayEnd(),
  2156. sEnd = oSettings.fnFormatNumber( iEnd ),
  2157. iTotal = oSettings.fnRecordsDisplay(),
  2158. sTotal = oSettings.fnFormatNumber( iTotal ),
  2159. iMax = oSettings.fnRecordsTotal(),
  2160. sMax = oSettings.fnFormatNumber( iMax );
  2161. // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
  2162. // internally
  2163. if ( oSettings.oScroll.bInfinite )
  2164. {
  2165. sStart = oSettings.fnFormatNumber( 1 );
  2166. }
  2167. return str.
  2168. replace('_START_', sStart).
  2169. replace('_END_', sEnd).
  2170. replace('_TOTAL_', sTotal).
  2171. replace('_MAX_', sMax);
  2172. }
  2173. /**
  2174. * Draw the table for the first time, adding all required features
  2175. * @param {object} oSettings dataTables settings object
  2176. * @memberof DataTable#oApi
  2177. */
  2178. function _fnInitialise ( oSettings )
  2179. {
  2180. var i, iLen, iAjaxStart=oSettings.iInitDisplayStart;
  2181. /* Ensure that the table data is fully initialised */
  2182. if ( oSettings.bInitialised === false )
  2183. {
  2184. setTimeout( function(){ _fnInitialise( oSettings ); }, 200 );
  2185. return;
  2186. }
  2187. /* Show the display HTML options */
  2188. _fnAddOptionsHtml( oSettings );
  2189. /* Build and draw the header / footer for the table */
  2190. _fnBuildHead( oSettings );
  2191. _fnDrawHead( oSettings, oSettings.aoHeader );
  2192. if ( oSettings.nTFoot )
  2193. {
  2194. _fnDrawHead( oSettings, oSettings.aoFooter );
  2195. }
  2196. /* Okay to show that something is going on now */
  2197. _fnProcessingDisplay( oSettings, true );
  2198. /* Calculate sizes for columns */
  2199. if ( oSettings.oFeatures.bAutoWidth )
  2200. {
  2201. _fnCalculateColumnWidths( oSettings );
  2202. }
  2203. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  2204. {
  2205. if ( oSettings.aoColumns[i].sWidth !== null )
  2206. {
  2207. oSettings.aoColumns[i].nTh.style.width = _fnStringToCss( oSettings.aoColumns[i].sWidth );
  2208. }
  2209. }
  2210. /* If there is default sorting required - let's do it. The sort function will do the
  2211. * drawing for us. Otherwise we draw the table regardless of the Ajax source - this allows
  2212. * the table to look initialised for Ajax sourcing data (show 'loading' message possibly)
  2213. */
  2214. if ( oSettings.oFeatures.bSort )
  2215. {
  2216. _fnSort( oSettings );
  2217. }
  2218. else if ( oSettings.oFeatures.bFilter )
  2219. {
  2220. _fnFilterComplete( oSettings, oSettings.oPreviousSearch );
  2221. }
  2222. else
  2223. {
  2224. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  2225. _fnCalculateEnd( oSettings );
  2226. _fnDraw( oSettings );
  2227. }
  2228. /* if there is an ajax source load the data */
  2229. if ( oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide )
  2230. {
  2231. var aoData = [];
  2232. _fnServerParams( oSettings, aoData );
  2233. oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aoData, function(json) {
  2234. var aData = (oSettings.sAjaxDataProp !== "") ?
  2235. _fnGetObjectDataFn( oSettings.sAjaxDataProp )(json) : json;
  2236. /* Got the data - add it to the table */
  2237. for ( i=0 ; i<aData.length ; i++ )
  2238. {
  2239. _fnAddData( oSettings, aData[i] );
  2240. }
  2241. /* Reset the init display for cookie saving. We've already done a filter, and
  2242. * therefore cleared it before. So we need to make it appear 'fresh'
  2243. */
  2244. oSettings.iInitDisplayStart = iAjaxStart;
  2245. if ( oSettings.oFeatures.bSort )
  2246. {
  2247. _fnSort( oSettings );
  2248. }
  2249. else
  2250. {
  2251. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  2252. _fnCalculateEnd( oSettings );
  2253. _fnDraw( oSettings );
  2254. }
  2255. _fnProcessingDisplay( oSettings, false );
  2256. _fnInitComplete( oSettings, json );
  2257. }, oSettings );
  2258. return;
  2259. }
  2260. /* Server-side processing initialisation complete is done at the end of _fnDraw */
  2261. if ( !oSettings.oFeatures.bServerSide )
  2262. {
  2263. _fnProcessingDisplay( oSettings, false );
  2264. _fnInitComplete( oSettings );
  2265. }
  2266. }
  2267. /**
  2268. * Draw the table for the first time, adding all required features
  2269. * @param {object} oSettings dataTables settings object
  2270. * @param {object} [json] JSON from the server that completed the table, if using Ajax source
  2271. * with client-side processing (optional)
  2272. * @memberof DataTable#oApi
  2273. */
  2274. function _fnInitComplete ( oSettings, json )
  2275. {
  2276. oSettings._bInitComplete = true;
  2277. _fnCallbackFire( oSettings, 'aoInitComplete', 'init', [oSettings, json] );
  2278. }
  2279. /**
  2280. * Language compatibility - when certain options are given, and others aren't, we
  2281. * need to duplicate the values over, in order to provide backwards compatibility
  2282. * with older language files.
  2283. * @param {object} oSettings dataTables settings object
  2284. * @memberof DataTable#oApi
  2285. */
  2286. function _fnLanguageCompat( oLanguage )
  2287. {
  2288. var oDefaults = DataTable.defaults.oLanguage;
  2289. /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
  2290. * sZeroRecords - assuming that is given.
  2291. */
  2292. if ( !oLanguage.sEmptyTable && oLanguage.sZeroRecords &&
  2293. oDefaults.sEmptyTable === "No data available in table" )
  2294. {
  2295. _fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sEmptyTable' );
  2296. }
  2297. /* Likewise with loading records */
  2298. if ( !oLanguage.sLoadingRecords && oLanguage.sZeroRecords &&
  2299. oDefaults.sLoadingRecords === "Loading..." )
  2300. {
  2301. _fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sLoadingRecords' );
  2302. }
  2303. }
  2304. /**
  2305. * Generate the node required for user display length changing
  2306. * @param {object} oSettings dataTables settings object
  2307. * @returns {node} Display length feature node
  2308. * @memberof DataTable#oApi
  2309. */
  2310. function _fnFeatureHtmlLength ( oSettings )
  2311. {
  2312. if ( oSettings.oScroll.bInfinite )
  2313. {
  2314. return null;
  2315. }
  2316. /* This can be overruled by not using the _MENU_ var/macro in the language variable */
  2317. var sName = 'name="'+oSettings.sTableId+'_length"';
  2318. var sStdMenu = '<select size="1" '+sName+'>';
  2319. var i, iLen;
  2320. var aLengthMenu = oSettings.aLengthMenu;
  2321. if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' &&
  2322. typeof aLengthMenu[1] === 'object' )
  2323. {
  2324. for ( i=0, iLen=aLengthMenu[0].length ; i<iLen ; i++ )
  2325. {
  2326. sStdMenu += '<option value="'+aLengthMenu[0][i]+'">'+aLengthMenu[1][i]+'</option>';
  2327. }
  2328. }
  2329. else
  2330. {
  2331. for ( i=0, iLen=aLengthMenu.length ; i<iLen ; i++ )
  2332. {
  2333. sStdMenu += '<option value="'+aLengthMenu[i]+'">'+aLengthMenu[i]+'</option>';
  2334. }
  2335. }
  2336. sStdMenu += '</select>';
  2337. var nLength = document.createElement( 'div' );
  2338. if ( !oSettings.aanFeatures.l )
  2339. {
  2340. nLength.id = oSettings.sTableId+'_length';
  2341. }
  2342. nLength.className = oSettings.oClasses.sLength;
  2343. nLength.innerHTML = '<label>'+oSettings.oLanguage.sLengthMenu.replace( '_MENU_', sStdMenu )+'</label>';
  2344. /*
  2345. * Set the length to the current display length - thanks to Andrea Pavlovic for this fix,
  2346. * and Stefan Skopnik for fixing the fix!
  2347. */
  2348. $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true);
  2349. $('select', nLength).bind( 'change.DT', function(e) {
  2350. var iVal = $(this).val();
  2351. /* Update all other length options for the new display */
  2352. var n = oSettings.aanFeatures.l;
  2353. for ( i=0, iLen=n.length ; i<iLen ; i++ )
  2354. {
  2355. if ( n[i] != this.parentNode )
  2356. {
  2357. $('select', n[i]).val( iVal );
  2358. }
  2359. }
  2360. /* Redraw the table */
  2361. oSettings._iDisplayLength = parseInt(iVal, 10);
  2362. _fnCalculateEnd( oSettings );
  2363. /* If we have space to show extra rows (backing up from the end point - then do so */
  2364. if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() )
  2365. {
  2366. oSettings._iDisplayStart = oSettings.fnDisplayEnd() - oSettings._iDisplayLength;
  2367. if ( oSettings._iDisplayStart < 0 )
  2368. {
  2369. oSettings._iDisplayStart = 0;
  2370. }
  2371. }
  2372. if ( oSettings._iDisplayLength == -1 )
  2373. {
  2374. oSettings._iDisplayStart = 0;
  2375. }
  2376. _fnDraw( oSettings );
  2377. } );
  2378. $('select', nLength).attr('aria-controls', oSettings.sTableId);
  2379. return nLength;
  2380. }
  2381. /**
  2382. * Rcalculate the end point based on the start point
  2383. * @param {object} oSettings dataTables settings object
  2384. * @memberof DataTable#oApi
  2385. */
  2386. function _fnCalculateEnd( oSettings )
  2387. {
  2388. if ( oSettings.oFeatures.bPaginate === false )
  2389. {
  2390. oSettings._iDisplayEnd = oSettings.aiDisplay.length;
  2391. }
  2392. else
  2393. {
  2394. /* Set the end point of the display - based on how many elements there are
  2395. * still to display
  2396. */
  2397. if ( oSettings._iDisplayStart + oSettings._iDisplayLength > oSettings.aiDisplay.length ||
  2398. oSettings._iDisplayLength == -1 )
  2399. {
  2400. oSettings._iDisplayEnd = oSettings.aiDisplay.length;
  2401. }
  2402. else
  2403. {
  2404. oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength;
  2405. }
  2406. }
  2407. }
  2408. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2409. * Note that most of the paging logic is done in
  2410. * DataTable.ext.oPagination
  2411. */
  2412. /**
  2413. * Generate the node required for default pagination
  2414. * @param {object} oSettings dataTables settings object
  2415. * @returns {node} Pagination feature node
  2416. * @memberof DataTable#oApi
  2417. */
  2418. function _fnFeatureHtmlPaginate ( oSettings )
  2419. {
  2420. if ( oSettings.oScroll.bInfinite )
  2421. {
  2422. return null;
  2423. }
  2424. var nPaginate = document.createElement( 'div' );
  2425. nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType;
  2426. DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate,
  2427. function( oSettings ) {
  2428. _fnCalculateEnd( oSettings );
  2429. _fnDraw( oSettings );
  2430. }
  2431. );
  2432. /* Add a draw callback for the pagination on first instance, to update the paging display */
  2433. if ( !oSettings.aanFeatures.p )
  2434. {
  2435. oSettings.aoDrawCallback.push( {
  2436. "fn": function( oSettings ) {
  2437. DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) {
  2438. _fnCalculateEnd( oSettings );
  2439. _fnDraw( oSettings );
  2440. } );
  2441. },
  2442. "sName": "pagination"
  2443. } );
  2444. }
  2445. return nPaginate;
  2446. }
  2447. /**
  2448. * Alter the display settings to change the page
  2449. * @param {object} oSettings dataTables settings object
  2450. * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
  2451. * or page number to jump to (integer)
  2452. * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1
  2453. * @memberof DataTable#oApi
  2454. */
  2455. function _fnPageChange ( oSettings, mAction )
  2456. {
  2457. var iOldStart = oSettings._iDisplayStart;
  2458. if ( typeof mAction === "number" )
  2459. {
  2460. oSettings._iDisplayStart = mAction * oSettings._iDisplayLength;
  2461. if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() )
  2462. {
  2463. oSettings._iDisplayStart = 0;
  2464. }
  2465. }
  2466. else if ( mAction == "first" )
  2467. {
  2468. oSettings._iDisplayStart = 0;
  2469. }
  2470. else if ( mAction == "previous" )
  2471. {
  2472. oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ?
  2473. oSettings._iDisplayStart - oSettings._iDisplayLength :
  2474. 0;
  2475. /* Correct for underrun */
  2476. if ( oSettings._iDisplayStart < 0 )
  2477. {
  2478. oSettings._iDisplayStart = 0;
  2479. }
  2480. }
  2481. else if ( mAction == "next" )
  2482. {
  2483. if ( oSettings._iDisplayLength >= 0 )
  2484. {
  2485. /* Make sure we are not over running the display array */
  2486. if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() )
  2487. {
  2488. oSettings._iDisplayStart += oSettings._iDisplayLength;
  2489. }
  2490. }
  2491. else
  2492. {
  2493. oSettings._iDisplayStart = 0;
  2494. }
  2495. }
  2496. else if ( mAction == "last" )
  2497. {
  2498. if ( oSettings._iDisplayLength >= 0 )
  2499. {
  2500. var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1;
  2501. oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength;
  2502. }
  2503. else
  2504. {
  2505. oSettings._iDisplayStart = 0;
  2506. }
  2507. }
  2508. else
  2509. {
  2510. _fnLog( oSettings, 0, "Unknown paging action: "+mAction );
  2511. }
  2512. $(oSettings.oInstance).trigger('page', oSettings);
  2513. return iOldStart != oSettings._iDisplayStart;
  2514. }
  2515. /**
  2516. * Generate the node required for the processing node
  2517. * @param {object} oSettings dataTables settings object
  2518. * @returns {node} Processing element
  2519. * @memberof DataTable#oApi
  2520. */
  2521. function _fnFeatureHtmlProcessing ( oSettings )
  2522. {
  2523. var nProcessing = document.createElement( 'div' );
  2524. if ( !oSettings.aanFeatures.r )
  2525. {
  2526. nProcessing.id = oSettings.sTableId+'_processing';
  2527. }
  2528. nProcessing.innerHTML = oSettings.oLanguage.sProcessing;
  2529. nProcessing.className = oSettings.oClasses.sProcessing;
  2530. oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable );
  2531. return nProcessing;
  2532. }
  2533. /**
  2534. * Display or hide the processing indicator
  2535. * @param {object} oSettings dataTables settings object
  2536. * @param {bool} bShow Show the processing indicator (true) or not (false)
  2537. * @memberof DataTable#oApi
  2538. */
  2539. function _fnProcessingDisplay ( oSettings, bShow )
  2540. {
  2541. if ( oSettings.oFeatures.bProcessing )
  2542. {
  2543. var an = oSettings.aanFeatures.r;
  2544. for ( var i=0, iLen=an.length ; i<iLen ; i++ )
  2545. {
  2546. an[i].style.visibility = bShow ? "visible" : "hidden";
  2547. }
  2548. }
  2549. $(oSettings.oInstance).trigger('processing', [oSettings, bShow]);
  2550. }
  2551. /**
  2552. * Add any control elements for the table - specifically scrolling
  2553. * @param {object} oSettings dataTables settings object
  2554. * @returns {node} Node to add to the DOM
  2555. * @memberof DataTable#oApi
  2556. */
  2557. function _fnFeatureHtmlTable ( oSettings )
  2558. {
  2559. /* Check if scrolling is enabled or not - if not then leave the DOM unaltered */
  2560. if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY === "" )
  2561. {
  2562. return oSettings.nTable;
  2563. }
  2564. /*
  2565. * The HTML structure that we want to generate in this function is:
  2566. * div - nScroller
  2567. * div - nScrollHead
  2568. * div - nScrollHeadInner
  2569. * table - nScrollHeadTable
  2570. * thead - nThead
  2571. * div - nScrollBody
  2572. * table - oSettings.nTable
  2573. * thead - nTheadSize
  2574. * tbody - nTbody
  2575. * div - nScrollFoot
  2576. * div - nScrollFootInner
  2577. * table - nScrollFootTable
  2578. * tfoot - nTfoot
  2579. */
  2580. var
  2581. nScroller = document.createElement('div'),
  2582. nScrollHead = document.createElement('div'),
  2583. nScrollHeadInner = document.createElement('div'),
  2584. nScrollBody = document.createElement('div'),
  2585. nScrollFoot = document.createElement('div'),
  2586. nScrollFootInner = document.createElement('div'),
  2587. nScrollHeadTable = oSettings.nTable.cloneNode(false),
  2588. nScrollFootTable = oSettings.nTable.cloneNode(false),
  2589. nThead = oSettings.nTable.getElementsByTagName('thead')[0],
  2590. nTfoot = oSettings.nTable.getElementsByTagName('tfoot').length === 0 ? null :
  2591. oSettings.nTable.getElementsByTagName('tfoot')[0],
  2592. oClasses = oSettings.oClasses;
  2593. nScrollHead.appendChild( nScrollHeadInner );
  2594. nScrollFoot.appendChild( nScrollFootInner );
  2595. nScrollBody.appendChild( oSettings.nTable );
  2596. nScroller.appendChild( nScrollHead );
  2597. nScroller.appendChild( nScrollBody );
  2598. nScrollHeadInner.appendChild( nScrollHeadTable );
  2599. nScrollHeadTable.appendChild( nThead );
  2600. if ( nTfoot !== null )
  2601. {
  2602. nScroller.appendChild( nScrollFoot );
  2603. nScrollFootInner.appendChild( nScrollFootTable );
  2604. nScrollFootTable.appendChild( nTfoot );
  2605. }
  2606. nScroller.className = oClasses.sScrollWrapper;
  2607. nScrollHead.className = oClasses.sScrollHead;
  2608. nScrollHeadInner.className = oClasses.sScrollHeadInner;
  2609. nScrollBody.className = oClasses.sScrollBody;
  2610. nScrollFoot.className = oClasses.sScrollFoot;
  2611. nScrollFootInner.className = oClasses.sScrollFootInner;
  2612. if ( oSettings.oScroll.bAutoCss )
  2613. {
  2614. nScrollHead.style.overflow = "hidden";
  2615. nScrollHead.style.position = "relative";
  2616. nScrollFoot.style.overflow = "hidden";
  2617. nScrollBody.style.overflow = "auto";
  2618. }
  2619. nScrollHead.style.border = "0";
  2620. nScrollHead.style.width = "100%";
  2621. nScrollFoot.style.border = "0";
  2622. nScrollHeadInner.style.width = oSettings.oScroll.sXInner !== "" ?
  2623. oSettings.oScroll.sXInner : "100%"; /* will be overwritten */
  2624. /* Modify attributes to respect the clones */
  2625. nScrollHeadTable.removeAttribute('id');
  2626. nScrollHeadTable.style.marginLeft = "0";
  2627. oSettings.nTable.style.marginLeft = "0";
  2628. if ( nTfoot !== null )
  2629. {
  2630. nScrollFootTable.removeAttribute('id');
  2631. nScrollFootTable.style.marginLeft = "0";
  2632. }
  2633. /* Move caption elements from the body to the header, footer or leave where it is
  2634. * depending on the configuration. Note that the DTD says there can be only one caption */
  2635. var nCaption = $(oSettings.nTable).children('caption');
  2636. if ( nCaption.length > 0 )
  2637. {
  2638. nCaption = nCaption[0];
  2639. if ( nCaption._captionSide === "top" )
  2640. {
  2641. nScrollHeadTable.appendChild( nCaption );
  2642. }
  2643. else if ( nCaption._captionSide === "bottom" && nTfoot )
  2644. {
  2645. nScrollFootTable.appendChild( nCaption );
  2646. }
  2647. }
  2648. /*
  2649. * Sizing
  2650. */
  2651. /* When xscrolling add the width and a scroller to move the header with the body */
  2652. if ( oSettings.oScroll.sX !== "" )
  2653. {
  2654. nScrollHead.style.width = _fnStringToCss( oSettings.oScroll.sX );
  2655. nScrollBody.style.width = _fnStringToCss( oSettings.oScroll.sX );
  2656. if ( nTfoot !== null )
  2657. {
  2658. nScrollFoot.style.width = _fnStringToCss( oSettings.oScroll.sX );
  2659. }
  2660. /* When the body is scrolled, then we also want to scroll the headers */
  2661. $(nScrollBody).scroll( function (e) {
  2662. nScrollHead.scrollLeft = this.scrollLeft;
  2663. if ( nTfoot !== null )
  2664. {
  2665. nScrollFoot.scrollLeft = this.scrollLeft;
  2666. }
  2667. } );
  2668. }
  2669. /* When yscrolling, add the height */
  2670. if ( oSettings.oScroll.sY !== "" )
  2671. {
  2672. nScrollBody.style.height = _fnStringToCss( oSettings.oScroll.sY );
  2673. }
  2674. /* Redraw - align columns across the tables */
  2675. oSettings.aoDrawCallback.push( {
  2676. "fn": _fnScrollDraw,
  2677. "sName": "scrolling"
  2678. } );
  2679. /* Infinite scrolling event handlers */
  2680. if ( oSettings.oScroll.bInfinite )
  2681. {
  2682. $(nScrollBody).scroll( function() {
  2683. /* Use a blocker to stop scrolling from loading more data while other data is still loading */
  2684. if ( !oSettings.bDrawing && $(this).scrollTop() !== 0 )
  2685. {
  2686. /* Check if we should load the next data set */
  2687. if ( $(this).scrollTop() + $(this).height() >
  2688. $(oSettings.nTable).height() - oSettings.oScroll.iLoadGap )
  2689. {
  2690. /* Only do the redraw if we have to - we might be at the end of the data */
  2691. if ( oSettings.fnDisplayEnd() < oSettings.fnRecordsDisplay() )
  2692. {
  2693. _fnPageChange( oSettings, 'next' );
  2694. _fnCalculateEnd( oSettings );
  2695. _fnDraw( oSettings );
  2696. }
  2697. }
  2698. }
  2699. } );
  2700. }
  2701. oSettings.nScrollHead = nScrollHead;
  2702. oSettings.nScrollFoot = nScrollFoot;
  2703. return nScroller;
  2704. }
  2705. /**
  2706. * Update the various tables for resizing. It's a bit of a pig this function, but
  2707. * basically the idea to:
  2708. * 1. Re-create the table inside the scrolling div
  2709. * 2. Take live measurements from the DOM
  2710. * 3. Apply the measurements
  2711. * 4. Clean up
  2712. * @param {object} o dataTables settings object
  2713. * @returns {node} Node to add to the DOM
  2714. * @memberof DataTable#oApi
  2715. */
  2716. function _fnScrollDraw ( o )
  2717. {
  2718. var
  2719. nScrollHeadInner = o.nScrollHead.getElementsByTagName('div')[0],
  2720. nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0],
  2721. nScrollBody = o.nTable.parentNode,
  2722. i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis,
  2723. nTheadSize, nTfootSize,
  2724. iWidth, aApplied=[], iSanityWidth,
  2725. nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null,
  2726. nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null,
  2727. ie67 = $.browser.msie && $.browser.version <= 7;
  2728. /*
  2729. * 1. Re-create the table inside the scrolling div
  2730. */
  2731. /* Remove the old minimised thead and tfoot elements in the inner table */
  2732. $(o.nTable).children('thead, tfoot').remove();
  2733. /* Clone the current header and footer elements and then place it into the inner table */
  2734. nTheadSize = $(o.nTHead).clone()[0];
  2735. o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] );
  2736. if ( o.nTFoot !== null )
  2737. {
  2738. nTfootSize = $(o.nTFoot).clone()[0];
  2739. o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] );
  2740. }
  2741. /*
  2742. * 2. Take live measurements from the DOM - do not alter the DOM itself!
  2743. */
  2744. /* Remove old sizing and apply the calculated column widths
  2745. * Get the unique column headers in the newly created (cloned) header. We want to apply the
  2746. * calclated sizes to this header
  2747. */
  2748. if ( o.oScroll.sX === "" )
  2749. {
  2750. nScrollBody.style.width = '100%';
  2751. nScrollHeadInner.parentNode.style.width = '100%';
  2752. }
  2753. var nThs = _fnGetUniqueThs( o, nTheadSize );
  2754. for ( i=0, iLen=nThs.length ; i<iLen ; i++ )
  2755. {
  2756. iVis = _fnVisibleToColumnIndex( o, i );
  2757. nThs[i].style.width = o.aoColumns[iVis].sWidth;
  2758. }
  2759. if ( o.nTFoot !== null )
  2760. {
  2761. _fnApplyToChildren( function(n) {
  2762. n.style.width = "";
  2763. }, nTfootSize.getElementsByTagName('tr') );
  2764. }
  2765. // If scroll collapse is enabled, when we put the headers back into the body for sizing, we
  2766. // will end up forcing the scrollbar to appear, making our measurements wrong for when we
  2767. // then hide it (end of this function), so add the header height to the body scroller.
  2768. if ( o.oScroll.bCollapse && o.oScroll.sY !== "" )
  2769. {
  2770. nScrollBody.style.height = (nScrollBody.offsetHeight + o.nTHead.offsetHeight)+"px";
  2771. }
  2772. /* Size the table as a whole */
  2773. iSanityWidth = $(o.nTable).outerWidth();
  2774. if ( o.oScroll.sX === "" )
  2775. {
  2776. /* No x scrolling */
  2777. o.nTable.style.width = "100%";
  2778. /* I know this is rubbish - but IE7 will make the width of the table when 100% include
  2779. * the scrollbar - which is shouldn't. When there is a scrollbar we need to take this
  2780. * into account.
  2781. */
  2782. if ( ie67 && ($('tbody', nScrollBody).height() > nScrollBody.offsetHeight ||
  2783. $(nScrollBody).css('overflow-y') == "scroll") )
  2784. {
  2785. o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth() - o.oScroll.iBarWidth);
  2786. }
  2787. }
  2788. else
  2789. {
  2790. if ( o.oScroll.sXInner !== "" )
  2791. {
  2792. /* x scroll inner has been given - use it */
  2793. o.nTable.style.width = _fnStringToCss(o.oScroll.sXInner);
  2794. }
  2795. else if ( iSanityWidth == $(nScrollBody).width() &&
  2796. $(nScrollBody).height() < $(o.nTable).height() )
  2797. {
  2798. /* There is y-scrolling - try to take account of the y scroll bar */
  2799. o.nTable.style.width = _fnStringToCss( iSanityWidth-o.oScroll.iBarWidth );
  2800. if ( $(o.nTable).outerWidth() > iSanityWidth-o.oScroll.iBarWidth )
  2801. {
  2802. /* Not possible to take account of it */
  2803. o.nTable.style.width = _fnStringToCss( iSanityWidth );
  2804. }
  2805. }
  2806. else
  2807. {
  2808. /* All else fails */
  2809. o.nTable.style.width = _fnStringToCss( iSanityWidth );
  2810. }
  2811. }
  2812. /* Recalculate the sanity width - now that we've applied the required width, before it was
  2813. * a temporary variable. This is required because the column width calculation is done
  2814. * before this table DOM is created.
  2815. */
  2816. iSanityWidth = $(o.nTable).outerWidth();
  2817. /* We want the hidden header to have zero height, so remove padding and borders. Then
  2818. * set the width based on the real headers
  2819. */
  2820. anHeadToSize = o.nTHead.getElementsByTagName('tr');
  2821. anHeadSizers = nTheadSize.getElementsByTagName('tr');
  2822. _fnApplyToChildren( function(nSizer, nToSize) {
  2823. oStyle = nSizer.style;
  2824. oStyle.paddingTop = "0";
  2825. oStyle.paddingBottom = "0";
  2826. oStyle.borderTopWidth = "0";
  2827. oStyle.borderBottomWidth = "0";
  2828. oStyle.height = 0;
  2829. iWidth = $(nSizer).width();
  2830. nToSize.style.width = _fnStringToCss( iWidth );
  2831. aApplied.push( iWidth );
  2832. }, anHeadSizers, anHeadToSize );
  2833. $(anHeadSizers).height(0);
  2834. if ( o.nTFoot !== null )
  2835. {
  2836. /* Clone the current footer and then place it into the body table as a "hidden header" */
  2837. anFootSizers = nTfootSize.getElementsByTagName('tr');
  2838. anFootToSize = o.nTFoot.getElementsByTagName('tr');
  2839. _fnApplyToChildren( function(nSizer, nToSize) {
  2840. oStyle = nSizer.style;
  2841. oStyle.paddingTop = "0";
  2842. oStyle.paddingBottom = "0";
  2843. oStyle.borderTopWidth = "0";
  2844. oStyle.borderBottomWidth = "0";
  2845. oStyle.height = 0;
  2846. iWidth = $(nSizer).width();
  2847. nToSize.style.width = _fnStringToCss( iWidth );
  2848. aApplied.push( iWidth );
  2849. }, anFootSizers, anFootToSize );
  2850. $(anFootSizers).height(0);
  2851. }
  2852. /*
  2853. * 3. Apply the measurements
  2854. */
  2855. /* "Hide" the header and footer that we used for the sizing. We want to also fix their width
  2856. * to what they currently are
  2857. */
  2858. _fnApplyToChildren( function(nSizer) {
  2859. nSizer.innerHTML = "";
  2860. nSizer.style.width = _fnStringToCss( aApplied.shift() );
  2861. }, anHeadSizers );
  2862. if ( o.nTFoot !== null )
  2863. {
  2864. _fnApplyToChildren( function(nSizer) {
  2865. nSizer.innerHTML = "";
  2866. nSizer.style.width = _fnStringToCss( aApplied.shift() );
  2867. }, anFootSizers );
  2868. }
  2869. /* Sanity check that the table is of a sensible width. If not then we are going to get
  2870. * misalignment - try to prevent this by not allowing the table to shrink below its min width
  2871. */
  2872. if ( $(o.nTable).outerWidth() < iSanityWidth )
  2873. {
  2874. /* The min width depends upon if we have a vertical scrollbar visible or not */
  2875. var iCorrection = ((nScrollBody.scrollHeight > nScrollBody.offsetHeight ||
  2876. $(nScrollBody).css('overflow-y') == "scroll")) ?
  2877. iSanityWidth+o.oScroll.iBarWidth : iSanityWidth;
  2878. /* IE6/7 are a law unto themselves... */
  2879. if ( ie67 && (nScrollBody.scrollHeight >
  2880. nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") )
  2881. {
  2882. o.nTable.style.width = _fnStringToCss( iCorrection-o.oScroll.iBarWidth );
  2883. }
  2884. /* Apply the calculated minimum width to the table wrappers */
  2885. nScrollBody.style.width = _fnStringToCss( iCorrection );
  2886. nScrollHeadInner.parentNode.style.width = _fnStringToCss( iCorrection );
  2887. if ( o.nTFoot !== null )
  2888. {
  2889. nScrollFootInner.parentNode.style.width = _fnStringToCss( iCorrection );
  2890. }
  2891. /* And give the user a warning that we've stopped the table getting too small */
  2892. if ( o.oScroll.sX === "" )
  2893. {
  2894. _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+
  2895. " misalignment. The table has been drawn at its minimum possible width." );
  2896. }
  2897. else if ( o.oScroll.sXInner !== "" )
  2898. {
  2899. _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+
  2900. " misalignment. Increase the sScrollXInner value or remove it to allow automatic"+
  2901. " calculation" );
  2902. }
  2903. }
  2904. else
  2905. {
  2906. nScrollBody.style.width = _fnStringToCss( '100%' );
  2907. nScrollHeadInner.parentNode.style.width = _fnStringToCss( '100%' );
  2908. if ( o.nTFoot !== null )
  2909. {
  2910. nScrollFootInner.parentNode.style.width = _fnStringToCss( '100%' );
  2911. }
  2912. }
  2913. /*
  2914. * 4. Clean up
  2915. */
  2916. if ( o.oScroll.sY === "" )
  2917. {
  2918. /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
  2919. * the scrollbar height from the visible display, rather than adding it on. We need to
  2920. * set the height in order to sort this. Don't want to do it in any other browsers.
  2921. */
  2922. if ( ie67 )
  2923. {
  2924. nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+o.oScroll.iBarWidth );
  2925. }
  2926. }
  2927. if ( o.oScroll.sY !== "" && o.oScroll.bCollapse )
  2928. {
  2929. nScrollBody.style.height = _fnStringToCss( o.oScroll.sY );
  2930. var iExtra = (o.oScroll.sX !== "" && o.nTable.offsetWidth > nScrollBody.offsetWidth) ?
  2931. o.oScroll.iBarWidth : 0;
  2932. if ( o.nTable.offsetHeight < nScrollBody.offsetHeight )
  2933. {
  2934. nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+iExtra );
  2935. }
  2936. }
  2937. /* Finally set the width's of the header and footer tables */
  2938. var iOuterWidth = $(o.nTable).outerWidth();
  2939. nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth );
  2940. nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth );
  2941. // Figure out if there are scrollbar present - if so then we need a the header and footer to
  2942. // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
  2943. var bScrolling = $(o.nTable).height() > nScrollBody.clientHeight || $(nScrollBody).css('overflow-y') == "scroll";
  2944. nScrollHeadInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px";
  2945. if ( o.nTFoot !== null )
  2946. {
  2947. nScrollFootTable.style.width = _fnStringToCss( iOuterWidth );
  2948. nScrollFootInner.style.width = _fnStringToCss( iOuterWidth );
  2949. nScrollFootInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px";
  2950. }
  2951. /* Adjust the position of the header incase we loose the y-scrollbar */
  2952. $(nScrollBody).scroll();
  2953. /* If sorting or filtering has occurred, jump the scrolling back to the top */
  2954. if ( o.bSorted || o.bFiltered )
  2955. {
  2956. nScrollBody.scrollTop = 0;
  2957. }
  2958. }
  2959. /**
  2960. * Apply a given function to the display child nodes of an element array (typically
  2961. * TD children of TR rows
  2962. * @param {function} fn Method to apply to the objects
  2963. * @param array {nodes} an1 List of elements to look through for display children
  2964. * @param array {nodes} an2 Another list (identical structure to the first) - optional
  2965. * @memberof DataTable#oApi
  2966. */
  2967. function _fnApplyToChildren( fn, an1, an2 )
  2968. {
  2969. for ( var i=0, iLen=an1.length ; i<iLen ; i++ )
  2970. {
  2971. for ( var j=0, jLen=an1[i].childNodes.length ; j<jLen ; j++ )
  2972. {
  2973. if ( an1[i].childNodes[j].nodeType == 1 )
  2974. {
  2975. if ( an2 )
  2976. {
  2977. fn( an1[i].childNodes[j], an2[i].childNodes[j] );
  2978. }
  2979. else
  2980. {
  2981. fn( an1[i].childNodes[j] );
  2982. }
  2983. }
  2984. }
  2985. }
  2986. }
  2987. /**
  2988. * Convert a CSS unit width to pixels (e.g. 2em)
  2989. * @param {string} sWidth width to be converted
  2990. * @param {node} nParent parent to get the with for (required for relative widths) - optional
  2991. * @returns {int} iWidth width in pixels
  2992. * @memberof DataTable#oApi
  2993. */
  2994. function _fnConvertToWidth ( sWidth, nParent )
  2995. {
  2996. if ( !sWidth || sWidth === null || sWidth === '' )
  2997. {
  2998. return 0;
  2999. }
  3000. if ( !nParent )
  3001. {
  3002. nParent = document.getElementsByTagName('body')[0];
  3003. }
  3004. var iWidth;
  3005. var nTmp = document.createElement( "div" );
  3006. nTmp.style.width = _fnStringToCss( sWidth );
  3007. nParent.appendChild( nTmp );
  3008. iWidth = nTmp.offsetWidth;
  3009. nParent.removeChild( nTmp );
  3010. return ( iWidth );
  3011. }
  3012. /**
  3013. * Calculate the width of columns for the table
  3014. * @param {object} oSettings dataTables settings object
  3015. * @memberof DataTable#oApi
  3016. */
  3017. function _fnCalculateColumnWidths ( oSettings )
  3018. {
  3019. var iTableWidth = oSettings.nTable.offsetWidth;
  3020. var iUserInputs = 0;
  3021. var iTmpWidth;
  3022. var iVisibleColumns = 0;
  3023. var iColums = oSettings.aoColumns.length;
  3024. var i, iIndex, iCorrector, iWidth;
  3025. var oHeaders = $('th', oSettings.nTHead);
  3026. var widthAttr = oSettings.nTable.getAttribute('width');
  3027. /* Convert any user input sizes into pixel sizes */
  3028. for ( i=0 ; i<iColums ; i++ )
  3029. {
  3030. if ( oSettings.aoColumns[i].bVisible )
  3031. {
  3032. iVisibleColumns++;
  3033. if ( oSettings.aoColumns[i].sWidth !== null )
  3034. {
  3035. iTmpWidth = _fnConvertToWidth( oSettings.aoColumns[i].sWidthOrig,
  3036. oSettings.nTable.parentNode );
  3037. if ( iTmpWidth !== null )
  3038. {
  3039. oSettings.aoColumns[i].sWidth = _fnStringToCss( iTmpWidth );
  3040. }
  3041. iUserInputs++;
  3042. }
  3043. }
  3044. }
  3045. /* If the number of columns in the DOM equals the number that we have to process in
  3046. * DataTables, then we can use the offsets that are created by the web-browser. No custom
  3047. * sizes can be set in order for this to happen, nor scrolling used
  3048. */
  3049. if ( iColums == oHeaders.length && iUserInputs === 0 && iVisibleColumns == iColums &&
  3050. oSettings.oScroll.sX === "" && oSettings.oScroll.sY === "" )
  3051. {
  3052. for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
  3053. {
  3054. iTmpWidth = $(oHeaders[i]).width();
  3055. if ( iTmpWidth !== null )
  3056. {
  3057. oSettings.aoColumns[i].sWidth = _fnStringToCss( iTmpWidth );
  3058. }
  3059. }
  3060. }
  3061. else
  3062. {
  3063. /* Otherwise we are going to have to do some calculations to get the width of each column.
  3064. * Construct a 1 row table with the widest node in the data, and any user defined widths,
  3065. * then insert it into the DOM and allow the browser to do all the hard work of
  3066. * calculating table widths.
  3067. */
  3068. var
  3069. nCalcTmp = oSettings.nTable.cloneNode( false ),
  3070. nTheadClone = oSettings.nTHead.cloneNode(true),
  3071. nBody = document.createElement( 'tbody' ),
  3072. nTr = document.createElement( 'tr' ),
  3073. nDivSizing;
  3074. nCalcTmp.removeAttribute( "id" );
  3075. nCalcTmp.appendChild( nTheadClone );
  3076. if ( oSettings.nTFoot !== null )
  3077. {
  3078. nCalcTmp.appendChild( oSettings.nTFoot.cloneNode(true) );
  3079. _fnApplyToChildren( function(n) {
  3080. n.style.width = "";
  3081. }, nCalcTmp.getElementsByTagName('tr') );
  3082. }
  3083. nCalcTmp.appendChild( nBody );
  3084. nBody.appendChild( nTr );
  3085. /* Remove any sizing that was previously applied by the styles */
  3086. var jqColSizing = $('thead th', nCalcTmp);
  3087. if ( jqColSizing.length === 0 )
  3088. {
  3089. jqColSizing = $('tbody tr:eq(0)>td', nCalcTmp);
  3090. }
  3091. /* Apply custom sizing to the cloned header */
  3092. var nThs = _fnGetUniqueThs( oSettings, nTheadClone );
  3093. iCorrector = 0;
  3094. for ( i=0 ; i<iColums ; i++ )
  3095. {
  3096. var oColumn = oSettings.aoColumns[i];
  3097. if ( oColumn.bVisible && oColumn.sWidthOrig !== null && oColumn.sWidthOrig !== "" )
  3098. {
  3099. nThs[i-iCorrector].style.width = _fnStringToCss( oColumn.sWidthOrig );
  3100. }
  3101. else if ( oColumn.bVisible )
  3102. {
  3103. nThs[i-iCorrector].style.width = "";
  3104. }
  3105. else
  3106. {
  3107. iCorrector++;
  3108. }
  3109. }
  3110. /* Find the biggest td for each column and put it into the table */
  3111. for ( i=0 ; i<iColums ; i++ )
  3112. {
  3113. if ( oSettings.aoColumns[i].bVisible )
  3114. {
  3115. var nTd = _fnGetWidestNode( oSettings, i );
  3116. if ( nTd !== null )
  3117. {
  3118. nTd = nTd.cloneNode(true);
  3119. if ( oSettings.aoColumns[i].sContentPadding !== "" )
  3120. {
  3121. nTd.innerHTML += oSettings.aoColumns[i].sContentPadding;
  3122. }
  3123. nTr.appendChild( nTd );
  3124. }
  3125. }
  3126. }
  3127. /* Build the table and 'display' it */
  3128. var nWrapper = oSettings.nTable.parentNode;
  3129. nWrapper.appendChild( nCalcTmp );
  3130. /* When scrolling (X or Y) we want to set the width of the table as appropriate. However,
  3131. * when not scrolling leave the table width as it is. This results in slightly different,
  3132. * but I think correct behaviour
  3133. */
  3134. if ( oSettings.oScroll.sX !== "" && oSettings.oScroll.sXInner !== "" )
  3135. {
  3136. nCalcTmp.style.width = _fnStringToCss(oSettings.oScroll.sXInner);
  3137. }
  3138. else if ( oSettings.oScroll.sX !== "" )
  3139. {
  3140. nCalcTmp.style.width = "";
  3141. if ( $(nCalcTmp).width() < nWrapper.offsetWidth )
  3142. {
  3143. nCalcTmp.style.width = _fnStringToCss( nWrapper.offsetWidth );
  3144. }
  3145. }
  3146. else if ( oSettings.oScroll.sY !== "" )
  3147. {
  3148. nCalcTmp.style.width = _fnStringToCss( nWrapper.offsetWidth );
  3149. }
  3150. else if ( widthAttr )
  3151. {
  3152. nCalcTmp.style.width = _fnStringToCss( widthAttr );
  3153. }
  3154. nCalcTmp.style.visibility = "hidden";
  3155. /* Scrolling considerations */
  3156. _fnScrollingWidthAdjust( oSettings, nCalcTmp );
  3157. /* Read the width's calculated by the browser and store them for use by the caller. We
  3158. * first of all try to use the elements in the body, but it is possible that there are
  3159. * no elements there, under which circumstances we use the header elements
  3160. */
  3161. var oNodes = $("tbody tr:eq(0)", nCalcTmp).children();
  3162. if ( oNodes.length === 0 )
  3163. {
  3164. oNodes = _fnGetUniqueThs( oSettings, $('thead', nCalcTmp)[0] );
  3165. }
  3166. /* Browsers need a bit of a hand when a width is assigned to any columns when
  3167. * x-scrolling as they tend to collapse the table to the min-width, even if
  3168. * we sent the column widths. So we need to keep track of what the table width
  3169. * should be by summing the user given values, and the automatic values
  3170. */
  3171. if ( oSettings.oScroll.sX !== "" )
  3172. {
  3173. var iTotal = 0;
  3174. iCorrector = 0;
  3175. for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
  3176. {
  3177. if ( oSettings.aoColumns[i].bVisible )
  3178. {
  3179. if ( oSettings.aoColumns[i].sWidthOrig === null )
  3180. {
  3181. iTotal += $(oNodes[iCorrector]).outerWidth();
  3182. }
  3183. else
  3184. {
  3185. iTotal += parseInt(oSettings.aoColumns[i].sWidth.replace('px',''), 10) +
  3186. ($(oNodes[iCorrector]).outerWidth() - $(oNodes[iCorrector]).width());
  3187. }
  3188. iCorrector++;
  3189. }
  3190. }
  3191. nCalcTmp.style.width = _fnStringToCss( iTotal );
  3192. oSettings.nTable.style.width = _fnStringToCss( iTotal );
  3193. }
  3194. iCorrector = 0;
  3195. for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
  3196. {
  3197. if ( oSettings.aoColumns[i].bVisible )
  3198. {
  3199. iWidth = $(oNodes[iCorrector]).width();
  3200. if ( iWidth !== null && iWidth > 0 )
  3201. {
  3202. oSettings.aoColumns[i].sWidth = _fnStringToCss( iWidth );
  3203. }
  3204. iCorrector++;
  3205. }
  3206. }
  3207. var cssWidth = $(nCalcTmp).css('width');
  3208. oSettings.nTable.style.width = (cssWidth.indexOf('%') !== -1) ?
  3209. cssWidth : _fnStringToCss( $(nCalcTmp).outerWidth() );
  3210. nCalcTmp.parentNode.removeChild( nCalcTmp );
  3211. }
  3212. if ( widthAttr )
  3213. {
  3214. oSettings.nTable.style.width = _fnStringToCss( widthAttr );
  3215. }
  3216. }
  3217. /**
  3218. * Adjust a table's width to take account of scrolling
  3219. * @param {object} oSettings dataTables settings object
  3220. * @param {node} n table node
  3221. * @memberof DataTable#oApi
  3222. */
  3223. function _fnScrollingWidthAdjust ( oSettings, n )
  3224. {
  3225. if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY !== "" )
  3226. {
  3227. /* When y-scrolling only, we want to remove the width of the scroll bar so the table
  3228. * + scroll bar will fit into the area avaialble.
  3229. */
  3230. var iOrigWidth = $(n).width();
  3231. n.style.width = _fnStringToCss( $(n).outerWidth()-oSettings.oScroll.iBarWidth );
  3232. }
  3233. else if ( oSettings.oScroll.sX !== "" )
  3234. {
  3235. /* When x-scrolling both ways, fix the table at it's current size, without adjusting */
  3236. n.style.width = _fnStringToCss( $(n).outerWidth() );
  3237. }
  3238. }
  3239. /**
  3240. * Get the widest node
  3241. * @param {object} oSettings dataTables settings object
  3242. * @param {int} iCol column of interest
  3243. * @returns {string} max strlens for each column
  3244. * @memberof DataTable#oApi
  3245. */
  3246. function _fnGetWidestNode( oSettings, iCol )
  3247. {
  3248. var iMaxIndex = _fnGetMaxLenString( oSettings, iCol );
  3249. if ( iMaxIndex < 0 )
  3250. {
  3251. return null;
  3252. }
  3253. if ( oSettings.aoData[iMaxIndex].nTr === null )
  3254. {
  3255. var n = document.createElement('td');
  3256. n.innerHTML = _fnGetCellData( oSettings, iMaxIndex, iCol, '' );
  3257. return n;
  3258. }
  3259. return _fnGetTdNodes(oSettings, iMaxIndex)[iCol];
  3260. }
  3261. /**
  3262. * Get the maximum strlen for each data column
  3263. * @param {object} oSettings dataTables settings object
  3264. * @param {int} iCol column of interest
  3265. * @returns {string} max strlens for each column
  3266. * @memberof DataTable#oApi
  3267. */
  3268. function _fnGetMaxLenString( oSettings, iCol )
  3269. {
  3270. var iMax = -1;
  3271. var iMaxIndex = -1;
  3272. for ( var i=0 ; i<oSettings.aoData.length ; i++ )
  3273. {
  3274. var s = _fnGetCellData( oSettings, i, iCol, 'display' )+"";
  3275. s = s.replace( /<.*?>/g, "" );
  3276. if ( s.length > iMax )
  3277. {
  3278. iMax = s.length;
  3279. iMaxIndex = i;
  3280. }
  3281. }
  3282. return iMaxIndex;
  3283. }
  3284. /**
  3285. * Append a CSS unit (only if required) to a string
  3286. * @param {array} aArray1 first array
  3287. * @param {array} aArray2 second array
  3288. * @returns {int} 0 if match, 1 if length is different, 2 if no match
  3289. * @memberof DataTable#oApi
  3290. */
  3291. function _fnStringToCss( s )
  3292. {
  3293. if ( s === null )
  3294. {
  3295. return "0px";
  3296. }
  3297. if ( typeof s == 'number' )
  3298. {
  3299. if ( s < 0 )
  3300. {
  3301. return "0px";
  3302. }
  3303. return s+"px";
  3304. }
  3305. /* Check if the last character is not 0-9 */
  3306. var c = s.charCodeAt( s.length-1 );
  3307. if (c < 0x30 || c > 0x39)
  3308. {
  3309. return s;
  3310. }
  3311. return s+"px";
  3312. }
  3313. /**
  3314. * Get the width of a scroll bar in this browser being used
  3315. * @returns {int} width in pixels
  3316. * @memberof DataTable#oApi
  3317. */
  3318. function _fnScrollBarWidth ()
  3319. {
  3320. var inner = document.createElement('p');
  3321. var style = inner.style;
  3322. style.width = "100%";
  3323. style.height = "200px";
  3324. style.padding = "0px";
  3325. var outer = document.createElement('div');
  3326. style = outer.style;
  3327. style.position = "absolute";
  3328. style.top = "0px";
  3329. style.left = "0px";
  3330. style.visibility = "hidden";
  3331. style.width = "200px";
  3332. style.height = "150px";
  3333. style.padding = "0px";
  3334. style.overflow = "hidden";
  3335. outer.appendChild(inner);
  3336. document.body.appendChild(outer);
  3337. var w1 = inner.offsetWidth;
  3338. outer.style.overflow = 'scroll';
  3339. var w2 = inner.offsetWidth;
  3340. if ( w1 == w2 )
  3341. {
  3342. w2 = outer.clientWidth;
  3343. }
  3344. document.body.removeChild(outer);
  3345. return (w1 - w2);
  3346. }
  3347. /**
  3348. * Change the order of the table
  3349. * @param {object} oSettings dataTables settings object
  3350. * @param {bool} bApplyClasses optional - should we apply classes or not
  3351. * @memberof DataTable#oApi
  3352. */
  3353. function _fnSort ( oSettings, bApplyClasses )
  3354. {
  3355. var
  3356. i, iLen, j, jLen, k, kLen,
  3357. sDataType, nTh,
  3358. aaSort = [],
  3359. aiOrig = [],
  3360. oSort = DataTable.ext.oSort,
  3361. aoData = oSettings.aoData,
  3362. aoColumns = oSettings.aoColumns,
  3363. oAria = oSettings.oLanguage.oAria;
  3364. /* No sorting required if server-side or no sorting array */
  3365. if ( !oSettings.oFeatures.bServerSide &&
  3366. (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) )
  3367. {
  3368. aaSort = ( oSettings.aaSortingFixed !== null ) ?
  3369. oSettings.aaSortingFixed.concat( oSettings.aaSorting ) :
  3370. oSettings.aaSorting.slice();
  3371. /* If there is a sorting data type, and a fuction belonging to it, then we need to
  3372. * get the data from the developer's function and apply it for this column
  3373. */
  3374. for ( i=0 ; i<aaSort.length ; i++ )
  3375. {
  3376. var iColumn = aaSort[i][0];
  3377. var iVisColumn = _fnColumnIndexToVisible( oSettings, iColumn );
  3378. sDataType = oSettings.aoColumns[ iColumn ].sSortDataType;
  3379. if ( DataTable.ext.afnSortData[sDataType] )
  3380. {
  3381. var aData = DataTable.ext.afnSortData[sDataType].call(
  3382. oSettings.oInstance, oSettings, iColumn, iVisColumn
  3383. );
  3384. if ( aData.length === aoData.length )
  3385. {
  3386. for ( j=0, jLen=aoData.length ; j<jLen ; j++ )
  3387. {
  3388. _fnSetCellData( oSettings, j, iColumn, aData[j] );
  3389. }
  3390. }
  3391. else
  3392. {
  3393. _fnLog( oSettings, 0, "Returned data sort array (col "+iColumn+") is the wrong length" );
  3394. }
  3395. }
  3396. }
  3397. /* Create a value - key array of the current row positions such that we can use their
  3398. * current position during the sort, if values match, in order to perform stable sorting
  3399. */
  3400. for ( i=0, iLen=oSettings.aiDisplayMaster.length ; i<iLen ; i++ )
  3401. {
  3402. aiOrig[ oSettings.aiDisplayMaster[i] ] = i;
  3403. }
  3404. /* Build an internal data array which is specific to the sort, so we can get and prep
  3405. * the data to be sorted only once, rather than needing to do it every time the sorting
  3406. * function runs. This make the sorting function a very simple comparison
  3407. */
  3408. var iSortLen = aaSort.length;
  3409. var fnSortFormat, aDataSort;
  3410. for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
  3411. {
  3412. for ( j=0 ; j<iSortLen ; j++ )
  3413. {
  3414. aDataSort = aoColumns[ aaSort[j][0] ].aDataSort;
  3415. for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
  3416. {
  3417. sDataType = aoColumns[ aDataSort[k] ].sType;
  3418. fnSortFormat = oSort[ (sDataType ? sDataType : 'string')+"-pre" ];
  3419. aoData[i]._aSortData[ aDataSort[k] ] = fnSortFormat ?
  3420. fnSortFormat( _fnGetCellData( oSettings, i, aDataSort[k], 'sort' ) ) :
  3421. _fnGetCellData( oSettings, i, aDataSort[k], 'sort' );
  3422. }
  3423. }
  3424. }
  3425. /* Do the sort - here we want multi-column sorting based on a given data source (column)
  3426. * and sorting function (from oSort) in a certain direction. It's reasonably complex to
  3427. * follow on it's own, but this is what we want (example two column sorting):
  3428. * fnLocalSorting = function(a,b){
  3429. * var iTest;
  3430. * iTest = oSort['string-asc']('data11', 'data12');
  3431. * if (iTest !== 0)
  3432. * return iTest;
  3433. * iTest = oSort['numeric-desc']('data21', 'data22');
  3434. * if (iTest !== 0)
  3435. * return iTest;
  3436. * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
  3437. * }
  3438. * Basically we have a test for each sorting column, if the data in that column is equal,
  3439. * test the next column. If all columns match, then we use a numeric sort on the row
  3440. * positions in the original data array to provide a stable sort.
  3441. */
  3442. oSettings.aiDisplayMaster.sort( function ( a, b ) {
  3443. var k, l, lLen, iTest, aDataSort, sDataType;
  3444. for ( k=0 ; k<iSortLen ; k++ )
  3445. {
  3446. aDataSort = aoColumns[ aaSort[k][0] ].aDataSort;
  3447. for ( l=0, lLen=aDataSort.length ; l<lLen ; l++ )
  3448. {
  3449. sDataType = aoColumns[ aDataSort[l] ].sType;
  3450. iTest = oSort[ (sDataType ? sDataType : 'string')+"-"+aaSort[k][1] ](
  3451. aoData[a]._aSortData[ aDataSort[l] ],
  3452. aoData[b]._aSortData[ aDataSort[l] ]
  3453. );
  3454. if ( iTest !== 0 )
  3455. {
  3456. return iTest;
  3457. }
  3458. }
  3459. }
  3460. return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
  3461. } );
  3462. }
  3463. /* Alter the sorting classes to take account of the changes */
  3464. if ( (bApplyClasses === undefined || bApplyClasses) && !oSettings.oFeatures.bDeferRender )
  3465. {
  3466. _fnSortingClasses( oSettings );
  3467. }
  3468. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  3469. {
  3470. var sTitle = aoColumns[i].sTitle.replace( /<.*?>/g, "" );
  3471. nTh = aoColumns[i].nTh;
  3472. nTh.removeAttribute('aria-sort');
  3473. nTh.removeAttribute('aria-label');
  3474. /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
  3475. if ( aoColumns[i].bSortable )
  3476. {
  3477. if ( aaSort.length > 0 && aaSort[0][0] == i )
  3478. {
  3479. nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" );
  3480. var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ?
  3481. aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0];
  3482. nTh.setAttribute('aria-label', sTitle+
  3483. (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
  3484. }
  3485. else
  3486. {
  3487. nTh.setAttribute('aria-label', sTitle+
  3488. (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
  3489. }
  3490. }
  3491. else
  3492. {
  3493. nTh.setAttribute('aria-label', sTitle);
  3494. }
  3495. }
  3496. /* Tell the draw function that we have sorted the data */
  3497. oSettings.bSorted = true;
  3498. $(oSettings.oInstance).trigger('sort', oSettings);
  3499. /* Copy the master data into the draw array and re-draw */
  3500. if ( oSettings.oFeatures.bFilter )
  3501. {
  3502. /* _fnFilter() will redraw the table for us */
  3503. _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 );
  3504. }
  3505. else
  3506. {
  3507. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  3508. oSettings._iDisplayStart = 0; /* reset display back to page 0 */
  3509. _fnCalculateEnd( oSettings );
  3510. _fnDraw( oSettings );
  3511. }
  3512. }
  3513. /**
  3514. * Attach a sort handler (click) to a node
  3515. * @param {object} oSettings dataTables settings object
  3516. * @param {node} nNode node to attach the handler to
  3517. * @param {int} iDataIndex column sorting index
  3518. * @param {function} [fnCallback] callback function
  3519. * @memberof DataTable#oApi
  3520. */
  3521. function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback )
  3522. {
  3523. _fnBindAction( nNode, {}, function (e) {
  3524. /* If the column is not sortable - don't to anything */
  3525. if ( oSettings.aoColumns[iDataIndex].bSortable === false )
  3526. {
  3527. return;
  3528. }
  3529. /*
  3530. * This is a little bit odd I admit... I declare a temporary function inside the scope of
  3531. * _fnBuildHead and the click handler in order that the code presented here can be used
  3532. * twice - once for when bProcessing is enabled, and another time for when it is
  3533. * disabled, as we need to perform slightly different actions.
  3534. * Basically the issue here is that the Javascript engine in modern browsers don't
  3535. * appear to allow the rendering engine to update the display while it is still excuting
  3536. * it's thread (well - it does but only after long intervals). This means that the
  3537. * 'processing' display doesn't appear for a table sort. To break the js thread up a bit
  3538. * I force an execution break by using setTimeout - but this breaks the expected
  3539. * thread continuation for the end-developer's point of view (their code would execute
  3540. * too early), so we on;y do it when we absolutely have to.
  3541. */
  3542. var fnInnerSorting = function () {
  3543. var iColumn, iNextSort;
  3544. /* If the shift key is pressed then we are multipe column sorting */
  3545. if ( e.shiftKey )
  3546. {
  3547. /* Are we already doing some kind of sort on this column? */
  3548. var bFound = false;
  3549. for ( var i=0 ; i<oSettings.aaSorting.length ; i++ )
  3550. {
  3551. if ( oSettings.aaSorting[i][0] == iDataIndex )
  3552. {
  3553. bFound = true;
  3554. iColumn = oSettings.aaSorting[i][0];
  3555. iNextSort = oSettings.aaSorting[i][2]+1;
  3556. if ( !oSettings.aoColumns[iColumn].asSorting[iNextSort] )
  3557. {
  3558. /* Reached the end of the sorting options, remove from multi-col sort */
  3559. oSettings.aaSorting.splice( i, 1 );
  3560. }
  3561. else
  3562. {
  3563. /* Move onto next sorting direction */
  3564. oSettings.aaSorting[i][1] = oSettings.aoColumns[iColumn].asSorting[iNextSort];
  3565. oSettings.aaSorting[i][2] = iNextSort;
  3566. }
  3567. break;
  3568. }
  3569. }
  3570. /* No sort yet - add it in */
  3571. if ( bFound === false )
  3572. {
  3573. oSettings.aaSorting.push( [ iDataIndex,
  3574. oSettings.aoColumns[iDataIndex].asSorting[0], 0 ] );
  3575. }
  3576. }
  3577. else
  3578. {
  3579. /* If no shift key then single column sort */
  3580. if ( oSettings.aaSorting.length == 1 && oSettings.aaSorting[0][0] == iDataIndex )
  3581. {
  3582. iColumn = oSettings.aaSorting[0][0];
  3583. iNextSort = oSettings.aaSorting[0][2]+1;
  3584. if ( !oSettings.aoColumns[iColumn].asSorting[iNextSort] )
  3585. {
  3586. iNextSort = 0;
  3587. }
  3588. oSettings.aaSorting[0][1] = oSettings.aoColumns[iColumn].asSorting[iNextSort];
  3589. oSettings.aaSorting[0][2] = iNextSort;
  3590. }
  3591. else
  3592. {
  3593. oSettings.aaSorting.splice( 0, oSettings.aaSorting.length );
  3594. oSettings.aaSorting.push( [ iDataIndex,
  3595. oSettings.aoColumns[iDataIndex].asSorting[0], 0 ] );
  3596. }
  3597. }
  3598. /* Run the sort */
  3599. _fnSort( oSettings );
  3600. }; /* /fnInnerSorting */
  3601. if ( !oSettings.oFeatures.bProcessing )
  3602. {
  3603. fnInnerSorting();
  3604. }
  3605. else
  3606. {
  3607. _fnProcessingDisplay( oSettings, true );
  3608. setTimeout( function() {
  3609. fnInnerSorting();
  3610. if ( !oSettings.oFeatures.bServerSide )
  3611. {
  3612. _fnProcessingDisplay( oSettings, false );
  3613. }
  3614. }, 0 );
  3615. }
  3616. /* Call the user specified callback function - used for async user interaction */
  3617. if ( typeof fnCallback == 'function' )
  3618. {
  3619. fnCallback( oSettings );
  3620. }
  3621. } );
  3622. }
  3623. /**
  3624. * Set the sorting classes on the header, Note: it is safe to call this function
  3625. * when bSort and bSortClasses are false
  3626. * @param {object} oSettings dataTables settings object
  3627. * @memberof DataTable#oApi
  3628. */
  3629. function _fnSortingClasses( oSettings )
  3630. {
  3631. var i, iLen, j, jLen, iFound;
  3632. var aaSort, sClass;
  3633. var iColumns = oSettings.aoColumns.length;
  3634. var oClasses = oSettings.oClasses;
  3635. for ( i=0 ; i<iColumns ; i++ )
  3636. {
  3637. if ( oSettings.aoColumns[i].bSortable )
  3638. {
  3639. $(oSettings.aoColumns[i].nTh).removeClass( oClasses.sSortAsc +" "+ oClasses.sSortDesc +
  3640. " "+ oSettings.aoColumns[i].sSortingClass );
  3641. }
  3642. }
  3643. if ( oSettings.aaSortingFixed !== null )
  3644. {
  3645. aaSort = oSettings.aaSortingFixed.concat( oSettings.aaSorting );
  3646. }
  3647. else
  3648. {
  3649. aaSort = oSettings.aaSorting.slice();
  3650. }
  3651. /* Apply the required classes to the header */
  3652. for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
  3653. {
  3654. if ( oSettings.aoColumns[i].bSortable )
  3655. {
  3656. sClass = oSettings.aoColumns[i].sSortingClass;
  3657. iFound = -1;
  3658. for ( j=0 ; j<aaSort.length ; j++ )
  3659. {
  3660. if ( aaSort[j][0] == i )
  3661. {
  3662. sClass = ( aaSort[j][1] == "asc" ) ?
  3663. oClasses.sSortAsc : oClasses.sSortDesc;
  3664. iFound = j;
  3665. break;
  3666. }
  3667. }
  3668. $(oSettings.aoColumns[i].nTh).addClass( sClass );
  3669. if ( oSettings.bJUI )
  3670. {
  3671. /* jQuery UI uses extra markup */
  3672. var jqSpan = $("span."+oClasses.sSortIcon, oSettings.aoColumns[i].nTh);
  3673. jqSpan.removeClass(oClasses.sSortJUIAsc +" "+ oClasses.sSortJUIDesc +" "+
  3674. oClasses.sSortJUI +" "+ oClasses.sSortJUIAscAllowed +" "+ oClasses.sSortJUIDescAllowed );
  3675. var sSpanClass;
  3676. if ( iFound == -1 )
  3677. {
  3678. sSpanClass = oSettings.aoColumns[i].sSortingClassJUI;
  3679. }
  3680. else if ( aaSort[iFound][1] == "asc" )
  3681. {
  3682. sSpanClass = oClasses.sSortJUIAsc;
  3683. }
  3684. else
  3685. {
  3686. sSpanClass = oClasses.sSortJUIDesc;
  3687. }
  3688. jqSpan.addClass( sSpanClass );
  3689. }
  3690. }
  3691. else
  3692. {
  3693. /* No sorting on this column, so add the base class. This will have been assigned by
  3694. * _fnAddColumn
  3695. */
  3696. $(oSettings.aoColumns[i].nTh).addClass( oSettings.aoColumns[i].sSortingClass );
  3697. }
  3698. }
  3699. /*
  3700. * Apply the required classes to the table body
  3701. * Note that this is given as a feature switch since it can significantly slow down a sort
  3702. * on large data sets (adding and removing of classes is always slow at the best of times..)
  3703. * Further to this, note that this code is admitadly fairly ugly. It could be made a lot
  3704. * simpiler using jQuery selectors and add/removeClass, but that is significantly slower
  3705. * (on the order of 5 times slower) - hence the direct DOM manipulation here.
  3706. * Note that for defered drawing we do use jQuery - the reason being that taking the first
  3707. * row found to see if the whole column needs processed can miss classes since the first
  3708. * column might be new.
  3709. */
  3710. sClass = oClasses.sSortColumn;
  3711. if ( oSettings.oFeatures.bSort && oSettings.oFeatures.bSortClasses )
  3712. {
  3713. var nTds = _fnGetTdNodes( oSettings );
  3714. /* Remove the old classes */
  3715. if ( oSettings.oFeatures.bDeferRender )
  3716. {
  3717. $(nTds).removeClass(sClass+'1 '+sClass+'2 '+sClass+'3');
  3718. }
  3719. else if ( nTds.length >= iColumns )
  3720. {
  3721. for ( i=0 ; i<iColumns ; i++ )
  3722. {
  3723. if ( nTds[i].className.indexOf(sClass+"1") != -1 )
  3724. {
  3725. for ( j=0, jLen=(nTds.length/iColumns) ; j<jLen ; j++ )
  3726. {
  3727. nTds[(iColumns*j)+i].className =
  3728. $.trim( nTds[(iColumns*j)+i].className.replace( sClass+"1", "" ) );
  3729. }
  3730. }
  3731. else if ( nTds[i].className.indexOf(sClass+"2") != -1 )
  3732. {
  3733. for ( j=0, jLen=(nTds.length/iColumns) ; j<jLen ; j++ )
  3734. {
  3735. nTds[(iColumns*j)+i].className =
  3736. $.trim( nTds[(iColumns*j)+i].className.replace( sClass+"2", "" ) );
  3737. }
  3738. }
  3739. else if ( nTds[i].className.indexOf(sClass+"3") != -1 )
  3740. {
  3741. for ( j=0, jLen=(nTds.length/iColumns) ; j<jLen ; j++ )
  3742. {
  3743. nTds[(iColumns*j)+i].className =
  3744. $.trim( nTds[(iColumns*j)+i].className.replace( " "+sClass+"3", "" ) );
  3745. }
  3746. }
  3747. }
  3748. }
  3749. /* Add the new classes to the table */
  3750. var iClass = 1, iTargetCol;
  3751. for ( i=0 ; i<aaSort.length ; i++ )
  3752. {
  3753. iTargetCol = parseInt( aaSort[i][0], 10 );
  3754. for ( j=0, jLen=(nTds.length/iColumns) ; j<jLen ; j++ )
  3755. {
  3756. nTds[(iColumns*j)+iTargetCol].className += " "+sClass+iClass;
  3757. }
  3758. if ( iClass < 3 )
  3759. {
  3760. iClass++;
  3761. }
  3762. }
  3763. }
  3764. }
  3765. /**
  3766. * Save the state of a table in a cookie such that the page can be reloaded
  3767. * @param {object} oSettings dataTables settings object
  3768. * @memberof DataTable#oApi
  3769. */
  3770. function _fnSaveState ( oSettings )
  3771. {
  3772. if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying )
  3773. {
  3774. return;
  3775. }
  3776. /* Store the interesting variables */
  3777. var i, iLen, bInfinite=oSettings.oScroll.bInfinite;
  3778. var oState = {
  3779. "iCreate": new Date().getTime(),
  3780. "iStart": (bInfinite ? 0 : oSettings._iDisplayStart),
  3781. "iEnd": (bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd),
  3782. "iLength": oSettings._iDisplayLength,
  3783. "aaSorting": $.extend( true, [], oSettings.aaSorting ),
  3784. "oSearch": $.extend( true, {}, oSettings.oPreviousSearch ),
  3785. "aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ),
  3786. "abVisCols": []
  3787. };
  3788. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  3789. {
  3790. oState.abVisCols.push( oSettings.aoColumns[i].bVisible );
  3791. }
  3792. _fnCallbackFire( oSettings, "aoStateSaveParams", 'stateSaveParams', [oSettings, oState] );
  3793. oSettings.fnStateSave.call( oSettings.oInstance, oSettings, oState );
  3794. }
  3795. /**
  3796. * Attempt to load a saved table state from a cookie
  3797. * @param {object} oSettings dataTables settings object
  3798. * @param {object} oInit DataTables init object so we can override settings
  3799. * @memberof DataTable#oApi
  3800. */
  3801. function _fnLoadState ( oSettings, oInit )
  3802. {
  3803. if ( !oSettings.oFeatures.bStateSave )
  3804. {
  3805. return;
  3806. }
  3807. var oData = oSettings.fnStateLoad.call( oSettings.oInstance, oSettings );
  3808. if ( !oData )
  3809. {
  3810. return;
  3811. }
  3812. /* Allow custom and plug-in manipulation functions to alter the saved data set and
  3813. * cancelling of loading by returning false
  3814. */
  3815. var abStateLoad = _fnCallbackFire( oSettings, 'aoStateLoadParams', 'stateLoadParams', [oSettings, oData] );
  3816. if ( $.inArray( false, abStateLoad ) !== -1 )
  3817. {
  3818. return;
  3819. }
  3820. /* Store the saved state so it might be accessed at any time */
  3821. oSettings.oLoadedState = $.extend( true, {}, oData );
  3822. /* Restore key features */
  3823. oSettings._iDisplayStart = oData.iStart;
  3824. oSettings.iInitDisplayStart = oData.iStart;
  3825. oSettings._iDisplayEnd = oData.iEnd;
  3826. oSettings._iDisplayLength = oData.iLength;
  3827. oSettings.aaSorting = oData.aaSorting.slice();
  3828. oSettings.saved_aaSorting = oData.aaSorting.slice();
  3829. /* Search filtering */
  3830. $.extend( oSettings.oPreviousSearch, oData.oSearch );
  3831. $.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols );
  3832. /* Column visibility state
  3833. * Pass back visibiliy settings to the init handler, but to do not here override
  3834. * the init object that the user might have passed in
  3835. */
  3836. oInit.saved_aoColumns = [];
  3837. for ( var i=0 ; i<oData.abVisCols.length ; i++ )
  3838. {
  3839. oInit.saved_aoColumns[i] = {};
  3840. oInit.saved_aoColumns[i].bVisible = oData.abVisCols[i];
  3841. }
  3842. _fnCallbackFire( oSettings, 'aoStateLoaded', 'stateLoaded', [oSettings, oData] );
  3843. }
  3844. /**
  3845. * Create a new cookie with a value to store the state of a table
  3846. * @param {string} sName name of the cookie to create
  3847. * @param {string} sValue the value the cookie should take
  3848. * @param {int} iSecs duration of the cookie
  3849. * @param {string} sBaseName sName is made up of the base + file name - this is the base
  3850. * @param {function} fnCallback User definable function to modify the cookie
  3851. * @memberof DataTable#oApi
  3852. */
  3853. function _fnCreateCookie ( sName, sValue, iSecs, sBaseName, fnCallback )
  3854. {
  3855. var date = new Date();
  3856. date.setTime( date.getTime()+(iSecs*1000) );
  3857. /*
  3858. * Shocking but true - it would appear IE has major issues with having the path not having
  3859. * a trailing slash on it. We need the cookie to be available based on the path, so we
  3860. * have to append the file name to the cookie name. Appalling. Thanks to vex for adding the
  3861. * patch to use at least some of the path
  3862. */
  3863. var aParts = window.location.pathname.split('/');
  3864. var sNameFile = sName + '_' + aParts.pop().replace(/[\/:]/g,"").toLowerCase();
  3865. var sFullCookie, oData;
  3866. if ( fnCallback !== null )
  3867. {
  3868. oData = (typeof $.parseJSON === 'function') ?
  3869. $.parseJSON( sValue ) : eval( '('+sValue+')' );
  3870. sFullCookie = fnCallback( sNameFile, oData, date.toGMTString(),
  3871. aParts.join('/')+"/" );
  3872. }
  3873. else
  3874. {
  3875. sFullCookie = sNameFile + "=" + encodeURIComponent(sValue) +
  3876. "; expires=" + date.toGMTString() +"; path=" + aParts.join('/')+"/";
  3877. }
  3878. /* Are we going to go over the cookie limit of 4KiB? If so, try to delete a cookies
  3879. * belonging to DataTables. This is FAR from bullet proof
  3880. */
  3881. var sOldName="", iOldTime=9999999999999;
  3882. var iLength = _fnReadCookie( sNameFile )!==null ? document.cookie.length :
  3883. sFullCookie.length + document.cookie.length;
  3884. if ( iLength+10 > 4096 ) /* Magic 10 for padding */
  3885. {
  3886. var aCookies =document.cookie.split(';');
  3887. for ( var i=0, iLen=aCookies.length ; i<iLen ; i++ )
  3888. {
  3889. if ( aCookies[i].indexOf( sBaseName ) != -1 )
  3890. {
  3891. /* It's a DataTables cookie, so eval it and check the time stamp */
  3892. var aSplitCookie = aCookies[i].split('=');
  3893. try { oData = eval( '('+decodeURIComponent(aSplitCookie[1])+')' ); }
  3894. catch( e ) { continue; }
  3895. if ( oData.iCreate && oData.iCreate < iOldTime )
  3896. {
  3897. sOldName = aSplitCookie[0];
  3898. iOldTime = oData.iCreate;
  3899. }
  3900. }
  3901. }
  3902. if ( sOldName !== "" )
  3903. {
  3904. document.cookie = sOldName+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+
  3905. aParts.join('/') + "/";
  3906. }
  3907. }
  3908. document.cookie = sFullCookie;
  3909. }
  3910. /**
  3911. * Read an old cookie to get a cookie with an old table state
  3912. * @param {string} sName name of the cookie to read
  3913. * @returns {string} contents of the cookie - or null if no cookie with that name found
  3914. * @memberof DataTable#oApi
  3915. */
  3916. function _fnReadCookie ( sName )
  3917. {
  3918. var
  3919. aParts = window.location.pathname.split('/'),
  3920. sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase() + '=',
  3921. sCookieContents = document.cookie.split(';');
  3922. for( var i=0 ; i<sCookieContents.length ; i++ )
  3923. {
  3924. var c = sCookieContents[i];
  3925. while (c.charAt(0)==' ')
  3926. {
  3927. c = c.substring(1,c.length);
  3928. }
  3929. if (c.indexOf(sNameEQ) === 0)
  3930. {
  3931. return decodeURIComponent( c.substring(sNameEQ.length,c.length) );
  3932. }
  3933. }
  3934. return null;
  3935. }
  3936. /**
  3937. * Return the settings object for a particular table
  3938. * @param {node} nTable table we are using as a dataTable
  3939. * @returns {object} Settings object - or null if not found
  3940. * @memberof DataTable#oApi
  3941. */
  3942. function _fnSettingsFromNode ( nTable )
  3943. {
  3944. for ( var i=0 ; i<DataTable.settings.length ; i++ )
  3945. {
  3946. if ( DataTable.settings[i].nTable === nTable )
  3947. {
  3948. return DataTable.settings[i];
  3949. }
  3950. }
  3951. return null;
  3952. }
  3953. /**
  3954. * Return an array with the TR nodes for the table
  3955. * @param {object} oSettings dataTables settings object
  3956. * @returns {array} TR array
  3957. * @memberof DataTable#oApi
  3958. */
  3959. function _fnGetTrNodes ( oSettings )
  3960. {
  3961. var aNodes = [];
  3962. var aoData = oSettings.aoData;
  3963. for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
  3964. {
  3965. if ( aoData[i].nTr !== null )
  3966. {
  3967. aNodes.push( aoData[i].nTr );
  3968. }
  3969. }
  3970. return aNodes;
  3971. }
  3972. /**
  3973. * Return an flat array with all TD nodes for the table, or row
  3974. * @param {object} oSettings dataTables settings object
  3975. * @param {int} [iIndividualRow] aoData index to get the nodes for - optional
  3976. * if not given then the return array will contain all nodes for the table
  3977. * @returns {array} TD array
  3978. * @memberof DataTable#oApi
  3979. */
  3980. function _fnGetTdNodes ( oSettings, iIndividualRow )
  3981. {
  3982. var anReturn = [];
  3983. var iCorrector;
  3984. var anTds;
  3985. var iRow, iRows=oSettings.aoData.length,
  3986. iColumn, iColumns, oData, sNodeName, iStart=0, iEnd=iRows;
  3987. /* Allow the collection to be limited to just one row */
  3988. if ( iIndividualRow !== undefined )
  3989. {
  3990. iStart = iIndividualRow;
  3991. iEnd = iIndividualRow+1;
  3992. }
  3993. for ( iRow=iStart ; iRow<iEnd ; iRow++ )
  3994. {
  3995. oData = oSettings.aoData[iRow];
  3996. if ( oData.nTr !== null )
  3997. {
  3998. /* get the TD child nodes - taking into account text etc nodes */
  3999. anTds = [];
  4000. for ( iColumn=0, iColumns=oData.nTr.childNodes.length ; iColumn<iColumns ; iColumn++ )
  4001. {
  4002. sNodeName = oData.nTr.childNodes[iColumn].nodeName.toLowerCase();
  4003. if ( sNodeName == 'td' || sNodeName == 'th' )
  4004. {
  4005. anTds.push( oData.nTr.childNodes[iColumn] );
  4006. }
  4007. }
  4008. iCorrector = 0;
  4009. for ( iColumn=0, iColumns=oSettings.aoColumns.length ; iColumn<iColumns ; iColumn++ )
  4010. {
  4011. if ( oSettings.aoColumns[iColumn].bVisible )
  4012. {
  4013. anReturn.push( anTds[iColumn-iCorrector] );
  4014. }
  4015. else
  4016. {
  4017. anReturn.push( oData._anHidden[iColumn] );
  4018. iCorrector++;
  4019. }
  4020. }
  4021. }
  4022. }
  4023. return anReturn;
  4024. }
  4025. /**
  4026. * Log an error message
  4027. * @param {object} oSettings dataTables settings object
  4028. * @param {int} iLevel log error messages, or display them to the user
  4029. * @param {string} sMesg error message
  4030. * @memberof DataTable#oApi
  4031. */
  4032. function _fnLog( oSettings, iLevel, sMesg )
  4033. {
  4034. var sAlert = (oSettings===null) ?
  4035. "DataTables warning: "+sMesg :
  4036. "DataTables warning (table id = '"+oSettings.sTableId+"'): "+sMesg;
  4037. if ( iLevel === 0 )
  4038. {
  4039. if ( DataTable.ext.sErrMode == 'alert' )
  4040. {
  4041. alert( sAlert );
  4042. }
  4043. else
  4044. {
  4045. throw new Error(sAlert);
  4046. }
  4047. return;
  4048. }
  4049. else if ( window.console && console.log )
  4050. {
  4051. console.log( sAlert );
  4052. }
  4053. }
  4054. /**
  4055. * See if a property is defined on one object, if so assign it to the other object
  4056. * @param {object} oRet target object
  4057. * @param {object} oSrc source object
  4058. * @param {string} sName property
  4059. * @param {string} [sMappedName] name to map too - optional, sName used if not given
  4060. * @memberof DataTable#oApi
  4061. */
  4062. function _fnMap( oRet, oSrc, sName, sMappedName )
  4063. {
  4064. if ( sMappedName === undefined )
  4065. {
  4066. sMappedName = sName;
  4067. }
  4068. if ( oSrc[sName] !== undefined )
  4069. {
  4070. oRet[sMappedName] = oSrc[sName];
  4071. }
  4072. }
  4073. /**
  4074. * Extend objects - very similar to jQuery.extend, but deep copy objects, and shallow
  4075. * copy arrays. The reason we need to do this, is that we don't want to deep copy array
  4076. * init values (such as aaSorting) since the dev wouldn't be able to override them, but
  4077. * we do want to deep copy arrays.
  4078. * @param {object} oOut Object to extend
  4079. * @param {object} oExtender Object from which the properties will be applied to oOut
  4080. * @returns {object} oOut Reference, just for convenience - oOut === the return.
  4081. * @memberof DataTable#oApi
  4082. * @todo This doesn't take account of arrays inside the deep copied objects.
  4083. */
  4084. function _fnExtend( oOut, oExtender )
  4085. {
  4086. for ( var prop in oExtender )
  4087. {
  4088. if ( oExtender.hasOwnProperty(prop) )
  4089. {
  4090. if ( typeof oInit[prop] === 'object' && $.isArray(oExtender[prop]) === false )
  4091. {
  4092. $.extend( true, oOut[prop], oExtender[prop] );
  4093. }
  4094. else
  4095. {
  4096. oOut[prop] = oExtender[prop];
  4097. }
  4098. }
  4099. }
  4100. return oOut;
  4101. }
  4102. /**
  4103. * Bind an event handers to allow a click or return key to activate the callback.
  4104. * This is good for accessability since a return on the keyboard will have the
  4105. * same effect as a click, if the element has focus.
  4106. * @param {element} n Element to bind the action to
  4107. * @param {object} oData Data object to pass to the triggered function
  4108. * @param {function) fn Callback function for when the event is triggered
  4109. * @memberof DataTable#oApi
  4110. */
  4111. function _fnBindAction( n, oData, fn )
  4112. {
  4113. $(n)
  4114. .bind( 'click.DT', oData, function (e) {
  4115. n.blur(); // Remove focus outline for mouse users
  4116. fn(e);
  4117. } )
  4118. .bind( 'keypress.DT', oData, function (e){
  4119. if ( e.which === 13 ) {
  4120. fn(e);
  4121. } } )
  4122. .bind( 'selectstart.DT', function () {
  4123. /* Take the brutal approach to cancelling text selection */
  4124. return false;
  4125. } );
  4126. }
  4127. /**
  4128. * Register a callback function. Easily allows a callback function to be added to
  4129. * an array store of callback functions that can then all be called together.
  4130. * @param {object} oSettings dataTables settings object
  4131. * @param {string} sStore Name of the array storeage for the callbacks in oSettings
  4132. * @param {function} fn Function to be called back
  4133. * @param {string) sName Identifying name for the callback (i.e. a label)
  4134. * @memberof DataTable#oApi
  4135. */
  4136. function _fnCallbackReg( oSettings, sStore, fn, sName )
  4137. {
  4138. if ( fn )
  4139. {
  4140. oSettings[sStore].push( {
  4141. "fn": fn,
  4142. "sName": sName
  4143. } );
  4144. }
  4145. }
  4146. /**
  4147. * Fire callback functions and trigger events. Note that the loop over the callback
  4148. * array store is done backwards! Further note that you do not want to fire off triggers
  4149. * in time sensitive applications (for example cell creation) as its slow.
  4150. * @param {object} oSettings dataTables settings object
  4151. * @param {string} sStore Name of the array storeage for the callbacks in oSettings
  4152. * @param {string} sTrigger Name of the jQuery custom event to trigger. If null no trigger
  4153. * is fired
  4154. * @param {array) aArgs Array of arguments to pass to the callback function / trigger
  4155. * @memberof DataTable#oApi
  4156. */
  4157. function _fnCallbackFire( oSettings, sStore, sTrigger, aArgs )
  4158. {
  4159. var aoStore = oSettings[sStore];
  4160. var aRet =[];
  4161. for ( var i=aoStore.length-1 ; i>=0 ; i-- )
  4162. {
  4163. aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) );
  4164. }
  4165. if ( sTrigger !== null )
  4166. {
  4167. $(oSettings.oInstance).trigger(sTrigger, aArgs);
  4168. }
  4169. return aRet;
  4170. }
  4171. /**
  4172. * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other
  4173. * library, then we use that as it is fast, safe and accurate. If the function isn't
  4174. * available then we need to built it ourselves - the insperation for this function comes
  4175. * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is
  4176. * not perfect and absolutely should not be used as a replacement to json2.js - but it does
  4177. * do what we need, without requiring a dependency for DataTables.
  4178. * @param {object} o JSON object to be converted
  4179. * @returns {string} JSON string
  4180. * @memberof DataTable#oApi
  4181. */
  4182. var _fnJsonString = (window.JSON) ? JSON.stringify : function( o )
  4183. {
  4184. /* Not an object or array */
  4185. var sType = typeof o;
  4186. if (sType !== "object" || o === null)
  4187. {
  4188. // simple data type
  4189. if (sType === "string")
  4190. {
  4191. o = '"'+o+'"';
  4192. }
  4193. return o+"";
  4194. }
  4195. /* If object or array, need to recurse over it */
  4196. var
  4197. sProp, mValue,
  4198. json = [],
  4199. bArr = $.isArray(o);
  4200. for (sProp in o)
  4201. {
  4202. mValue = o[sProp];
  4203. sType = typeof mValue;
  4204. if (sType === "string")
  4205. {
  4206. mValue = '"'+mValue+'"';
  4207. }
  4208. else if (sType === "object" && mValue !== null)
  4209. {
  4210. mValue = _fnJsonString(mValue);
  4211. }
  4212. json.push((bArr ? "" : '"'+sProp+'":') + mValue);
  4213. }
  4214. return (bArr ? "[" : "{") + json + (bArr ? "]" : "}");
  4215. };
  4216. /**
  4217. * Perform a jQuery selector action on the table's TR elements (from the tbody) and
  4218. * return the resulting jQuery object.
  4219. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
  4220. * @param {object} [oOpts] Optional parameters for modifying the rows to be included
  4221. * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
  4222. * criterion ("applied") or all TR elements (i.e. no filter).
  4223. * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
  4224. * Can be either 'current', whereby the current sorting of the table is used, or
  4225. * 'original' whereby the original order the data was read into the table is used.
  4226. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
  4227. * ("current") or not ("all"). If 'current' is given, then order is assumed to be
  4228. * 'current' and filter is 'applied', regardless of what they might be given as.
  4229. * @returns {object} jQuery object, filtered by the given selector.
  4230. * @dtopt API
  4231. *
  4232. * @example
  4233. * $(document).ready(function() {
  4234. * var oTable = $('#example').dataTable();
  4235. *
  4236. * // Highlight every second row
  4237. * oTable.$('tr:odd').css('backgroundColor', 'blue');
  4238. * } );
  4239. *
  4240. * @example
  4241. * $(document).ready(function() {
  4242. * var oTable = $('#example').dataTable();
  4243. *
  4244. * // Filter to rows with 'Webkit' in them, add a background colour and then
  4245. * // remove the filter, thus highlighting the 'Webkit' rows only.
  4246. * oTable.fnFilter('Webkit');
  4247. * oTable.$('tr', {"filter": "applied"}).css('backgroundColor', 'blue');
  4248. * oTable.fnFilter('');
  4249. * } );
  4250. */
  4251. this.$ = function ( sSelector, oOpts )
  4252. {
  4253. var i, iLen, a = [];
  4254. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4255. if ( !oOpts )
  4256. {
  4257. oOpts = {};
  4258. }
  4259. oOpts = $.extend( {}, {
  4260. "filter": "none", // applied
  4261. "order": "current", // "original"
  4262. "page": "all" // current
  4263. }, oOpts );
  4264. // Current page implies that order=current and fitler=applied, since it is fairly
  4265. // senseless otherwise
  4266. if ( oOpts.page == 'current' )
  4267. {
  4268. for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i<iLen ; i++ )
  4269. {
  4270. a.push( oSettings.aoData[ oSettings.aiDisplay[i] ].nTr );
  4271. }
  4272. }
  4273. else if ( oOpts.order == "current" && oOpts.filter == "none" )
  4274. {
  4275. for ( i=0, iLen=oSettings.aiDisplayMaster.length ; i<iLen ; i++ )
  4276. {
  4277. a.push( oSettings.aoData[ oSettings.aiDisplayMaster[i] ].nTr );
  4278. }
  4279. }
  4280. else if ( oOpts.order == "current" && oOpts.filter == "applied" )
  4281. {
  4282. for ( i=0, iLen=oSettings.aiDisplay.length ; i<iLen ; i++ )
  4283. {
  4284. a.push( oSettings.aoData[ oSettings.aiDisplay[i] ].nTr );
  4285. }
  4286. }
  4287. else if ( oOpts.order == "original" && oOpts.filter == "none" )
  4288. {
  4289. for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
  4290. {
  4291. a.push( oSettings.aoData[ i ].nTr );
  4292. }
  4293. }
  4294. else if ( oOpts.order == "original" && oOpts.filter == "applied" )
  4295. {
  4296. for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
  4297. {
  4298. if ( $.inArray( i, oSettings.aiDisplay ) !== -1 )
  4299. {
  4300. a.push( oSettings.aoData[ i ].nTr );
  4301. }
  4302. }
  4303. }
  4304. else
  4305. {
  4306. _fnLog( oSettings, 1, "Unknown selection options" );
  4307. }
  4308. /* We need to filter on the TR elements and also 'find' in their descendants
  4309. * to make the selector act like it would in a full table - so we need
  4310. * to build both results and then combine them together
  4311. */
  4312. var jqA = $(a);
  4313. var jqTRs = jqA.filter( sSelector );
  4314. var jqDescendants = jqA.find( sSelector );
  4315. return $( [].concat($.makeArray(jqTRs), $.makeArray(jqDescendants)) );
  4316. };
  4317. /**
  4318. * Almost identical to $ in operation, but in this case returns the data for the matched
  4319. * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
  4320. * rather than any decendents, so the data can be obtained for the row/cell. If matching
  4321. * rows are found, the data returned is the original data array/object that was used to
  4322. * create the row (or a generated array if from a DOM source).
  4323. *
  4324. * This method is often useful incombination with $ where both functions are given the
  4325. * same parameters and the array indexes will match identically.
  4326. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
  4327. * @param {object} [oOpts] Optional parameters for modifying the rows to be included
  4328. * @param {string} [oOpts.filter=none] Select elements that meet the current filter
  4329. * criterion ("applied") or all elements (i.e. no filter).
  4330. * @param {string} [oOpts.order=current] Order of the data in the processed array.
  4331. * Can be either 'current', whereby the current sorting of the table is used, or
  4332. * 'original' whereby the original order the data was read into the table is used.
  4333. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
  4334. * ("current") or not ("all"). If 'current' is given, then order is assumed to be
  4335. * 'current' and filter is 'applied', regardless of what they might be given as.
  4336. * @returns {array} Data for the matched elements. If any elements, as a result of the
  4337. * selector, were not TR, TD or TH elements in the DataTable, they will have a null
  4338. * entry in the array.
  4339. * @dtopt API
  4340. *
  4341. * @example
  4342. * $(document).ready(function() {
  4343. * var oTable = $('#example').dataTable();
  4344. *
  4345. * // Get the data from the first row in the table
  4346. * var data = oTable._('tr:first');
  4347. *
  4348. * // Do something useful with the data
  4349. * alert( "First cell is: "+data[0] );
  4350. * } );
  4351. *
  4352. * @example
  4353. * $(document).ready(function() {
  4354. * var oTable = $('#example').dataTable();
  4355. *
  4356. * // Filter to 'Webkit' and get all data for
  4357. * oTable.fnFilter('Webkit');
  4358. * var data = oTable._('tr', {"filter": "applied"});
  4359. *
  4360. * // Do something with the data
  4361. * alert( data.length+" rows matched the filter" );
  4362. * } );
  4363. */
  4364. this._ = function ( sSelector, oOpts )
  4365. {
  4366. var aOut = [];
  4367. var i, iLen, iIndex;
  4368. var aTrs = this.$( sSelector, oOpts );
  4369. for ( i=0, iLen=aTrs.length ; i<iLen ; i++ )
  4370. {
  4371. aOut.push( this.fnGetData(aTrs[i]) );
  4372. }
  4373. return aOut;
  4374. };
  4375. /**
  4376. * Add a single new row or multiple rows of data to the table. Please note
  4377. * that this is suitable for client-side processing only - if you are using
  4378. * server-side processing (i.e. "bServerSide": true), then to add data, you
  4379. * must add it to the data source, i.e. the server-side, through an Ajax call.
  4380. * @param {array|object} mData The data to be added to the table. This can be:
  4381. * <ul>
  4382. * <li>1D array of data - add a single row with the data provided</li>
  4383. * <li>2D array of arrays - add multiple rows in a single call</li>
  4384. * <li>object - data object when using <i>mDataProp</i></li>
  4385. * <li>array of objects - multiple data objects when using <i>mDataProp</i></li>
  4386. * </ul>
  4387. * @param {bool} [bRedraw=true] redraw the table or not
  4388. * @returns {array} An array of integers, representing the list of indexes in
  4389. * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
  4390. * the table.
  4391. * @dtopt API
  4392. *
  4393. * @example
  4394. * // Global var for counter
  4395. * var giCount = 2;
  4396. *
  4397. * $(document).ready(function() {
  4398. * $('#example').dataTable();
  4399. * } );
  4400. *
  4401. * function fnClickAddRow() {
  4402. * $('#example').dataTable().fnAddData( [
  4403. * giCount+".1",
  4404. * giCount+".2",
  4405. * giCount+".3",
  4406. * giCount+".4" ]
  4407. * );
  4408. *
  4409. * giCount++;
  4410. * }
  4411. */
  4412. this.fnAddData = function( mData, bRedraw )
  4413. {
  4414. if ( mData.length === 0 )
  4415. {
  4416. return [];
  4417. }
  4418. var aiReturn = [];
  4419. var iTest;
  4420. /* Find settings from table node */
  4421. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4422. /* Check if we want to add multiple rows or not */
  4423. if ( typeof mData[0] === "object" && mData[0] !== null )
  4424. {
  4425. for ( var i=0 ; i<mData.length ; i++ )
  4426. {
  4427. iTest = _fnAddData( oSettings, mData[i] );
  4428. if ( iTest == -1 )
  4429. {
  4430. return aiReturn;
  4431. }
  4432. aiReturn.push( iTest );
  4433. }
  4434. }
  4435. else
  4436. {
  4437. iTest = _fnAddData( oSettings, mData );
  4438. if ( iTest == -1 )
  4439. {
  4440. return aiReturn;
  4441. }
  4442. aiReturn.push( iTest );
  4443. }
  4444. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  4445. if ( bRedraw === undefined || bRedraw )
  4446. {
  4447. _fnReDraw( oSettings );
  4448. }
  4449. return aiReturn;
  4450. };
  4451. /**
  4452. * This function will make DataTables recalculate the column sizes, based on the data
  4453. * contained in the table and the sizes applied to the columns (in the DOM, CSS or
  4454. * through the sWidth parameter). This can be useful when the width of the table's
  4455. * parent element changes (for example a window resize).
  4456. * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
  4457. * @dtopt API
  4458. *
  4459. * @example
  4460. * $(document).ready(function() {
  4461. * var oTable = $('#example').dataTable( {
  4462. * "sScrollY": "200px",
  4463. * "bPaginate": false
  4464. * } );
  4465. *
  4466. * $(window).bind('resize', function () {
  4467. * oTable.fnAdjustColumnSizing();
  4468. * } );
  4469. * } );
  4470. */
  4471. this.fnAdjustColumnSizing = function ( bRedraw )
  4472. {
  4473. var oSettings = _fnSettingsFromNode(this[DataTable.ext.iApiIndex]);
  4474. _fnAdjustColumnSizing( oSettings );
  4475. if ( bRedraw === undefined || bRedraw )
  4476. {
  4477. this.fnDraw( false );
  4478. }
  4479. else if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
  4480. {
  4481. /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
  4482. this.oApi._fnScrollDraw(oSettings);
  4483. }
  4484. };
  4485. /**
  4486. * Quickly and simply clear a table
  4487. * @param {bool} [bRedraw=true] redraw the table or not
  4488. * @dtopt API
  4489. *
  4490. * @example
  4491. * $(document).ready(function() {
  4492. * var oTable = $('#example').dataTable();
  4493. *
  4494. * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
  4495. * oTable.fnClearTable();
  4496. * } );
  4497. */
  4498. this.fnClearTable = function( bRedraw )
  4499. {
  4500. /* Find settings from table node */
  4501. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4502. _fnClearTable( oSettings );
  4503. if ( bRedraw === undefined || bRedraw )
  4504. {
  4505. _fnDraw( oSettings );
  4506. }
  4507. };
  4508. /**
  4509. * The exact opposite of 'opening' a row, this function will close any rows which
  4510. * are currently 'open'.
  4511. * @param {node} nTr the table row to 'close'
  4512. * @returns {int} 0 on success, or 1 if failed (can't find the row)
  4513. * @dtopt API
  4514. *
  4515. * @example
  4516. * $(document).ready(function() {
  4517. * var oTable;
  4518. *
  4519. * // 'open' an information row when a row is clicked on
  4520. * $('#example tbody tr').click( function () {
  4521. * if ( oTable.fnIsOpen(this) ) {
  4522. * oTable.fnClose( this );
  4523. * } else {
  4524. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  4525. * }
  4526. * } );
  4527. *
  4528. * oTable = $('#example').dataTable();
  4529. * } );
  4530. */
  4531. this.fnClose = function( nTr )
  4532. {
  4533. /* Find settings from table node */
  4534. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4535. for ( var i=0 ; i<oSettings.aoOpenRows.length ; i++ )
  4536. {
  4537. if ( oSettings.aoOpenRows[i].nParent == nTr )
  4538. {
  4539. var nTrParent = oSettings.aoOpenRows[i].nTr.parentNode;
  4540. if ( nTrParent )
  4541. {
  4542. /* Remove it if it is currently on display */
  4543. nTrParent.removeChild( oSettings.aoOpenRows[i].nTr );
  4544. }
  4545. oSettings.aoOpenRows.splice( i, 1 );
  4546. return 0;
  4547. }
  4548. }
  4549. return 1;
  4550. };
  4551. /**
  4552. * Remove a row for the table
  4553. * @param {mixed} mTarget The index of the row from aoData to be deleted, or
  4554. * the TR element you want to delete
  4555. * @param {function|null} [fnCallBack] Callback function
  4556. * @param {bool} [bRedraw=true] Redraw the table or not
  4557. * @returns {array} The row that was deleted
  4558. * @dtopt API
  4559. *
  4560. * @example
  4561. * $(document).ready(function() {
  4562. * var oTable = $('#example').dataTable();
  4563. *
  4564. * // Immediately remove the first row
  4565. * oTable.fnDeleteRow( 0 );
  4566. * } );
  4567. */
  4568. this.fnDeleteRow = function( mTarget, fnCallBack, bRedraw )
  4569. {
  4570. /* Find settings from table node */
  4571. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4572. var i, iLen, iAODataIndex;
  4573. iAODataIndex = (typeof mTarget === 'object') ?
  4574. _fnNodeToDataIndex(oSettings, mTarget) : mTarget;
  4575. /* Return the data array from this row */
  4576. var oData = oSettings.aoData.splice( iAODataIndex, 1 );
  4577. /* Update the _DT_RowIndex parameter */
  4578. for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
  4579. {
  4580. if ( oSettings.aoData[i].nTr !== null )
  4581. {
  4582. oSettings.aoData[i].nTr._DT_RowIndex = i;
  4583. }
  4584. }
  4585. /* Remove the target row from the search array */
  4586. var iDisplayIndex = $.inArray( iAODataIndex, oSettings.aiDisplay );
  4587. oSettings.asDataSearch.splice( iDisplayIndex, 1 );
  4588. /* Delete from the display arrays */
  4589. _fnDeleteIndex( oSettings.aiDisplayMaster, iAODataIndex );
  4590. _fnDeleteIndex( oSettings.aiDisplay, iAODataIndex );
  4591. /* If there is a user callback function - call it */
  4592. if ( typeof fnCallBack === "function" )
  4593. {
  4594. fnCallBack.call( this, oSettings, oData );
  4595. }
  4596. /* Check for an 'overflow' they case for dislaying the table */
  4597. if ( oSettings._iDisplayStart >= oSettings.aiDisplay.length )
  4598. {
  4599. oSettings._iDisplayStart -= oSettings._iDisplayLength;
  4600. if ( oSettings._iDisplayStart < 0 )
  4601. {
  4602. oSettings._iDisplayStart = 0;
  4603. }
  4604. }
  4605. if ( bRedraw === undefined || bRedraw )
  4606. {
  4607. _fnCalculateEnd( oSettings );
  4608. _fnDraw( oSettings );
  4609. }
  4610. return oData;
  4611. };
  4612. /**
  4613. * Restore the table to it's original state in the DOM by removing all of DataTables
  4614. * enhancements, alterations to the DOM structure of the table and event listeners.
  4615. * @param {boolean} [bRemove=false] Completely remove the table from the DOM
  4616. * @dtopt API
  4617. *
  4618. * @example
  4619. * $(document).ready(function() {
  4620. * // This example is fairly pointless in reality, but shows how fnDestroy can be used
  4621. * var oTable = $('#example').dataTable();
  4622. * oTable.fnDestroy();
  4623. * } );
  4624. */
  4625. this.fnDestroy = function ( bRemove )
  4626. {
  4627. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4628. var nOrig = oSettings.nTableWrapper.parentNode;
  4629. var nBody = oSettings.nTBody;
  4630. var i, iLen;
  4631. bRemove = (bRemove===undefined) ? false : true;
  4632. /* Flag to note that the table is currently being destroyed - no action should be taken */
  4633. oSettings.bDestroying = true;
  4634. /* Fire off the destroy callbacks for plug-ins etc */
  4635. _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] );
  4636. /* Restore hidden columns */
  4637. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  4638. {
  4639. if ( oSettings.aoColumns[i].bVisible === false )
  4640. {
  4641. this.fnSetColumnVis( i, true );
  4642. }
  4643. }
  4644. /* Blitz all DT events */
  4645. $(oSettings.nTableWrapper).find('*').andSelf().unbind('.DT');
  4646. /* If there is an 'empty' indicator row, remove it */
  4647. $('tbody>tr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove();
  4648. /* When scrolling we had to break the table up - restore it */
  4649. if ( oSettings.nTable != oSettings.nTHead.parentNode )
  4650. {
  4651. $(oSettings.nTable).children('thead').remove();
  4652. oSettings.nTable.appendChild( oSettings.nTHead );
  4653. }
  4654. if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode )
  4655. {
  4656. $(oSettings.nTable).children('tfoot').remove();
  4657. oSettings.nTable.appendChild( oSettings.nTFoot );
  4658. }
  4659. /* Remove the DataTables generated nodes, events and classes */
  4660. oSettings.nTable.parentNode.removeChild( oSettings.nTable );
  4661. $(oSettings.nTableWrapper).remove();
  4662. oSettings.aaSorting = [];
  4663. oSettings.aaSortingFixed = [];
  4664. _fnSortingClasses( oSettings );
  4665. $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') );
  4666. $('th, td', oSettings.nTHead).removeClass( [
  4667. oSettings.oClasses.sSortable,
  4668. oSettings.oClasses.sSortableAsc,
  4669. oSettings.oClasses.sSortableDesc,
  4670. oSettings.oClasses.sSortableNone ].join(' ')
  4671. );
  4672. if ( oSettings.bJUI )
  4673. {
  4674. $('th span.'+oSettings.oClasses.sSortIcon
  4675. + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove();
  4676. $('th, td', oSettings.nTHead).each( function () {
  4677. var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this);
  4678. var kids = jqWrapper.contents();
  4679. $(this).append( kids );
  4680. jqWrapper.remove();
  4681. } );
  4682. }
  4683. /* Add the TR elements back into the table in their original order */
  4684. if ( !bRemove && oSettings.nTableReinsertBefore )
  4685. {
  4686. nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore );
  4687. }
  4688. else if ( !bRemove )
  4689. {
  4690. nOrig.appendChild( oSettings.nTable );
  4691. }
  4692. for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
  4693. {
  4694. if ( oSettings.aoData[i].nTr !== null )
  4695. {
  4696. nBody.appendChild( oSettings.aoData[i].nTr );
  4697. }
  4698. }
  4699. /* Restore the width of the original table */
  4700. if ( oSettings.oFeatures.bAutoWidth === true )
  4701. {
  4702. oSettings.nTable.style.width = _fnStringToCss(oSettings.sDestroyWidth);
  4703. }
  4704. /* If the were originally odd/even type classes - then we add them back here. Note
  4705. * this is not fool proof (for example if not all rows as odd/even classes - but
  4706. * it's a good effort without getting carried away
  4707. */
  4708. $(nBody).children('tr:even').addClass( oSettings.asDestroyStripes[0] );
  4709. $(nBody).children('tr:odd').addClass( oSettings.asDestroyStripes[1] );
  4710. /* Remove the settings object from the settings array */
  4711. for ( i=0, iLen=DataTable.settings.length ; i<iLen ; i++ )
  4712. {
  4713. if ( DataTable.settings[i] == oSettings )
  4714. {
  4715. DataTable.settings.splice( i, 1 );
  4716. }
  4717. }
  4718. /* End it all */
  4719. oSettings = null;
  4720. };
  4721. /**
  4722. * Redraw the table
  4723. * @param {bool} [bComplete=true] Re-filter and resort (if enabled) the table before the draw.
  4724. * @dtopt API
  4725. *
  4726. * @example
  4727. * $(document).ready(function() {
  4728. * var oTable = $('#example').dataTable();
  4729. *
  4730. * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
  4731. * oTable.fnDraw();
  4732. * } );
  4733. */
  4734. this.fnDraw = function( bComplete )
  4735. {
  4736. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4737. if ( bComplete === false )
  4738. {
  4739. _fnCalculateEnd( oSettings );
  4740. _fnDraw( oSettings );
  4741. }
  4742. else
  4743. {
  4744. _fnReDraw( oSettings );
  4745. }
  4746. };
  4747. /**
  4748. * Filter the input based on data
  4749. * @param {string} sInput String to filter the table on
  4750. * @param {int|null} [iColumn] Column to limit filtering to
  4751. * @param {bool} [bRegex=false] Treat as regular expression or not
  4752. * @param {bool} [bSmart=true] Perform smart filtering or not
  4753. * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
  4754. * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
  4755. * @dtopt API
  4756. *
  4757. * @example
  4758. * $(document).ready(function() {
  4759. * var oTable = $('#example').dataTable();
  4760. *
  4761. * // Sometime later - filter...
  4762. * oTable.fnFilter( 'test string' );
  4763. * } );
  4764. */
  4765. this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
  4766. {
  4767. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4768. if ( !oSettings.oFeatures.bFilter )
  4769. {
  4770. return;
  4771. }
  4772. if ( bRegex === undefined || bRegex === null )
  4773. {
  4774. bRegex = false;
  4775. }
  4776. if ( bSmart === undefined || bSmart === null )
  4777. {
  4778. bSmart = true;
  4779. }
  4780. if ( bShowGlobal === undefined || bShowGlobal === null )
  4781. {
  4782. bShowGlobal = true;
  4783. }
  4784. if ( bCaseInsensitive === undefined || bCaseInsensitive === null )
  4785. {
  4786. bCaseInsensitive = true;
  4787. }
  4788. if ( iColumn === undefined || iColumn === null )
  4789. {
  4790. /* Global filter */
  4791. _fnFilterComplete( oSettings, {
  4792. "sSearch":sInput+"",
  4793. "bRegex": bRegex,
  4794. "bSmart": bSmart,
  4795. "bCaseInsensitive": bCaseInsensitive
  4796. }, 1 );
  4797. if ( bShowGlobal && oSettings.aanFeatures.f )
  4798. {
  4799. var n = oSettings.aanFeatures.f;
  4800. for ( var i=0, iLen=n.length ; i<iLen ; i++ )
  4801. {
  4802. $(n[i]._DT_Input).val( sInput );
  4803. }
  4804. }
  4805. }
  4806. else
  4807. {
  4808. /* Single column filter */
  4809. $.extend( oSettings.aoPreSearchCols[ iColumn ], {
  4810. "sSearch": sInput+"",
  4811. "bRegex": bRegex,
  4812. "bSmart": bSmart,
  4813. "bCaseInsensitive": bCaseInsensitive
  4814. } );
  4815. _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 );
  4816. }
  4817. };
  4818. /**
  4819. * Get the data for the whole table, an individual row or an individual cell based on the
  4820. * provided parameters.
  4821. * @param {int|node} [mRow] A TR row node, TD/TH cell node or an integer. If given as
  4822. * a TR node then the data source for the whole row will be returned. If given as a
  4823. * TD/TH cell node then iCol will be automatically calculated and the data for the
  4824. * cell returned. If given as an integer, then this is treated as the aoData internal
  4825. * data index for the row (see fnGetPosition) and the data for that row used.
  4826. * @param {int} [iCol] Optional column index that you want the data of.
  4827. * @returns {array|object|string} If mRow is undefined, then the data for all rows is
  4828. * returned. If mRow is defined, just data for that row, and is iCol is
  4829. * defined, only data for the designated cell is returned.
  4830. * @dtopt API
  4831. *
  4832. * @example
  4833. * // Row data
  4834. * $(document).ready(function() {
  4835. * oTable = $('#example').dataTable();
  4836. *
  4837. * oTable.$('tr').click( function () {
  4838. * var data = oTable.fnGetData( this );
  4839. * // ... do something with the array / object of data for the row
  4840. * } );
  4841. * } );
  4842. *
  4843. * @example
  4844. * // Individual cell data
  4845. * $(document).ready(function() {
  4846. * oTable = $('#example').dataTable();
  4847. *
  4848. * oTable.$('td').click( function () {
  4849. * var sData = oTable.fnGetData( this );
  4850. * alert( 'The cell clicked on had the value of '+sData );
  4851. * } );
  4852. * } );
  4853. */
  4854. this.fnGetData = function( mRow, iCol )
  4855. {
  4856. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4857. if ( mRow !== undefined )
  4858. {
  4859. var iRow = mRow;
  4860. if ( typeof mRow === 'object' )
  4861. {
  4862. var sNode = mRow.nodeName.toLowerCase();
  4863. if (sNode === "tr" )
  4864. {
  4865. iRow = _fnNodeToDataIndex(oSettings, mRow);
  4866. }
  4867. else if ( sNode === "td" )
  4868. {
  4869. iRow = _fnNodeToDataIndex(oSettings, mRow.parentNode);
  4870. iCol = _fnNodeToColumnIndex( oSettings, iRow, mRow );
  4871. }
  4872. }
  4873. if ( iCol !== undefined )
  4874. {
  4875. return _fnGetCellData( oSettings, iRow, iCol, '' );
  4876. }
  4877. return (oSettings.aoData[iRow]!==undefined) ?
  4878. oSettings.aoData[iRow]._aData : null;
  4879. }
  4880. return _fnGetDataMaster( oSettings );
  4881. };
  4882. /**
  4883. * Get an array of the TR nodes that are used in the table's body. Note that you will
  4884. * typically want to use the '$' API method in preference to this as it is more
  4885. * flexible.
  4886. * @param {int} [iRow] Optional row index for the TR element you want
  4887. * @returns {array|node} If iRow is undefined, returns an array of all TR elements
  4888. * in the table's body, or iRow is defined, just the TR element requested.
  4889. * @dtopt API
  4890. *
  4891. * @example
  4892. * $(document).ready(function() {
  4893. * var oTable = $('#example').dataTable();
  4894. *
  4895. * // Get the nodes from the table
  4896. * var nNodes = oTable.fnGetNodes( );
  4897. * } );
  4898. */
  4899. this.fnGetNodes = function( iRow )
  4900. {
  4901. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4902. if ( iRow !== undefined ) {
  4903. return (oSettings.aoData[iRow]!==undefined) ?
  4904. oSettings.aoData[iRow].nTr : null;
  4905. }
  4906. return _fnGetTrNodes( oSettings );
  4907. };
  4908. /**
  4909. * Get the array indexes of a particular cell from it's DOM element
  4910. * and column index including hidden columns
  4911. * @param {node} nNode this can either be a TR, TD or TH in the table's body
  4912. * @returns {int} If nNode is given as a TR, then a single index is returned, or
  4913. * if given as a cell, an array of [row index, column index (visible)] is given.
  4914. * @dtopt API
  4915. *
  4916. * @example
  4917. * $(document).ready(function() {
  4918. * $('#example tbody td').click( function () {
  4919. * // Get the position of the current data from the node
  4920. * var aPos = oTable.fnGetPosition( this );
  4921. *
  4922. * // Get the data array for this row
  4923. * var aData = oTable.fnGetData( aPos[0] );
  4924. *
  4925. * // Update the data array and return the value
  4926. * aData[ aPos[1] ] = 'clicked';
  4927. * this.innerHTML = 'clicked';
  4928. * } );
  4929. *
  4930. * // Init DataTables
  4931. * oTable = $('#example').dataTable();
  4932. * } );
  4933. */
  4934. this.fnGetPosition = function( nNode )
  4935. {
  4936. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4937. var sNodeName = nNode.nodeName.toUpperCase();
  4938. if ( sNodeName == "TR" )
  4939. {
  4940. return _fnNodeToDataIndex(oSettings, nNode);
  4941. }
  4942. else if ( sNodeName == "TD" || sNodeName == "TH" )
  4943. {
  4944. var iDataIndex = _fnNodeToDataIndex( oSettings, nNode.parentNode );
  4945. var iColumnIndex = _fnNodeToColumnIndex( oSettings, iDataIndex, nNode );
  4946. return [ iDataIndex, _fnColumnIndexToVisible(oSettings, iColumnIndex ), iColumnIndex ];
  4947. }
  4948. return null;
  4949. };
  4950. /**
  4951. * Check to see if a row is 'open' or not.
  4952. * @param {node} nTr the table row to check
  4953. * @returns {boolean} true if the row is currently open, false otherwise
  4954. * @dtopt API
  4955. *
  4956. * @example
  4957. * $(document).ready(function() {
  4958. * var oTable;
  4959. *
  4960. * // 'open' an information row when a row is clicked on
  4961. * $('#example tbody tr').click( function () {
  4962. * if ( oTable.fnIsOpen(this) ) {
  4963. * oTable.fnClose( this );
  4964. * } else {
  4965. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  4966. * }
  4967. * } );
  4968. *
  4969. * oTable = $('#example').dataTable();
  4970. * } );
  4971. */
  4972. this.fnIsOpen = function( nTr )
  4973. {
  4974. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  4975. var aoOpenRows = oSettings.aoOpenRows;
  4976. for ( var i=0 ; i<oSettings.aoOpenRows.length ; i++ )
  4977. {
  4978. if ( oSettings.aoOpenRows[i].nParent == nTr )
  4979. {
  4980. return true;
  4981. }
  4982. }
  4983. return false;
  4984. };
  4985. /**
  4986. * This function will place a new row directly after a row which is currently
  4987. * on display on the page, with the HTML contents that is passed into the
  4988. * function. This can be used, for example, to ask for confirmation that a
  4989. * particular record should be deleted.
  4990. * @param {node} nTr The table row to 'open'
  4991. * @param {string|node|jQuery} mHtml The HTML to put into the row
  4992. * @param {string} sClass Class to give the new TD cell
  4993. * @returns {node} The row opened. Note that if the table row passed in as the
  4994. * first parameter, is not found in the table, this method will silently
  4995. * return.
  4996. * @dtopt API
  4997. *
  4998. * @example
  4999. * $(document).ready(function() {
  5000. * var oTable;
  5001. *
  5002. * // 'open' an information row when a row is clicked on
  5003. * $('#example tbody tr').click( function () {
  5004. * if ( oTable.fnIsOpen(this) ) {
  5005. * oTable.fnClose( this );
  5006. * } else {
  5007. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  5008. * }
  5009. * } );
  5010. *
  5011. * oTable = $('#example').dataTable();
  5012. * } );
  5013. */
  5014. this.fnOpen = function( nTr, mHtml, sClass )
  5015. {
  5016. /* Find settings from table node */
  5017. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  5018. /* Check that the row given is in the table */
  5019. var nTableRows = _fnGetTrNodes( oSettings );
  5020. if ( $.inArray(nTr, nTableRows) === -1 )
  5021. {
  5022. return;
  5023. }
  5024. /* the old open one if there is one */
  5025. this.fnClose( nTr );
  5026. var nNewRow = document.createElement("tr");
  5027. var nNewCell = document.createElement("td");
  5028. nNewRow.appendChild( nNewCell );
  5029. nNewCell.className = sClass;
  5030. nNewCell.colSpan = _fnVisbleColumns( oSettings );
  5031. if (typeof mHtml === "string")
  5032. {
  5033. nNewCell.innerHTML = mHtml;
  5034. }
  5035. else
  5036. {
  5037. $(nNewCell).html( mHtml );
  5038. }
  5039. /* If the nTr isn't on the page at the moment - then we don't insert at the moment */
  5040. var nTrs = $('tr', oSettings.nTBody);
  5041. if ( $.inArray(nTr, nTrs) != -1 )
  5042. {
  5043. $(nNewRow).insertAfter(nTr);
  5044. }
  5045. oSettings.aoOpenRows.push( {
  5046. "nTr": nNewRow,
  5047. "nParent": nTr
  5048. } );
  5049. return nNewRow;
  5050. };
  5051. /**
  5052. * Change the pagination - provides the internal logic for pagination in a simple API
  5053. * function. With this function you can have a DataTables table go to the next,
  5054. * previous, first or last pages.
  5055. * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
  5056. * or page number to jump to (integer), note that page 0 is the first page.
  5057. * @param {bool} [bRedraw=true] Redraw the table or not
  5058. * @dtopt API
  5059. *
  5060. * @example
  5061. * $(document).ready(function() {
  5062. * var oTable = $('#example').dataTable();
  5063. * oTable.fnPageChange( 'next' );
  5064. * } );
  5065. */
  5066. this.fnPageChange = function ( mAction, bRedraw )
  5067. {
  5068. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  5069. _fnPageChange( oSettings, mAction );
  5070. _fnCalculateEnd( oSettings );
  5071. if ( bRedraw === undefined || bRedraw )
  5072. {
  5073. _fnDraw( oSettings );
  5074. }
  5075. };
  5076. /**
  5077. * Show a particular column
  5078. * @param {int} iCol The column whose display should be changed
  5079. * @param {bool} bShow Show (true) or hide (false) the column
  5080. * @param {bool} [bRedraw=true] Redraw the table or not
  5081. * @dtopt API
  5082. *
  5083. * @example
  5084. * $(document).ready(function() {
  5085. * var oTable = $('#example').dataTable();
  5086. *
  5087. * // Hide the second column after initialisation
  5088. * oTable.fnSetColumnVis( 1, false );
  5089. * } );
  5090. */
  5091. this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
  5092. {
  5093. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  5094. var i, iLen;
  5095. var aoColumns = oSettings.aoColumns;
  5096. var aoData = oSettings.aoData;
  5097. var nTd, bAppend, iBefore;
  5098. /* No point in doing anything if we are requesting what is already true */
  5099. if ( aoColumns[iCol].bVisible == bShow )
  5100. {
  5101. return;
  5102. }
  5103. /* Show the column */
  5104. if ( bShow )
  5105. {
  5106. var iInsert = 0;
  5107. for ( i=0 ; i<iCol ; i++ )
  5108. {
  5109. if ( aoColumns[i].bVisible )
  5110. {
  5111. iInsert++;
  5112. }
  5113. }
  5114. /* Need to decide if we should use appendChild or insertBefore */
  5115. bAppend = (iInsert >= _fnVisbleColumns( oSettings ));
  5116. /* Which coloumn should we be inserting before? */
  5117. if ( !bAppend )
  5118. {
  5119. for ( i=iCol ; i<aoColumns.length ; i++ )
  5120. {
  5121. if ( aoColumns[i].bVisible )
  5122. {
  5123. iBefore = i;
  5124. break;
  5125. }
  5126. }
  5127. }
  5128. for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
  5129. {
  5130. if ( aoData[i].nTr !== null )
  5131. {
  5132. if ( bAppend )
  5133. {
  5134. aoData[i].nTr.appendChild(
  5135. aoData[i]._anHidden[iCol]
  5136. );
  5137. }
  5138. else
  5139. {
  5140. aoData[i].nTr.insertBefore(
  5141. aoData[i]._anHidden[iCol],
  5142. _fnGetTdNodes( oSettings, i )[iBefore] );
  5143. }
  5144. }
  5145. }
  5146. }
  5147. else
  5148. {
  5149. /* Remove a column from display */
  5150. for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
  5151. {
  5152. if ( aoData[i].nTr !== null )
  5153. {
  5154. nTd = _fnGetTdNodes( oSettings, i )[iCol];
  5155. aoData[i]._anHidden[iCol] = nTd;
  5156. nTd.parentNode.removeChild( nTd );
  5157. }
  5158. }
  5159. }
  5160. /* Clear to set the visible flag */
  5161. aoColumns[iCol].bVisible = bShow;
  5162. /* Redraw the header and footer based on the new column visibility */
  5163. _fnDrawHead( oSettings, oSettings.aoHeader );
  5164. if ( oSettings.nTFoot )
  5165. {
  5166. _fnDrawHead( oSettings, oSettings.aoFooter );
  5167. }
  5168. /* If there are any 'open' rows, then we need to alter the colspan for this col change */
  5169. for ( i=0, iLen=oSettings.aoOpenRows.length ; i<iLen ; i++ )
  5170. {
  5171. oSettings.aoOpenRows[i].nTr.colSpan = _fnVisbleColumns( oSettings );
  5172. }
  5173. /* Do a redraw incase anything depending on the table columns needs it
  5174. * (built-in: scrolling)
  5175. */
  5176. if ( bRedraw === undefined || bRedraw )
  5177. {
  5178. _fnAdjustColumnSizing( oSettings );
  5179. _fnDraw( oSettings );
  5180. }
  5181. _fnSaveState( oSettings );
  5182. };
  5183. /**
  5184. * Get the settings for a particular table for external manipulation
  5185. * @returns {object} DataTables settings object. See
  5186. * {@link DataTable.models.oSettings}
  5187. * @dtopt API
  5188. *
  5189. * @example
  5190. * $(document).ready(function() {
  5191. * var oTable = $('#example').dataTable();
  5192. * var oSettings = oTable.fnSettings();
  5193. *
  5194. * // Show an example parameter from the settings
  5195. * alert( oSettings._iDisplayStart );
  5196. * } );
  5197. */
  5198. this.fnSettings = function()
  5199. {
  5200. return _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  5201. };
  5202. /**
  5203. * Sort the table by a particular column
  5204. * @param {int} iCol the data index to sort on. Note that this will not match the
  5205. * 'display index' if you have hidden data entries
  5206. * @dtopt API
  5207. *
  5208. * @example
  5209. * $(document).ready(function() {
  5210. * var oTable = $('#example').dataTable();
  5211. *
  5212. * // Sort immediately with columns 0 and 1
  5213. * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
  5214. * } );
  5215. */
  5216. this.fnSort = function( aaSort )
  5217. {
  5218. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  5219. oSettings.aaSorting = aaSort;
  5220. _fnSort( oSettings );
  5221. };
  5222. /**
  5223. * Attach a sort listener to an element for a given column
  5224. * @param {node} nNode the element to attach the sort listener to
  5225. * @param {int} iColumn the column that a click on this node will sort on
  5226. * @param {function} [fnCallback] callback function when sort is run
  5227. * @dtopt API
  5228. *
  5229. * @example
  5230. * $(document).ready(function() {
  5231. * var oTable = $('#example').dataTable();
  5232. *
  5233. * // Sort on column 1, when 'sorter' is clicked on
  5234. * oTable.fnSortListener( document.getElementById('sorter'), 1 );
  5235. * } );
  5236. */
  5237. this.fnSortListener = function( nNode, iColumn, fnCallback )
  5238. {
  5239. _fnSortAttachListener( _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ), nNode, iColumn,
  5240. fnCallback );
  5241. };
  5242. /**
  5243. * Update a table cell or row - this method will accept either a single value to
  5244. * update the cell with, an array of values with one element for each column or
  5245. * an object in the same format as the original data source. The function is
  5246. * self-referencing in order to make the multi column updates easier.
  5247. * @param {object|array|string} mData Data to update the cell/row with
  5248. * @param {node|int} mRow TR element you want to update or the aoData index
  5249. * @param {int} [iColumn] The column to update (not used of mData is an array or object)
  5250. * @param {bool} [bRedraw=true] Redraw the table or not
  5251. * @param {bool} [bAction=true] Perform predraw actions or not
  5252. * @returns {int} 0 on success, 1 on error
  5253. * @dtopt API
  5254. *
  5255. * @example
  5256. * $(document).ready(function() {
  5257. * var oTable = $('#example').dataTable();
  5258. * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
  5259. * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], 1, 0 ); // Row
  5260. * } );
  5261. */
  5262. this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
  5263. {
  5264. var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
  5265. var i, iLen, sDisplay;
  5266. var iRow = (typeof mRow === 'object') ?
  5267. _fnNodeToDataIndex(oSettings, mRow) : mRow;
  5268. if ( oSettings.__fnUpdateDeep === undefined && $.isArray(mData) && typeof mData === 'object' )
  5269. {
  5270. /* Array update - update the whole row */
  5271. oSettings.aoData[iRow]._aData = mData.slice();
  5272. /* Flag to the function that we are recursing */
  5273. oSettings.__fnUpdateDeep = true;
  5274. for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
  5275. {
  5276. this.fnUpdate( _fnGetCellData( oSettings, iRow, i ), iRow, i, false, false );
  5277. }
  5278. oSettings.__fnUpdateDeep = undefined;
  5279. }
  5280. else if ( oSettings.__fnUpdateDeep === undefined && mData !== null && typeof mData === 'object' )
  5281. {
  5282. /* Object update - update the whole row - assume the developer gets the object right */
  5283. oSettings.aoData[iRow]._aData = $.extend( true, {}, mData );
  5284. oSettings.__fnUpdateDeep = true;
  5285. for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
  5286. {
  5287. this.fnUpdate( _fnGetCellData( oSettings, iRow, i ), iRow, i, false, false );
  5288. }
  5289. oSettings.__fnUpdateDeep = undefined;
  5290. }
  5291. else
  5292. {
  5293. /* Individual cell update */
  5294. _fnSetCellData( oSettings, iRow, iColumn, mData );
  5295. sDisplay = _fnGetCellData( oSettings, iRow, iColumn, 'display' );
  5296. var oCol = oSettings.aoColumns[iColumn];
  5297. if ( oCol.fnRender !== null )
  5298. {
  5299. sDisplay = _fnRender( oSettings, iRow, iColumn );
  5300. if ( oCol.bUseRendered )
  5301. {
  5302. _fnSetCellData( oSettings, iRow, iColumn, sDisplay );
  5303. }
  5304. }
  5305. if ( oSettings.aoData[iRow].nTr !== null )
  5306. {
  5307. /* Do the actual HTML update */
  5308. _fnGetTdNodes( oSettings, iRow )[iColumn].innerHTML = sDisplay;
  5309. }
  5310. }
  5311. /* Modify the search index for this row (strictly this is likely not needed, since fnReDraw
  5312. * will rebuild the search array - however, the redraw might be disabled by the user)
  5313. */
  5314. var iDisplayIndex = $.inArray( iRow, oSettings.aiDisplay );
  5315. oSettings.asDataSearch[iDisplayIndex] = _fnBuildSearchRow( oSettings,
  5316. _fnGetRowData( oSettings, iRow, 'filter' ) );
  5317. /* Perform pre-draw actions */
  5318. if ( bAction === undefined || bAction )
  5319. {
  5320. _fnAdjustColumnSizing( oSettings );
  5321. }
  5322. /* Redraw the table */
  5323. if ( bRedraw === undefined || bRedraw )
  5324. {
  5325. _fnReDraw( oSettings );
  5326. }
  5327. return 0;
  5328. };
  5329. /**
  5330. * Provide a common method for plug-ins to check the version of DataTables being used, in order
  5331. * to ensure compatibility.
  5332. * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
  5333. * formats "X" and "X.Y" are also acceptable.
  5334. * @returns {boolean} true if this version of DataTables is greater or equal to the required
  5335. * version, or false if this version of DataTales is not suitable
  5336. * @method
  5337. * @dtopt API
  5338. *
  5339. * @example
  5340. * $(document).ready(function() {
  5341. * var oTable = $('#example').dataTable();
  5342. * alert( oTable.fnVersionCheck( '1.9.0' ) );
  5343. * } );
  5344. */
  5345. this.fnVersionCheck = DataTable.ext.fnVersionCheck;
  5346. /*
  5347. * This is really a good bit rubbish this method of exposing the internal methods
  5348. * publically... - To be fixed in 2.0 using methods on the prototype
  5349. */
  5350. /**
  5351. * Create a wrapper function for exporting an internal functions to an external API.
  5352. * @param {string} sFunc API function name
  5353. * @returns {function} wrapped function
  5354. * @memberof DataTable#oApi
  5355. */
  5356. function _fnExternApiFunc (sFunc)
  5357. {
  5358. return function() {
  5359. var aArgs = [_fnSettingsFromNode(this[DataTable.ext.iApiIndex])].concat(
  5360. Array.prototype.slice.call(arguments) );
  5361. return DataTable.ext.oApi[sFunc].apply( this, aArgs );
  5362. };
  5363. }
  5364. /**
  5365. * Reference to internal functions for use by plug-in developers. Note that these
  5366. * methods are references to internal functions and are considered to be private.
  5367. * If you use these methods, be aware that they are liable to change between versions
  5368. * (check the upgrade notes).
  5369. * @namespace
  5370. */
  5371. this.oApi = {
  5372. "_fnExternApiFunc": _fnExternApiFunc,
  5373. "_fnInitialise": _fnInitialise,
  5374. "_fnInitComplete": _fnInitComplete,
  5375. "_fnLanguageCompat": _fnLanguageCompat,
  5376. "_fnAddColumn": _fnAddColumn,
  5377. "_fnColumnOptions": _fnColumnOptions,
  5378. "_fnAddData": _fnAddData,
  5379. "_fnCreateTr": _fnCreateTr,
  5380. "_fnGatherData": _fnGatherData,
  5381. "_fnBuildHead": _fnBuildHead,
  5382. "_fnDrawHead": _fnDrawHead,
  5383. "_fnDraw": _fnDraw,
  5384. "_fnReDraw": _fnReDraw,
  5385. "_fnAjaxUpdate": _fnAjaxUpdate,
  5386. "_fnAjaxParameters": _fnAjaxParameters,
  5387. "_fnAjaxUpdateDraw": _fnAjaxUpdateDraw,
  5388. "_fnServerParams": _fnServerParams,
  5389. "_fnAddOptionsHtml": _fnAddOptionsHtml,
  5390. "_fnFeatureHtmlTable": _fnFeatureHtmlTable,
  5391. "_fnScrollDraw": _fnScrollDraw,
  5392. "_fnAdjustColumnSizing": _fnAdjustColumnSizing,
  5393. "_fnFeatureHtmlFilter": _fnFeatureHtmlFilter,
  5394. "_fnFilterComplete": _fnFilterComplete,
  5395. "_fnFilterCustom": _fnFilterCustom,
  5396. "_fnFilterColumn": _fnFilterColumn,
  5397. "_fnFilter": _fnFilter,
  5398. "_fnBuildSearchArray": _fnBuildSearchArray,
  5399. "_fnBuildSearchRow": _fnBuildSearchRow,
  5400. "_fnFilterCreateSearch": _fnFilterCreateSearch,
  5401. "_fnDataToSearch": _fnDataToSearch,
  5402. "_fnSort": _fnSort,
  5403. "_fnSortAttachListener": _fnSortAttachListener,
  5404. "_fnSortingClasses": _fnSortingClasses,
  5405. "_fnFeatureHtmlPaginate": _fnFeatureHtmlPaginate,
  5406. "_fnPageChange": _fnPageChange,
  5407. "_fnFeatureHtmlInfo": _fnFeatureHtmlInfo,
  5408. "_fnUpdateInfo": _fnUpdateInfo,
  5409. "_fnFeatureHtmlLength": _fnFeatureHtmlLength,
  5410. "_fnFeatureHtmlProcessing": _fnFeatureHtmlProcessing,
  5411. "_fnProcessingDisplay": _fnProcessingDisplay,
  5412. "_fnVisibleToColumnIndex": _fnVisibleToColumnIndex,
  5413. "_fnColumnIndexToVisible": _fnColumnIndexToVisible,
  5414. "_fnNodeToDataIndex": _fnNodeToDataIndex,
  5415. "_fnVisbleColumns": _fnVisbleColumns,
  5416. "_fnCalculateEnd": _fnCalculateEnd,
  5417. "_fnConvertToWidth": _fnConvertToWidth,
  5418. "_fnCalculateColumnWidths": _fnCalculateColumnWidths,
  5419. "_fnScrollingWidthAdjust": _fnScrollingWidthAdjust,
  5420. "_fnGetWidestNode": _fnGetWidestNode,
  5421. "_fnGetMaxLenString": _fnGetMaxLenString,
  5422. "_fnStringToCss": _fnStringToCss,
  5423. "_fnDetectType": _fnDetectType,
  5424. "_fnSettingsFromNode": _fnSettingsFromNode,
  5425. "_fnGetDataMaster": _fnGetDataMaster,
  5426. "_fnGetTrNodes": _fnGetTrNodes,
  5427. "_fnGetTdNodes": _fnGetTdNodes,
  5428. "_fnEscapeRegex": _fnEscapeRegex,
  5429. "_fnDeleteIndex": _fnDeleteIndex,
  5430. "_fnReOrderIndex": _fnReOrderIndex,
  5431. "_fnColumnOrdering": _fnColumnOrdering,
  5432. "_fnLog": _fnLog,
  5433. "_fnClearTable": _fnClearTable,
  5434. "_fnSaveState": _fnSaveState,
  5435. "_fnLoadState": _fnLoadState,
  5436. "_fnCreateCookie": _fnCreateCookie,
  5437. "_fnReadCookie": _fnReadCookie,
  5438. "_fnDetectHeader": _fnDetectHeader,
  5439. "_fnGetUniqueThs": _fnGetUniqueThs,
  5440. "_fnScrollBarWidth": _fnScrollBarWidth,
  5441. "_fnApplyToChildren": _fnApplyToChildren,
  5442. "_fnMap": _fnMap,
  5443. "_fnGetRowData": _fnGetRowData,
  5444. "_fnGetCellData": _fnGetCellData,
  5445. "_fnSetCellData": _fnSetCellData,
  5446. "_fnGetObjectDataFn": _fnGetObjectDataFn,
  5447. "_fnSetObjectDataFn": _fnSetObjectDataFn,
  5448. "_fnApplyColumnDefs": _fnApplyColumnDefs,
  5449. "_fnBindAction": _fnBindAction,
  5450. "_fnExtend": _fnExtend,
  5451. "_fnCallbackReg": _fnCallbackReg,
  5452. "_fnCallbackFire": _fnCallbackFire,
  5453. "_fnJsonString": _fnJsonString,
  5454. "_fnRender": _fnRender,
  5455. "_fnNodeToColumnIndex": _fnNodeToColumnIndex,
  5456. "_fnInfoMacros": _fnInfoMacros
  5457. };
  5458. $.extend( DataTable.ext.oApi, this.oApi );
  5459. for ( var sFunc in DataTable.ext.oApi )
  5460. {
  5461. if ( sFunc )
  5462. {
  5463. this[sFunc] = _fnExternApiFunc(sFunc);
  5464. }
  5465. }
  5466. var _that = this;
  5467. return this.each(function() {
  5468. var i=0, iLen, j, jLen, k, kLen;
  5469. var sId = this.getAttribute( 'id' );
  5470. var bInitHandedOff = false;
  5471. var bUsePassedData = false;
  5472. /* Sanity check */
  5473. if ( this.nodeName.toLowerCase() != 'table' )
  5474. {
  5475. _fnLog( null, 0, "Attempted to initialise DataTables on a node which is not a "+
  5476. "table: "+this.nodeName );
  5477. return;
  5478. }
  5479. /* Check to see if we are re-initialising a table */
  5480. for ( i=0, iLen=DataTable.settings.length ; i<iLen ; i++ )
  5481. {
  5482. /* Base check on table node */
  5483. if ( DataTable.settings[i].nTable == this )
  5484. {
  5485. if ( oInit === undefined || oInit.bRetrieve )
  5486. {
  5487. return DataTable.settings[i].oInstance;
  5488. }
  5489. else if ( oInit.bDestroy )
  5490. {
  5491. DataTable.settings[i].oInstance.fnDestroy();
  5492. break;
  5493. }
  5494. else
  5495. {
  5496. _fnLog( DataTable.settings[i], 0, "Cannot reinitialise DataTable.\n\n"+
  5497. "To retrieve the DataTables object for this table, pass no arguments or see "+
  5498. "the docs for bRetrieve and bDestroy" );
  5499. return;
  5500. }
  5501. }
  5502. /* If the element we are initialising has the same ID as a table which was previously
  5503. * initialised, but the table nodes don't match (from before) then we destroy the old
  5504. * instance by simply deleting it. This is under the assumption that the table has been
  5505. * destroyed by other methods. Anyone using non-id selectors will need to do this manually
  5506. */
  5507. if ( DataTable.settings[i].sTableId == this.id )
  5508. {
  5509. DataTable.settings.splice( i, 1 );
  5510. break;
  5511. }
  5512. }
  5513. /* Ensure the table has an ID - required for accessibility */
  5514. if ( sId === null || sId === "" )
  5515. {
  5516. sId = "DataTables_Table_"+(DataTable.ext._oExternConfig.iNextUnique++);
  5517. this.id = sId;
  5518. }
  5519. /* Create the settings object for this table and set some of the default parameters */
  5520. var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
  5521. "nTable": this,
  5522. "oApi": _that.oApi,
  5523. "oInit": oInit,
  5524. "sDestroyWidth": $(this).width(),
  5525. "sInstance": sId,
  5526. "sTableId": sId
  5527. } );
  5528. DataTable.settings.push( oSettings );
  5529. // Need to add the instance after the instance after the settings object has been added
  5530. // to the settings array, so we can self reference the table instance if more than one
  5531. oSettings.oInstance = (_that.length===1) ? _that : $(this).dataTable();
  5532. /* Setting up the initialisation object */
  5533. if ( !oInit )
  5534. {
  5535. oInit = {};
  5536. }
  5537. // Backwards compatibility, before we apply all the defaults
  5538. if ( oInit.oLanguage )
  5539. {
  5540. _fnLanguageCompat( oInit.oLanguage );
  5541. }
  5542. oInit = _fnExtend( $.extend(true, {}, DataTable.defaults), oInit );
  5543. // Map the initialisation options onto the settings object
  5544. _fnMap( oSettings.oFeatures, oInit, "bPaginate" );
  5545. _fnMap( oSettings.oFeatures, oInit, "bLengthChange" );
  5546. _fnMap( oSettings.oFeatures, oInit, "bFilter" );
  5547. _fnMap( oSettings.oFeatures, oInit, "bSort" );
  5548. _fnMap( oSettings.oFeatures, oInit, "bInfo" );
  5549. _fnMap( oSettings.oFeatures, oInit, "bProcessing" );
  5550. _fnMap( oSettings.oFeatures, oInit, "bAutoWidth" );
  5551. _fnMap( oSettings.oFeatures, oInit, "bSortClasses" );
  5552. _fnMap( oSettings.oFeatures, oInit, "bServerSide" );
  5553. _fnMap( oSettings.oFeatures, oInit, "bDeferRender" );
  5554. _fnMap( oSettings.oScroll, oInit, "sScrollX", "sX" );
  5555. _fnMap( oSettings.oScroll, oInit, "sScrollXInner", "sXInner" );
  5556. _fnMap( oSettings.oScroll, oInit, "sScrollY", "sY" );
  5557. _fnMap( oSettings.oScroll, oInit, "bScrollCollapse", "bCollapse" );
  5558. _fnMap( oSettings.oScroll, oInit, "bScrollInfinite", "bInfinite" );
  5559. _fnMap( oSettings.oScroll, oInit, "iScrollLoadGap", "iLoadGap" );
  5560. _fnMap( oSettings.oScroll, oInit, "bScrollAutoCss", "bAutoCss" );
  5561. _fnMap( oSettings, oInit, "asStripeClasses" );
  5562. _fnMap( oSettings, oInit, "asStripClasses", "asStripeClasses" ); // legacy
  5563. _fnMap( oSettings, oInit, "fnServerData" );
  5564. _fnMap( oSettings, oInit, "fnFormatNumber" );
  5565. _fnMap( oSettings, oInit, "sServerMethod" );
  5566. _fnMap( oSettings, oInit, "aaSorting" );
  5567. _fnMap( oSettings, oInit, "aaSortingFixed" );
  5568. _fnMap( oSettings, oInit, "aLengthMenu" );
  5569. _fnMap( oSettings, oInit, "sPaginationType" );
  5570. _fnMap( oSettings, oInit, "sAjaxSource" );
  5571. _fnMap( oSettings, oInit, "sAjaxDataProp" );
  5572. _fnMap( oSettings, oInit, "iCookieDuration" );
  5573. _fnMap( oSettings, oInit, "sCookiePrefix" );
  5574. _fnMap( oSettings, oInit, "sDom" );
  5575. _fnMap( oSettings, oInit, "bSortCellsTop" );
  5576. _fnMap( oSettings, oInit, "iTabIndex" );
  5577. _fnMap( oSettings, oInit, "oSearch", "oPreviousSearch" );
  5578. _fnMap( oSettings, oInit, "aoSearchCols", "aoPreSearchCols" );
  5579. _fnMap( oSettings, oInit, "iDisplayLength", "_iDisplayLength" );
  5580. _fnMap( oSettings, oInit, "bJQueryUI", "bJUI" );
  5581. _fnMap( oSettings, oInit, "fnCookieCallback" );
  5582. _fnMap( oSettings, oInit, "fnStateLoad" );
  5583. _fnMap( oSettings, oInit, "fnStateSave" );
  5584. _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
  5585. /* Callback functions which are array driven */
  5586. _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
  5587. _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
  5588. _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
  5589. _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
  5590. _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
  5591. _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
  5592. _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
  5593. _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
  5594. _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
  5595. _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
  5596. _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
  5597. if ( oSettings.oFeatures.bServerSide && oSettings.oFeatures.bSort &&
  5598. oSettings.oFeatures.bSortClasses )
  5599. {
  5600. /* Enable sort classes for server-side processing. Safe to do it here, since server-side
  5601. * processing must be enabled by the developer
  5602. */
  5603. _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSortingClasses, 'server_side_sort_classes' );
  5604. }
  5605. else if ( oSettings.oFeatures.bDeferRender )
  5606. {
  5607. _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSortingClasses, 'defer_sort_classes' );
  5608. }
  5609. if ( oInit.bJQueryUI )
  5610. {
  5611. /* Use the JUI classes object for display. You could clone the oStdClasses object if
  5612. * you want to have multiple tables with multiple independent classes
  5613. */
  5614. $.extend( oSettings.oClasses, DataTable.ext.oJUIClasses );
  5615. if ( oInit.sDom === DataTable.defaults.sDom && DataTable.defaults.sDom === "lfrtip" )
  5616. {
  5617. /* Set the DOM to use a layout suitable for jQuery UI's theming */
  5618. oSettings.sDom = '<"H"lfr>t<"F"ip>';
  5619. }
  5620. }
  5621. else
  5622. {
  5623. $.extend( oSettings.oClasses, DataTable.ext.oStdClasses );
  5624. }
  5625. $(this).addClass( oSettings.oClasses.sTable );
  5626. /* Calculate the scroll bar width and cache it for use later on */
  5627. if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
  5628. {
  5629. oSettings.oScroll.iBarWidth = _fnScrollBarWidth();
  5630. }
  5631. if ( oSettings.iInitDisplayStart === undefined )
  5632. {
  5633. /* Display start point, taking into account the save saving */
  5634. oSettings.iInitDisplayStart = oInit.iDisplayStart;
  5635. oSettings._iDisplayStart = oInit.iDisplayStart;
  5636. }
  5637. /* Must be done after everything which can be overridden by a cookie! */
  5638. if ( oInit.bStateSave )
  5639. {
  5640. oSettings.oFeatures.bStateSave = true;
  5641. _fnLoadState( oSettings, oInit );
  5642. _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
  5643. }
  5644. if ( oInit.iDeferLoading !== null )
  5645. {
  5646. oSettings.bDeferLoading = true;
  5647. var tmp = $.isArray( oInit.iDeferLoading );
  5648. oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
  5649. oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
  5650. }
  5651. if ( oInit.aaData !== null )
  5652. {
  5653. bUsePassedData = true;
  5654. }
  5655. /* Language definitions */
  5656. if ( oInit.oLanguage.sUrl !== "" )
  5657. {
  5658. /* Get the language definitions from a file - because this Ajax call makes the language
  5659. * get async to the remainder of this function we use bInitHandedOff to indicate that
  5660. * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
  5661. */
  5662. oSettings.oLanguage.sUrl = oInit.oLanguage.sUrl;
  5663. $.getJSON( oSettings.oLanguage.sUrl, null, function( json ) {
  5664. _fnLanguageCompat( json );
  5665. $.extend( true, oSettings.oLanguage, oInit.oLanguage, json );
  5666. _fnInitialise( oSettings );
  5667. } );
  5668. bInitHandedOff = true;
  5669. }
  5670. else
  5671. {
  5672. $.extend( true, oSettings.oLanguage, oInit.oLanguage );
  5673. }
  5674. /*
  5675. * Stripes
  5676. */
  5677. if ( oInit.asStripeClasses === null )
  5678. {
  5679. oSettings.asStripeClasses =[
  5680. oSettings.oClasses.sStripeOdd,
  5681. oSettings.oClasses.sStripeEven
  5682. ];
  5683. }
  5684. /* Remove row stripe classes if they are already on the table row */
  5685. var bStripeRemove = false;
  5686. var anRows = $(this).children('tbody').children('tr');
  5687. for ( i=0, iLen=oSettings.asStripeClasses.length ; i<iLen ; i++ )
  5688. {
  5689. if ( anRows.filter(":lt(2)").hasClass( oSettings.asStripeClasses[i]) )
  5690. {
  5691. bStripeRemove = true;
  5692. break;
  5693. }
  5694. }
  5695. if ( bStripeRemove )
  5696. {
  5697. /* Store the classes which we are about to remove so they can be readded on destroy */
  5698. oSettings.asDestroyStripes = [ '', '' ];
  5699. if ( $(anRows[0]).hasClass(oSettings.oClasses.sStripeOdd) )
  5700. {
  5701. oSettings.asDestroyStripes[0] += oSettings.oClasses.sStripeOdd+" ";
  5702. }
  5703. if ( $(anRows[0]).hasClass(oSettings.oClasses.sStripeEven) )
  5704. {
  5705. oSettings.asDestroyStripes[0] += oSettings.oClasses.sStripeEven;
  5706. }
  5707. if ( $(anRows[1]).hasClass(oSettings.oClasses.sStripeOdd) )
  5708. {
  5709. oSettings.asDestroyStripes[1] += oSettings.oClasses.sStripeOdd+" ";
  5710. }
  5711. if ( $(anRows[1]).hasClass(oSettings.oClasses.sStripeEven) )
  5712. {
  5713. oSettings.asDestroyStripes[1] += oSettings.oClasses.sStripeEven;
  5714. }
  5715. anRows.removeClass( oSettings.asStripeClasses.join(' ') );
  5716. }
  5717. /*
  5718. * Columns
  5719. * See if we should load columns automatically or use defined ones
  5720. */
  5721. var anThs = [];
  5722. var aoColumnsInit;
  5723. var nThead = this.getElementsByTagName('thead');
  5724. if ( nThead.length !== 0 )
  5725. {
  5726. _fnDetectHeader( oSettings.aoHeader, nThead[0] );
  5727. anThs = _fnGetUniqueThs( oSettings );
  5728. }
  5729. /* If not given a column array, generate one with nulls */
  5730. if ( oInit.aoColumns === null )
  5731. {
  5732. aoColumnsInit = [];
  5733. for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
  5734. {
  5735. aoColumnsInit.push( null );
  5736. }
  5737. }
  5738. else
  5739. {
  5740. aoColumnsInit = oInit.aoColumns;
  5741. }
  5742. /* Add the columns */
  5743. for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
  5744. {
  5745. /* Short cut - use the loop to check if we have column visibility state to restore */
  5746. if ( oInit.saved_aoColumns !== undefined && oInit.saved_aoColumns.length == iLen )
  5747. {
  5748. if ( aoColumnsInit[i] === null )
  5749. {
  5750. aoColumnsInit[i] = {};
  5751. }
  5752. aoColumnsInit[i].bVisible = oInit.saved_aoColumns[i].bVisible;
  5753. }
  5754. _fnAddColumn( oSettings, anThs ? anThs[i] : null );
  5755. }
  5756. /* Apply the column definitions */
  5757. _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
  5758. _fnColumnOptions( oSettings, iCol, oDef );
  5759. } );
  5760. /*
  5761. * Sorting
  5762. * Check the aaSorting array
  5763. */
  5764. for ( i=0, iLen=oSettings.aaSorting.length ; i<iLen ; i++ )
  5765. {
  5766. if ( oSettings.aaSorting[i][0] >= oSettings.aoColumns.length )
  5767. {
  5768. oSettings.aaSorting[i][0] = 0;
  5769. }
  5770. var oColumn = oSettings.aoColumns[ oSettings.aaSorting[i][0] ];
  5771. /* Add a default sorting index */
  5772. if ( oSettings.aaSorting[i][2] === undefined )
  5773. {
  5774. oSettings.aaSorting[i][2] = 0;
  5775. }
  5776. /* If aaSorting is not defined, then we use the first indicator in asSorting */
  5777. if ( oInit.aaSorting === undefined && oSettings.saved_aaSorting === undefined )
  5778. {
  5779. oSettings.aaSorting[i][1] = oColumn.asSorting[0];
  5780. }
  5781. /* Set the current sorting index based on aoColumns.asSorting */
  5782. for ( j=0, jLen=oColumn.asSorting.length ; j<jLen ; j++ )
  5783. {
  5784. if ( oSettings.aaSorting[i][1] == oColumn.asSorting[j] )
  5785. {
  5786. oSettings.aaSorting[i][2] = j;
  5787. break;
  5788. }
  5789. }
  5790. }
  5791. /* Do a first pass on the sorting classes (allows any size changes to be taken into
  5792. * account, and also will apply sorting disabled classes if disabled
  5793. */
  5794. _fnSortingClasses( oSettings );
  5795. /*
  5796. * Final init
  5797. * Cache the header, body and footer as required, creating them if needed
  5798. */
  5799. // Work around for Webkit bug 83867 - store the caption-side before removing from doc
  5800. var captions = $(this).children('caption').each( function () {
  5801. this._captionSide = $(this).css('caption-side');
  5802. } );
  5803. var thead = $(this).children('thead');
  5804. if ( thead.length === 0 )
  5805. {
  5806. thead = [ document.createElement( 'thead' ) ];
  5807. this.appendChild( thead[0] );
  5808. }
  5809. oSettings.nTHead = thead[0];
  5810. var tbody = $(this).children('tbody');
  5811. if ( tbody.length === 0 )
  5812. {
  5813. tbody = [ document.createElement( 'tbody' ) ];
  5814. this.appendChild( tbody[0] );
  5815. }
  5816. oSettings.nTBody = tbody[0];
  5817. oSettings.nTBody.setAttribute( "role", "alert" );
  5818. oSettings.nTBody.setAttribute( "aria-live", "polite" );
  5819. oSettings.nTBody.setAttribute( "aria-relevant", "all" );
  5820. var tfoot = $(this).children('tfoot');
  5821. if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
  5822. {
  5823. // If we are a scrolling table, and no footer has been given, then we need to create
  5824. // a tfoot element for the caption element to be appended to
  5825. tfoot = [ document.createElement( 'tfoot' ) ];
  5826. this.appendChild( tfoot[0] );
  5827. }
  5828. if ( tfoot.length > 0 )
  5829. {
  5830. oSettings.nTFoot = tfoot[0];
  5831. _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
  5832. }
  5833. /* Check if there is data passing into the constructor */
  5834. if ( bUsePassedData )
  5835. {
  5836. for ( i=0 ; i<oInit.aaData.length ; i++ )
  5837. {
  5838. _fnAddData( oSettings, oInit.aaData[ i ] );
  5839. }
  5840. }
  5841. else
  5842. {
  5843. /* Grab the data from the page */
  5844. _fnGatherData( oSettings );
  5845. }
  5846. /* Copy the data index array */
  5847. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  5848. /* Initialisation complete - table can be drawn */
  5849. oSettings.bInitialised = true;
  5850. /* Check if we need to initialise the table (it might not have been handed off to the
  5851. * language processor)
  5852. */
  5853. if ( bInitHandedOff === false )
  5854. {
  5855. _fnInitialise( oSettings );
  5856. }
  5857. } );
  5858. };
  5859. /**
  5860. * Provide a common method for plug-ins to check the version of DataTables being used, in order
  5861. * to ensure compatibility.
  5862. * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
  5863. * formats "X" and "X.Y" are also acceptable.
  5864. * @returns {boolean} true if this version of DataTables is greater or equal to the required
  5865. * version, or false if this version of DataTales is not suitable
  5866. * @static
  5867. * @dtopt API-Static
  5868. *
  5869. * @example
  5870. * alert( $.fn.dataTable.fnVersionCheck( '1.9.0' ) );
  5871. */
  5872. DataTable.fnVersionCheck = function( sVersion )
  5873. {
  5874. /* This is cheap, but effective */
  5875. var fnZPad = function (Zpad, count)
  5876. {
  5877. while(Zpad.length < count) {
  5878. Zpad += '0';
  5879. }
  5880. return Zpad;
  5881. };
  5882. var aThis = DataTable.ext.sVersion.split('.');
  5883. var aThat = sVersion.split('.');
  5884. var sThis = '', sThat = '';
  5885. for ( var i=0, iLen=aThat.length ; i<iLen ; i++ )
  5886. {
  5887. sThis += fnZPad( aThis[i], 3 );
  5888. sThat += fnZPad( aThat[i], 3 );
  5889. }
  5890. return parseInt(sThis, 10) >= parseInt(sThat, 10);
  5891. };
  5892. /**
  5893. * Check if a TABLE node is a DataTable table already or not.
  5894. * @param {node} nTable The TABLE node to check if it is a DataTable or not (note that other
  5895. * node types can be passed in, but will always return false).
  5896. * @returns {boolean} true the table given is a DataTable, or false otherwise
  5897. * @static
  5898. * @dtopt API-Static
  5899. *
  5900. * @example
  5901. * var ex = document.getElementById('example');
  5902. * if ( ! $.fn.DataTable.fnIsDataTable( ex ) ) {
  5903. * $(ex).dataTable();
  5904. * }
  5905. */
  5906. DataTable.fnIsDataTable = function ( nTable )
  5907. {
  5908. var o = DataTable.settings;
  5909. for ( var i=0 ; i<o.length ; i++ )
  5910. {
  5911. if ( o[i].nTable === nTable || o[i].nScrollHead === nTable || o[i].nScrollFoot === nTable )
  5912. {
  5913. return true;
  5914. }
  5915. }
  5916. return false;
  5917. };
  5918. /**
  5919. * Get all DataTable tables that have been initialised - optionally you can select to
  5920. * get only currently visible tables.
  5921. * @param {boolean} [bVisible=false] Flag to indicate if you want all (default) or
  5922. * visible tables only.
  5923. * @returns {array} Array of TABLE nodes (not DataTable instances) which are DataTables
  5924. * @static
  5925. * @dtopt API-Static
  5926. *
  5927. * @example
  5928. * var table = $.fn.dataTable.fnTables(true);
  5929. * if ( table.length > 0 ) {
  5930. * $(table).dataTable().fnAdjustColumnSizing();
  5931. * }
  5932. */
  5933. DataTable.fnTables = function ( bVisible )
  5934. {
  5935. var out = [];
  5936. jQuery.each( DataTable.settings, function (i, o) {
  5937. if ( !bVisible || (bVisible === true && $(o.nTable).is(':visible')) )
  5938. {
  5939. out.push( o.nTable );
  5940. }
  5941. } );
  5942. return out;
  5943. };
  5944. /**
  5945. * Version string for plug-ins to check compatibility. Allowed format is
  5946. * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and
  5947. * e are optional
  5948. * @member
  5949. * @type string
  5950. * @default Version number
  5951. */
  5952. DataTable.version = "1.9.1";
  5953. /**
  5954. * Private data store, containing all of the settings objects that are created for the
  5955. * tables on a given page.
  5956. *
  5957. * Note that the <i>DataTable.settings</i> object is aliased to <i>jQuery.fn.dataTableExt</i>
  5958. * through which it may be accessed and manipulated, or <i>jQuery.fn.dataTable.settings</i>.
  5959. * @member
  5960. * @type array
  5961. * @default []
  5962. * @private
  5963. */
  5964. DataTable.settings = [];
  5965. /**
  5966. * Object models container, for the various models that DataTables has available
  5967. * to it. These models define the objects that are used to hold the active state
  5968. * and configuration of the table.
  5969. * @namespace
  5970. */
  5971. DataTable.models = {};
  5972. /**
  5973. * DataTables extension options and plug-ins. This namespace acts as a collection "area"
  5974. * for plug-ins that can be used to extend the default DataTables behaviour - indeed many
  5975. * of the build in methods use this method to provide their own capabilities (sorting methods
  5976. * for example).
  5977. *
  5978. * Note that this namespace is aliased to jQuery.fn.dataTableExt so it can be readily accessed
  5979. * and modified by plug-ins.
  5980. * @namespace
  5981. */
  5982. DataTable.models.ext = {
  5983. /**
  5984. * Plug-in filtering functions - this method of filtering is complimentary to the default
  5985. * type based filtering, and a lot more comprehensive as it allows you complete control
  5986. * over the filtering logic. Each element in this array is a function (parameters
  5987. * described below) that is called for every row in the table, and your logic decides if
  5988. * it should be included in the filtered data set or not.
  5989. * <ul>
  5990. * <li>
  5991. * Function input parameters:
  5992. * <ul>
  5993. * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
  5994. * <li>{array|object} Data for the row to be processed (same as the original format
  5995. * that was passed in as the data source, or an array from a DOM data source</li>
  5996. * <li>{int} Row index in aoData ({@link DataTable.models.oSettings.aoData}), which can
  5997. * be useful to retrieve the TR element if you need DOM interaction.</li>
  5998. * </ul>
  5999. * </li>
  6000. * <li>
  6001. * Function return:
  6002. * <ul>
  6003. * <li>{boolean} Include the row in the filtered result set (true) or not (false)</li>
  6004. * </ul>
  6005. * </il>
  6006. * </ul>
  6007. * @type array
  6008. * @default []
  6009. *
  6010. * @example
  6011. * // The following example shows custom filtering being applied to the fourth column (i.e.
  6012. * // the aData[3] index) based on two input values from the end-user, matching the data in
  6013. * // a certain range.
  6014. * $.fn.dataTableExt.afnFiltering.push(
  6015. * function( oSettings, aData, iDataIndex ) {
  6016. * var iMin = document.getElementById('min').value * 1;
  6017. * var iMax = document.getElementById('max').value * 1;
  6018. * var iVersion = aData[3] == "-" ? 0 : aData[3]*1;
  6019. * if ( iMin == "" && iMax == "" ) {
  6020. * return true;
  6021. * }
  6022. * else if ( iMin == "" && iVersion < iMax ) {
  6023. * return true;
  6024. * }
  6025. * else if ( iMin < iVersion && "" == iMax ) {
  6026. * return true;
  6027. * }
  6028. * else if ( iMin < iVersion && iVersion < iMax ) {
  6029. * return true;
  6030. * }
  6031. * return false;
  6032. * }
  6033. * );
  6034. */
  6035. "afnFiltering": [],
  6036. /**
  6037. * Plug-in sorting functions - this method of sorting is complimentary to the default type
  6038. * based sorting that DataTables does automatically, allowing much greater control over the
  6039. * the data that is being used to sort a column. This is useful if you want to do sorting
  6040. * based on live data (for example the contents of an 'input' element) rather than just the
  6041. * static string that DataTables knows of. The way these plug-ins work is that you create
  6042. * an array of the values you wish to be sorted for the column in question and then return
  6043. * that array. Which pre-sorting function is run here depends on the sSortDataType parameter
  6044. * that is used for the column (if any). This is the corollary of <i>ofnSearch</i> for sort
  6045. * data.
  6046. * <ul>
  6047. * <li>
  6048. * Function input parameters:
  6049. * <ul>
  6050. * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
  6051. * <li>{int} Target column index</li>
  6052. * </ul>
  6053. * </li>
  6054. * <li>
  6055. * Function return:
  6056. * <ul>
  6057. * <li>{array} Data for the column to be sorted upon</li>
  6058. * </ul>
  6059. * </il>
  6060. * </ul>
  6061. *
  6062. * Note that as of v1.9, it is typically preferable to use <i>mDataProp</i> to prepare data for
  6063. * the different uses that DataTables can put the data to. Specifically <i>mDataProp</i> when
  6064. * used as a function will give you a 'type' (sorting, filtering etc) that you can use to
  6065. * prepare the data as required for the different types. As such, this method is deprecated.
  6066. * @type array
  6067. * @default []
  6068. * @deprecated
  6069. *
  6070. * @example
  6071. * // Updating the cached sorting information with user entered values in HTML input elements
  6072. * jQuery.fn.dataTableExt.afnSortData['dom-text'] = function ( oSettings, iColumn )
  6073. * {
  6074. * var aData = [];
  6075. * $( 'td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () {
  6076. * aData.push( this.value );
  6077. * } );
  6078. * return aData;
  6079. * }
  6080. */
  6081. "afnSortData": [],
  6082. /**
  6083. * Feature plug-ins - This is an array of objects which describe the feature plug-ins that are
  6084. * available to DataTables. These feature plug-ins are accessible through the sDom initialisation
  6085. * option. As such, each feature plug-in must describe a function that is used to initialise
  6086. * itself (fnInit), a character so the feature can be enabled by sDom (cFeature) and the name
  6087. * of the feature (sFeature). Thus the objects attached to this method must provide:
  6088. * <ul>
  6089. * <li>{function} fnInit Initialisation of the plug-in
  6090. * <ul>
  6091. * <li>
  6092. * Function input parameters:
  6093. * <ul>
  6094. * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
  6095. * </ul>
  6096. * </li>
  6097. * <li>
  6098. * Function return:
  6099. * <ul>
  6100. * <li>{node|null} The element which contains your feature. Note that the return
  6101. * may also be void if your plug-in does not require to inject any DOM elements
  6102. * into DataTables control (sDom) - for example this might be useful when
  6103. * developing a plug-in which allows table control via keyboard entry.</li>
  6104. * </ul>
  6105. * </il>
  6106. * </ul>
  6107. * </li>
  6108. * <li>{character} cFeature Character that will be matched in sDom - case sensitive</li>
  6109. * <li>{string} sFeature Feature name</li>
  6110. * </ul>
  6111. * @type array
  6112. * @default []
  6113. *
  6114. * @example
  6115. * // How TableTools initialises itself.
  6116. * $.fn.dataTableExt.aoFeatures.push( {
  6117. * "fnInit": function( oSettings ) {
  6118. * return new TableTools( { "oDTSettings": oSettings } );
  6119. * },
  6120. * "cFeature": "T",
  6121. * "sFeature": "TableTools"
  6122. * } );
  6123. */
  6124. "aoFeatures": [],
  6125. /**
  6126. * Type detection plug-in functions - DataTables utilises types to define how sorting and
  6127. * filtering behave, and types can be either be defined by the developer (sType for the
  6128. * column) or they can be automatically detected by the methods in this array. The functions
  6129. * defined in the array are quite simple, taking a single parameter (the data to analyse)
  6130. * and returning the type if it is a known type, or null otherwise.
  6131. * <ul>
  6132. * <li>
  6133. * Function input parameters:
  6134. * <ul>
  6135. * <li>{*} Data from the column cell to be analysed</li>
  6136. * </ul>
  6137. * </li>
  6138. * <li>
  6139. * Function return:
  6140. * <ul>
  6141. * <li>{string|null} Data type detected, or null if unknown (and thus pass it
  6142. * on to the other type detection functions.</li>
  6143. * </ul>
  6144. * </il>
  6145. * </ul>
  6146. * @type array
  6147. * @default []
  6148. *
  6149. * @example
  6150. * // Currency type detection plug-in:
  6151. * jQuery.fn.dataTableExt.aTypes.push(
  6152. * function ( sData ) {
  6153. * var sValidChars = "0123456789.-";
  6154. * var Char;
  6155. *
  6156. * // Check the numeric part
  6157. * for ( i=1 ; i<sData.length ; i++ ) {
  6158. * Char = sData.charAt(i);
  6159. * if (sValidChars.indexOf(Char) == -1) {
  6160. * return null;
  6161. * }
  6162. * }
  6163. *
  6164. * // Check prefixed by currency
  6165. * if ( sData.charAt(0) == '$' || sData.charAt(0) == '&pound;' ) {
  6166. * return 'currency';
  6167. * }
  6168. * return null;
  6169. * }
  6170. * );
  6171. */
  6172. "aTypes": [],
  6173. /**
  6174. * Provide a common method for plug-ins to check the version of DataTables being used,
  6175. * in order to ensure compatibility.
  6176. * @type function
  6177. * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note
  6178. * that the formats "X" and "X.Y" are also acceptable.
  6179. * @returns {boolean} true if this version of DataTables is greater or equal to the
  6180. * required version, or false if this version of DataTales is not suitable
  6181. *
  6182. * @example
  6183. * $(document).ready(function() {
  6184. * var oTable = $('#example').dataTable();
  6185. * alert( oTable.fnVersionCheck( '1.9.0' ) );
  6186. * } );
  6187. */
  6188. "fnVersionCheck": DataTable.fnVersionCheck,
  6189. /**
  6190. * Index for what 'this' index API functions should use
  6191. * @type int
  6192. * @default 0
  6193. */
  6194. "iApiIndex": 0,
  6195. /**
  6196. * Pre-processing of filtering data plug-ins - When you assign the sType for a column
  6197. * (or have it automatically detected for you by DataTables or a type detection plug-in),
  6198. * you will typically be using this for custom sorting, but it can also be used to provide
  6199. * custom filtering by allowing you to pre-processing the data and returning the data in
  6200. * the format that should be filtered upon. This is done by adding functions this object
  6201. * with a parameter name which matches the sType for that target column. This is the
  6202. * corollary of <i>afnSortData</i> for filtering data.
  6203. * <ul>
  6204. * <li>
  6205. * Function input parameters:
  6206. * <ul>
  6207. * <li>{*} Data from the column cell to be prepared for filtering</li>
  6208. * </ul>
  6209. * </li>
  6210. * <li>
  6211. * Function return:
  6212. * <ul>
  6213. * <li>{string|null} Formatted string that will be used for the filtering.</li>
  6214. * </ul>
  6215. * </il>
  6216. * </ul>
  6217. *
  6218. * Note that as of v1.9, it is typically preferable to use <i>mDataProp</i> to prepare data for
  6219. * the different uses that DataTables can put the data to. Specifically <i>mDataProp</i> when
  6220. * used as a function will give you a 'type' (sorting, filtering etc) that you can use to
  6221. * prepare the data as required for the different types. As such, this method is deprecated.
  6222. * @type object
  6223. * @default {}
  6224. * @deprecated
  6225. *
  6226. * @example
  6227. * $.fn.dataTableExt.ofnSearch['title-numeric'] = function ( sData ) {
  6228. * return sData.replace(/\n/g," ").replace( /<.*?>/g, "" );
  6229. * }
  6230. */
  6231. "ofnSearch": {},
  6232. /**
  6233. * Container for all private functions in DataTables so they can be exposed externally
  6234. * @type object
  6235. * @default {}
  6236. */
  6237. "oApi": {},
  6238. /**
  6239. * Storage for the various classes that DataTables uses
  6240. * @type object
  6241. * @default {}
  6242. */
  6243. "oStdClasses": {},
  6244. /**
  6245. * Storage for the various classes that DataTables uses - jQuery UI suitable
  6246. * @type object
  6247. * @default {}
  6248. */
  6249. "oJUIClasses": {},
  6250. /**
  6251. * Pagination plug-in methods - The style and controls of the pagination can significantly
  6252. * impact on how the end user interacts with the data in your table, and DataTables allows
  6253. * the addition of pagination controls by extending this object, which can then be enabled
  6254. * through the <i>sPaginationType</i> initialisation parameter. Each pagination type that
  6255. * is added is an object (the property name of which is what <i>sPaginationType</i> refers
  6256. * to) that has two properties, both methods that are used by DataTables to update the
  6257. * control's state.
  6258. * <ul>
  6259. * <li>
  6260. * fnInit - Initialisation of the paging controls. Called only during initialisation
  6261. * of the table. It is expected that this function will add the required DOM elements
  6262. * to the page for the paging controls to work. The element pointer
  6263. * 'oSettings.aanFeatures.p' array is provided by DataTables to contain the paging
  6264. * controls (note that this is a 2D array to allow for multiple instances of each
  6265. * DataTables DOM element). It is suggested that you add the controls to this element
  6266. * as children
  6267. * <ul>
  6268. * <li>
  6269. * Function input parameters:
  6270. * <ul>
  6271. * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
  6272. * <li>{node} Container into which the pagination controls must be inserted</li>
  6273. * <li>{function} Draw callback function - whenever the controls cause a page
  6274. * change, this method must be called to redraw the table.</li>
  6275. * </ul>
  6276. * </li>
  6277. * <li>
  6278. * Function return:
  6279. * <ul>
  6280. * <li>No return required</li>
  6281. * </ul>
  6282. * </il>
  6283. * </ul>
  6284. * </il>
  6285. * <li>
  6286. * fnInit - This function is called whenever the paging status of the table changes and is
  6287. * typically used to update classes and/or text of the paging controls to reflex the new
  6288. * status.
  6289. * <ul>
  6290. * <li>
  6291. * Function input parameters:
  6292. * <ul>
  6293. * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
  6294. * <li>{function} Draw callback function - in case you need to redraw the table again
  6295. * or attach new event listeners</li>
  6296. * </ul>
  6297. * </li>
  6298. * <li>
  6299. * Function return:
  6300. * <ul>
  6301. * <li>No return required</li>
  6302. * </ul>
  6303. * </il>
  6304. * </ul>
  6305. * </il>
  6306. * </ul>
  6307. * @type object
  6308. * @default {}
  6309. *
  6310. * @example
  6311. * $.fn.dataTableExt.oPagination.four_button = {
  6312. * "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) {
  6313. * nFirst = document.createElement( 'span' );
  6314. * nPrevious = document.createElement( 'span' );
  6315. * nNext = document.createElement( 'span' );
  6316. * nLast = document.createElement( 'span' );
  6317. *
  6318. * nFirst.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sFirst ) );
  6319. * nPrevious.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sPrevious ) );
  6320. * nNext.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sNext ) );
  6321. * nLast.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sLast ) );
  6322. *
  6323. * nFirst.className = "paginate_button first";
  6324. * nPrevious.className = "paginate_button previous";
  6325. * nNext.className="paginate_button next";
  6326. * nLast.className = "paginate_button last";
  6327. *
  6328. * nPaging.appendChild( nFirst );
  6329. * nPaging.appendChild( nPrevious );
  6330. * nPaging.appendChild( nNext );
  6331. * nPaging.appendChild( nLast );
  6332. *
  6333. * $(nFirst).click( function () {
  6334. * oSettings.oApi._fnPageChange( oSettings, "first" );
  6335. * fnCallbackDraw( oSettings );
  6336. * } );
  6337. *
  6338. * $(nPrevious).click( function() {
  6339. * oSettings.oApi._fnPageChange( oSettings, "previous" );
  6340. * fnCallbackDraw( oSettings );
  6341. * } );
  6342. *
  6343. * $(nNext).click( function() {
  6344. * oSettings.oApi._fnPageChange( oSettings, "next" );
  6345. * fnCallbackDraw( oSettings );
  6346. * } );
  6347. *
  6348. * $(nLast).click( function() {
  6349. * oSettings.oApi._fnPageChange( oSettings, "last" );
  6350. * fnCallbackDraw( oSettings );
  6351. * } );
  6352. *
  6353. * $(nFirst).bind( 'selectstart', function () { return false; } );
  6354. * $(nPrevious).bind( 'selectstart', function () { return false; } );
  6355. * $(nNext).bind( 'selectstart', function () { return false; } );
  6356. * $(nLast).bind( 'selectstart', function () { return false; } );
  6357. * },
  6358. *
  6359. * "fnUpdate": function ( oSettings, fnCallbackDraw ) {
  6360. * if ( !oSettings.aanFeatures.p ) {
  6361. * return;
  6362. * }
  6363. *
  6364. * // Loop over each instance of the pager
  6365. * var an = oSettings.aanFeatures.p;
  6366. * for ( var i=0, iLen=an.length ; i<iLen ; i++ ) {
  6367. * var buttons = an[i].getElementsByTagName('span');
  6368. * if ( oSettings._iDisplayStart === 0 ) {
  6369. * buttons[0].className = "paginate_disabled_previous";
  6370. * buttons[1].className = "paginate_disabled_previous";
  6371. * }
  6372. * else {
  6373. * buttons[0].className = "paginate_enabled_previous";
  6374. * buttons[1].className = "paginate_enabled_previous";
  6375. * }
  6376. *
  6377. * if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() ) {
  6378. * buttons[2].className = "paginate_disabled_next";
  6379. * buttons[3].className = "paginate_disabled_next";
  6380. * }
  6381. * else {
  6382. * buttons[2].className = "paginate_enabled_next";
  6383. * buttons[3].className = "paginate_enabled_next";
  6384. * }
  6385. * }
  6386. * }
  6387. * };
  6388. */
  6389. "oPagination": {},
  6390. /**
  6391. * Sorting plug-in methods - Sorting in DataTables is based on the detected type of the
  6392. * data column (you can add your own type detection functions, or override automatic
  6393. * detection using sType). With this specific type given to the column, DataTables will
  6394. * apply the required sort from the functions in the object. Each sort type must provide
  6395. * two mandatory methods, one each for ascending and descending sorting, and can optionally
  6396. * provide a pre-formatting method that will help speed up sorting by allowing DataTables
  6397. * to pre-format the sort data only once (rather than every time the actual sort functions
  6398. * are run). The two sorting functions are typical Javascript sort methods:
  6399. * <ul>
  6400. * <li>
  6401. * Function input parameters:
  6402. * <ul>
  6403. * <li>{*} Data to compare to the second parameter</li>
  6404. * <li>{*} Data to compare to the first parameter</li>
  6405. * </ul>
  6406. * </li>
  6407. * <li>
  6408. * Function return:
  6409. * <ul>
  6410. * <li>{int} Sorting match: <0 if first parameter should be sorted lower than
  6411. * the second parameter, ===0 if the two parameters are equal and >0 if
  6412. * the first parameter should be sorted height than the second parameter.</li>
  6413. * </ul>
  6414. * </il>
  6415. * </ul>
  6416. * @type object
  6417. * @default {}
  6418. *
  6419. * @example
  6420. * // Case-sensitive string sorting, with no pre-formatting method
  6421. * $.extend( $.fn.dataTableExt.oSort, {
  6422. * "string-case-asc": function(x,y) {
  6423. * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  6424. * },
  6425. * "string-case-desc": function(x,y) {
  6426. * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  6427. * }
  6428. * } );
  6429. *
  6430. * @example
  6431. * // Case-insensitive string sorting, with pre-formatting
  6432. * $.extend( $.fn.dataTableExt.oSort, {
  6433. * "string-pre": function(x) {
  6434. * return x.toLowerCase();
  6435. * },
  6436. * "string-asc": function(x,y) {
  6437. * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  6438. * },
  6439. * "string-desc": function(x,y) {
  6440. * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  6441. * }
  6442. * } );
  6443. */
  6444. "oSort": {},
  6445. /**
  6446. * Version string for plug-ins to check compatibility. Allowed format is
  6447. * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and
  6448. * e are optional
  6449. * @type string
  6450. * @default Version number
  6451. */
  6452. "sVersion": DataTable.version,
  6453. /**
  6454. * How should DataTables report an error. Can take the value 'alert' or 'throw'
  6455. * @type string
  6456. * @default alert
  6457. */
  6458. "sErrMode": "alert",
  6459. /**
  6460. * Store information for DataTables to access globally about other instances
  6461. * @namespace
  6462. * @private
  6463. */
  6464. "_oExternConfig": {
  6465. /* int:iNextUnique - next unique number for an instance */
  6466. "iNextUnique": 0
  6467. }
  6468. };
  6469. /**
  6470. * Template object for the way in which DataTables holds information about
  6471. * search information for the global filter and individual column filters.
  6472. * @namespace
  6473. */
  6474. DataTable.models.oSearch = {
  6475. /**
  6476. * Flag to indicate if the filtering should be case insensitive or not
  6477. * @type boolean
  6478. * @default true
  6479. */
  6480. "bCaseInsensitive": true,
  6481. /**
  6482. * Applied search term
  6483. * @type string
  6484. * @default <i>Empty string</i>
  6485. */
  6486. "sSearch": "",
  6487. /**
  6488. * Flag to indicate if the search term should be interpreted as a
  6489. * regular expression (true) or not (false) and therefore and special
  6490. * regex characters escaped.
  6491. * @type boolean
  6492. * @default false
  6493. */
  6494. "bRegex": false,
  6495. /**
  6496. * Flag to indicate if DataTables is to use its smart filtering or not.
  6497. * @type boolean
  6498. * @default true
  6499. */
  6500. "bSmart": true
  6501. };
  6502. /**
  6503. * Template object for the way in which DataTables holds information about
  6504. * each individual row. This is the object format used for the settings
  6505. * aoData array.
  6506. * @namespace
  6507. */
  6508. DataTable.models.oRow = {
  6509. /**
  6510. * TR element for the row
  6511. * @type node
  6512. * @default null
  6513. */
  6514. "nTr": null,
  6515. /**
  6516. * Data object from the original data source for the row. This is either
  6517. * an array if using the traditional form of DataTables, or an object if
  6518. * using mDataProp options. The exact type will depend on the passed in
  6519. * data from the data source, or will be an array if using DOM a data
  6520. * source.
  6521. * @type array|object
  6522. * @default []
  6523. */
  6524. "_aData": [],
  6525. /**
  6526. * Sorting data cache - this array is ostensibly the same length as the
  6527. * number of columns (although each index is generated only as it is
  6528. * needed), and holds the data that is used for sorting each column in the
  6529. * row. We do this cache generation at the start of the sort in order that
  6530. * the formatting of the sort data need be done only once for each cell
  6531. * per sort. This array should not be read from or written to by anything
  6532. * other than the master sorting methods.
  6533. * @type array
  6534. * @default []
  6535. * @private
  6536. */
  6537. "_aSortData": [],
  6538. /**
  6539. * Array of TD elements that are cached for hidden rows, so they can be
  6540. * reinserted into the table if a column is made visible again (or to act
  6541. * as a store if a column is made hidden). Only hidden columns have a
  6542. * reference in the array. For non-hidden columns the value is either
  6543. * undefined or null.
  6544. * @type array nodes
  6545. * @default []
  6546. * @private
  6547. */
  6548. "_anHidden": [],
  6549. /**
  6550. * Cache of the class name that DataTables has applied to the row, so we
  6551. * can quickly look at this variable rather than needing to do a DOM check
  6552. * on className for the nTr property.
  6553. * @type string
  6554. * @default <i>Empty string</i>
  6555. * @private
  6556. */
  6557. "_sRowStripe": ""
  6558. };
  6559. /**
  6560. * Template object for the column information object in DataTables. This object
  6561. * is held in the settings aoColumns array and contains all the information that
  6562. * DataTables needs about each individual column.
  6563. *
  6564. * Note that this object is related to {@link DataTable.defaults.columns}
  6565. * but this one is the internal data store for DataTables's cache of columns.
  6566. * It should NOT be manipulated outside of DataTables. Any configuration should
  6567. * be done through the initialisation options.
  6568. * @namespace
  6569. */
  6570. DataTable.models.oColumn = {
  6571. /**
  6572. * A list of the columns that sorting should occur on when this column
  6573. * is sorted. That this property is an array allows multi-column sorting
  6574. * to be defined for a column (for example first name / last name columns
  6575. * would benefit from this). The values are integers pointing to the
  6576. * columns to be sorted on (typically it will be a single integer pointing
  6577. * at itself, but that doesn't need to be the case).
  6578. * @type array
  6579. */
  6580. "aDataSort": null,
  6581. /**
  6582. * Define the sorting directions that are applied to the column, in sequence
  6583. * as the column is repeatedly sorted upon - i.e. the first value is used
  6584. * as the sorting direction when the column if first sorted (clicked on).
  6585. * Sort it again (click again) and it will move on to the next index.
  6586. * Repeat until loop.
  6587. * @type array
  6588. */
  6589. "asSorting": null,
  6590. /**
  6591. * Flag to indicate if the column is searchable, and thus should be included
  6592. * in the filtering or not.
  6593. * @type boolean
  6594. */
  6595. "bSearchable": null,
  6596. /**
  6597. * Flag to indicate if the column is sortable or not.
  6598. * @type boolean
  6599. */
  6600. "bSortable": null,
  6601. /**
  6602. * When using fnRender, you have two options for what to do with the data,
  6603. * and this property serves as the switch. Firstly, you can have the sorting
  6604. * and filtering use the rendered value (true - default), or you can have
  6605. * the sorting and filtering us the original value (false).
  6606. *
  6607. * *NOTE* It is it is advisable now to use mDataProp as a function and make
  6608. * use of the 'type' that it gives, allowing (potentially) different data to
  6609. * be used for sorting, filtering, display and type detection.
  6610. * @type boolean
  6611. * @deprecated
  6612. */
  6613. "bUseRendered": null,
  6614. /**
  6615. * Flag to indicate if the column is currently visible in the table or not
  6616. * @type boolean
  6617. */
  6618. "bVisible": null,
  6619. /**
  6620. * Flag to indicate to the type detection method if the automatic type
  6621. * detection should be used, or if a column type (sType) has been specified
  6622. * @type boolean
  6623. * @default true
  6624. * @private
  6625. */
  6626. "_bAutoType": true,
  6627. /**
  6628. * Developer definable function that is called whenever a cell is created (Ajax source,
  6629. * etc) or processed for input (DOM source). This can be used as a compliment to fnRender
  6630. * allowing you to modify the DOM element (add background colour for example) when the
  6631. * element is available (since it is not when fnRender is called).
  6632. * @type function
  6633. * @param {element} nTd The TD node that has been created
  6634. * @param {*} sData The Data for the cell
  6635. * @param {array|object} oData The data for the whole row
  6636. * @param {int} iRow The row index for the aoData data store
  6637. * @default null
  6638. */
  6639. "fnCreatedCell": null,
  6640. /**
  6641. * Function to get data from a cell in a column. You should <b>never</b>
  6642. * access data directly through _aData internally in DataTables - always use
  6643. * the method attached to this property. It allows mDataProp to function as
  6644. * required. This function is automatically assigned by the column
  6645. * initialisation method
  6646. * @type function
  6647. * @param {array|object} oData The data array/object for the array
  6648. * (i.e. aoData[]._aData)
  6649. * @param {string} sSpecific The specific data type you want to get -
  6650. * 'display', 'type' 'filter' 'sort'
  6651. * @returns {*} The data for the cell from the given row's data
  6652. * @default null
  6653. */
  6654. "fnGetData": null,
  6655. /**
  6656. * Custom display function that will be called for the display of each cell
  6657. * in this column.
  6658. * @type function
  6659. * @param {object} o Object with the following parameters:
  6660. * @param {int} o.iDataRow The row in aoData
  6661. * @param {int} o.iDataColumn The column in question
  6662. * @param {array o.aData The data for the row in question
  6663. * @param {object} o.oSettings The settings object for this DataTables instance
  6664. * @returns {string} The string you which to use in the display
  6665. * @default null
  6666. */
  6667. "fnRender": null,
  6668. /**
  6669. * Function to set data for a cell in the column. You should <b>never</b>
  6670. * set the data directly to _aData internally in DataTables - always use
  6671. * this method. It allows mDataProp to function as required. This function
  6672. * is automatically assigned by the column initialisation method
  6673. * @type function
  6674. * @param {array|object} oData The data array/object for the array
  6675. * (i.e. aoData[]._aData)
  6676. * @param {*} sValue Value to set
  6677. * @default null
  6678. */
  6679. "fnSetData": null,
  6680. /**
  6681. * Property to read the value for the cells in the column from the data
  6682. * source array / object. If null, then the default content is used, if a
  6683. * function is given then the return from the function is used.
  6684. * @type function|int|string|null
  6685. * @default null
  6686. */
  6687. "mDataProp": null,
  6688. /**
  6689. * Unique header TH/TD element for this column - this is what the sorting
  6690. * listener is attached to (if sorting is enabled.)
  6691. * @type node
  6692. * @default null
  6693. */
  6694. "nTh": null,
  6695. /**
  6696. * Unique footer TH/TD element for this column (if there is one). Not used
  6697. * in DataTables as such, but can be used for plug-ins to reference the
  6698. * footer for each column.
  6699. * @type node
  6700. * @default null
  6701. */
  6702. "nTf": null,
  6703. /**
  6704. * The class to apply to all TD elements in the table's TBODY for the column
  6705. * @type string
  6706. * @default null
  6707. */
  6708. "sClass": null,
  6709. /**
  6710. * When DataTables calculates the column widths to assign to each column,
  6711. * it finds the longest string in each column and then constructs a
  6712. * temporary table and reads the widths from that. The problem with this
  6713. * is that "mmm" is much wider then "iiii", but the latter is a longer
  6714. * string - thus the calculation can go wrong (doing it properly and putting
  6715. * it into an DOM object and measuring that is horribly(!) slow). Thus as
  6716. * a "work around" we provide this option. It will append its value to the
  6717. * text that is found to be the longest string for the column - i.e. padding.
  6718. * @type string
  6719. */
  6720. "sContentPadding": null,
  6721. /**
  6722. * Allows a default value to be given for a column's data, and will be used
  6723. * whenever a null data source is encountered (this can be because mDataProp
  6724. * is set to null, or because the data source itself is null).
  6725. * @type string
  6726. * @default null
  6727. */
  6728. "sDefaultContent": null,
  6729. /**
  6730. * Name for the column, allowing reference to the column by name as well as
  6731. * by index (needs a lookup to work by name).
  6732. * @type string
  6733. */
  6734. "sName": null,
  6735. /**
  6736. * Custom sorting data type - defines which of the available plug-ins in
  6737. * afnSortData the custom sorting will use - if any is defined.
  6738. * @type string
  6739. * @default std
  6740. */
  6741. "sSortDataType": 'std',
  6742. /**
  6743. * Class to be applied to the header element when sorting on this column
  6744. * @type string
  6745. * @default null
  6746. */
  6747. "sSortingClass": null,
  6748. /**
  6749. * Class to be applied to the header element when sorting on this column -
  6750. * when jQuery UI theming is used.
  6751. * @type string
  6752. * @default null
  6753. */
  6754. "sSortingClassJUI": null,
  6755. /**
  6756. * Title of the column - what is seen in the TH element (nTh).
  6757. * @type string
  6758. */
  6759. "sTitle": null,
  6760. /**
  6761. * Column sorting and filtering type
  6762. * @type string
  6763. * @default null
  6764. */
  6765. "sType": null,
  6766. /**
  6767. * Width of the column
  6768. * @type string
  6769. * @default null
  6770. */
  6771. "sWidth": null,
  6772. /**
  6773. * Width of the column when it was first "encountered"
  6774. * @type string
  6775. * @default null
  6776. */
  6777. "sWidthOrig": null
  6778. };
  6779. /**
  6780. * Initialisation options that can be given to DataTables at initialisation
  6781. * time.
  6782. * @namespace
  6783. */
  6784. DataTable.defaults = {
  6785. /**
  6786. * An array of data to use for the table, passed in at initialisation which
  6787. * will be used in preference to any data which is already in the DOM. This is
  6788. * particularly useful for constructing tables purely in Javascript, for
  6789. * example with a custom Ajax call.
  6790. * @type array
  6791. * @default null
  6792. * @dtopt Option
  6793. *
  6794. * @example
  6795. * // Using a 2D array data source
  6796. * $(document).ready( function () {
  6797. * $('#example').dataTable( {
  6798. * "aaData": [
  6799. * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
  6800. * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
  6801. * ],
  6802. * "aoColumns": [
  6803. * { "sTitle": "Engine" },
  6804. * { "sTitle": "Browser" },
  6805. * { "sTitle": "Platform" },
  6806. * { "sTitle": "Version" },
  6807. * { "sTitle": "Grade" }
  6808. * ]
  6809. * } );
  6810. * } );
  6811. *
  6812. * @example
  6813. * // Using an array of objects as a data source (mDataProp)
  6814. * $(document).ready( function () {
  6815. * $('#example').dataTable( {
  6816. * "aaData": [
  6817. * {
  6818. * "engine": "Trident",
  6819. * "browser": "Internet Explorer 4.0",
  6820. * "platform": "Win 95+",
  6821. * "version": 4,
  6822. * "grade": "X"
  6823. * },
  6824. * {
  6825. * "engine": "Trident",
  6826. * "browser": "Internet Explorer 5.0",
  6827. * "platform": "Win 95+",
  6828. * "version": 5,
  6829. * "grade": "C"
  6830. * }
  6831. * ],
  6832. * "aoColumns": [
  6833. * { "sTitle": "Engine", "mDataProp": "engine" },
  6834. * { "sTitle": "Browser", "mDataProp": "browser" },
  6835. * { "sTitle": "Platform", "mDataProp": "platform" },
  6836. * { "sTitle": "Version", "mDataProp": "version" },
  6837. * { "sTitle": "Grade", "mDataProp": "grade" }
  6838. * ]
  6839. * } );
  6840. * } );
  6841. */
  6842. "aaData": null,
  6843. /**
  6844. * If sorting is enabled, then DataTables will perform a first pass sort on
  6845. * initialisation. You can define which column(s) the sort is performed upon,
  6846. * and the sorting direction, with this variable. The aaSorting array should
  6847. * contain an array for each column to be sorted initially containing the
  6848. * column's index and a direction string ('asc' or 'desc').
  6849. * @type array
  6850. * @default [[0,'asc']]
  6851. * @dtopt Option
  6852. *
  6853. * @example
  6854. * // Sort by 3rd column first, and then 4th column
  6855. * $(document).ready( function() {
  6856. * $('#example').dataTable( {
  6857. * "aaSorting": [[2,'asc'], [3,'desc']]
  6858. * } );
  6859. * } );
  6860. *
  6861. * // No initial sorting
  6862. * $(document).ready( function() {
  6863. * $('#example').dataTable( {
  6864. * "aaSorting": []
  6865. * } );
  6866. * } );
  6867. */
  6868. "aaSorting": [[0,'asc']],
  6869. /**
  6870. * This parameter is basically identical to the aaSorting parameter, but
  6871. * cannot be overridden by user interaction with the table. What this means
  6872. * is that you could have a column (visible or hidden) which the sorting will
  6873. * always be forced on first - any sorting after that (from the user) will
  6874. * then be performed as required. This can be useful for grouping rows
  6875. * together.
  6876. * @type array
  6877. * @default null
  6878. * @dtopt Option
  6879. *
  6880. * @example
  6881. * $(document).ready( function() {
  6882. * $('#example').dataTable( {
  6883. * "aaSortingFixed": [[0,'asc']]
  6884. * } );
  6885. * } )
  6886. */
  6887. "aaSortingFixed": null,
  6888. /**
  6889. * This parameter allows you to readily specify the entries in the length drop
  6890. * down menu that DataTables shows when pagination is enabled. It can be
  6891. * either a 1D array of options which will be used for both the displayed
  6892. * option and the value, or a 2D array which will use the array in the first
  6893. * position as the value, and the array in the second position as the
  6894. * displayed options (useful for language strings such as 'All').
  6895. * @type array
  6896. * @default [ 10, 25, 50, 100 ]
  6897. * @dtopt Option
  6898. *
  6899. * @example
  6900. * $(document).ready(function() {
  6901. * $('#example').dataTable( {
  6902. * "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
  6903. * } );
  6904. * } );
  6905. *
  6906. * @example
  6907. * // Setting the default display length as well as length menu
  6908. * // This is likely to be wanted if you remove the '10' option which
  6909. * // is the iDisplayLength default.
  6910. * $(document).ready(function() {
  6911. * $('#example').dataTable( {
  6912. * "iDisplayLength": 25,
  6913. * "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]]
  6914. * } );
  6915. * } );
  6916. */
  6917. "aLengthMenu": [ 10, 25, 50, 100 ],
  6918. /**
  6919. * The aoColumns option in the initialisation parameter allows you to define
  6920. * details about the way individual columns behave. For a full list of
  6921. * column options that can be set, please see
  6922. * {@link DataTable.defaults.columns}. Note that if you use aoColumns to
  6923. * define your columns, you must have an entry in the array for every single
  6924. * column that you have in your table (these can be null if you don't which
  6925. * to specify any options).
  6926. * @member
  6927. */
  6928. "aoColumns": null,
  6929. /**
  6930. * Very similar to aoColumns, aoColumnDefs allows you to target a specific
  6931. * column, multiple columns, or all columns, using the aTargets property of
  6932. * each object in the array. This allows great flexibility when creating
  6933. * tables, as the aoColumnDefs arrays can be of any length, targeting the
  6934. * columns you specifically want. aoColumnDefs may use any of the column
  6935. * options available: {@link DataTable.defaults.columns}, but it _must_
  6936. * have aTargets defined in each object in the array. Values in the aTargets
  6937. * array may be:
  6938. * <ul>
  6939. * <li>a string - class name will be matched on the TH for the column</li>
  6940. * <li>0 or a positive integer - column index counting from the left</li>
  6941. * <li>a negative integer - column index counting from the right</li>
  6942. * <li>the string "_all" - all columns (i.e. assign a default)</li>
  6943. * </ul>
  6944. * @member
  6945. */
  6946. "aoColumnDefs": null,
  6947. /**
  6948. * Basically the same as oSearch, this parameter defines the individual column
  6949. * filtering state at initialisation time. The array must be of the same size
  6950. * as the number of columns, and each element be an object with the parameters
  6951. * "sSearch" and "bEscapeRegex" (the latter is optional). 'null' is also
  6952. * accepted and the default will be used.
  6953. * @type array
  6954. * @default []
  6955. * @dtopt Option
  6956. *
  6957. * @example
  6958. * $(document).ready( function() {
  6959. * $('#example').dataTable( {
  6960. * "aoSearchCols": [
  6961. * null,
  6962. * { "sSearch": "My filter" },
  6963. * null,
  6964. * { "sSearch": "^[0-9]", "bEscapeRegex": false }
  6965. * ]
  6966. * } );
  6967. * } )
  6968. */
  6969. "aoSearchCols": [],
  6970. /**
  6971. * An array of CSS classes that should be applied to displayed rows. This
  6972. * array may be of any length, and DataTables will apply each class
  6973. * sequentially, looping when required.
  6974. * @type array
  6975. * @default null <i>Will take the values determinted by the oClasses.sStripe*
  6976. * options</i>
  6977. * @dtopt Option
  6978. *
  6979. * @example
  6980. * $(document).ready( function() {
  6981. * $('#example').dataTable( {
  6982. * "asStripeClasses": [ 'strip1', 'strip2', 'strip3' ]
  6983. * } );
  6984. * } )
  6985. */
  6986. "asStripeClasses": null,
  6987. /**
  6988. * Enable or disable automatic column width calculation. This can be disabled
  6989. * as an optimisation (it takes some time to calculate the widths) if the
  6990. * tables widths are passed in using aoColumns.
  6991. * @type boolean
  6992. * @default true
  6993. * @dtopt Features
  6994. *
  6995. * @example
  6996. * $(document).ready( function () {
  6997. * $('#example').dataTable( {
  6998. * "bAutoWidth": false
  6999. * } );
  7000. * } );
  7001. */
  7002. "bAutoWidth": true,
  7003. /**
  7004. * Deferred rendering can provide DataTables with a huge speed boost when you
  7005. * are using an Ajax or JS data source for the table. This option, when set to
  7006. * true, will cause DataTables to defer the creation of the table elements for
  7007. * each row until they are needed for a draw - saving a significant amount of
  7008. * time.
  7009. * @type boolean
  7010. * @default false
  7011. * @dtopt Features
  7012. *
  7013. * @example
  7014. * $(document).ready(function() {
  7015. * var oTable = $('#example').dataTable( {
  7016. * "sAjaxSource": "sources/arrays.txt",
  7017. * "bDeferRender": true
  7018. * } );
  7019. * } );
  7020. */
  7021. "bDeferRender": false,
  7022. /**
  7023. * Replace a DataTable which matches the given selector and replace it with
  7024. * one which has the properties of the new initialisation object passed. If no
  7025. * table matches the selector, then the new DataTable will be constructed as
  7026. * per normal.
  7027. * @type boolean
  7028. * @default false
  7029. * @dtopt Options
  7030. *
  7031. * @example
  7032. * $(document).ready(function() {
  7033. * $('#example').dataTable( {
  7034. * "sScrollY": "200px",
  7035. * "bPaginate": false
  7036. * } );
  7037. *
  7038. * // Some time later....
  7039. * $('#example').dataTable( {
  7040. * "bFilter": false,
  7041. * "bDestroy": true
  7042. * } );
  7043. * } );
  7044. */
  7045. "bDestroy": false,
  7046. /**
  7047. * Enable or disable filtering of data. Filtering in DataTables is "smart" in
  7048. * that it allows the end user to input multiple words (space separated) and
  7049. * will match a row containing those words, even if not in the order that was
  7050. * specified (this allow matching across multiple columns). Note that if you
  7051. * wish to use filtering in DataTables this must remain 'true' - to remove the
  7052. * default filtering input box and retain filtering abilities, please use
  7053. * {@link DataTable.defaults.sDom}.
  7054. * @type boolean
  7055. * @default true
  7056. * @dtopt Features
  7057. *
  7058. * @example
  7059. * $(document).ready( function () {
  7060. * $('#example').dataTable( {
  7061. * "bFilter": false
  7062. * } );
  7063. * } );
  7064. */
  7065. "bFilter": true,
  7066. /**
  7067. * Enable or disable the table information display. This shows information
  7068. * about the data that is currently visible on the page, including information
  7069. * about filtered data if that action is being performed.
  7070. * @type boolean
  7071. * @default true
  7072. * @dtopt Features
  7073. *
  7074. * @example
  7075. * $(document).ready( function () {
  7076. * $('#example').dataTable( {
  7077. * "bInfo": false
  7078. * } );
  7079. * } );
  7080. */
  7081. "bInfo": true,
  7082. /**
  7083. * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
  7084. * slightly different and additional mark-up from what DataTables has
  7085. * traditionally used).
  7086. * @type boolean
  7087. * @default false
  7088. * @dtopt Features
  7089. *
  7090. * @example
  7091. * $(document).ready( function() {
  7092. * $('#example').dataTable( {
  7093. * "bJQueryUI": true
  7094. * } );
  7095. * } );
  7096. */
  7097. "bJQueryUI": false,
  7098. /**
  7099. * Allows the end user to select the size of a formatted page from a select
  7100. * menu (sizes are 10, 25, 50 and 100). Requires pagination (bPaginate).
  7101. * @type boolean
  7102. * @default true
  7103. * @dtopt Features
  7104. *
  7105. * @example
  7106. * $(document).ready( function () {
  7107. * $('#example').dataTable( {
  7108. * "bLengthChange": false
  7109. * } );
  7110. * } );
  7111. */
  7112. "bLengthChange": true,
  7113. /**
  7114. * Enable or disable pagination.
  7115. * @type boolean
  7116. * @default true
  7117. * @dtopt Features
  7118. *
  7119. * @example
  7120. * $(document).ready( function () {
  7121. * $('#example').dataTable( {
  7122. * "bPaginate": false
  7123. * } );
  7124. * } );
  7125. */
  7126. "bPaginate": true,
  7127. /**
  7128. * Enable or disable the display of a 'processing' indicator when the table is
  7129. * being processed (e.g. a sort). This is particularly useful for tables with
  7130. * large amounts of data where it can take a noticeable amount of time to sort
  7131. * the entries.
  7132. * @type boolean
  7133. * @default false
  7134. * @dtopt Features
  7135. *
  7136. * @example
  7137. * $(document).ready( function () {
  7138. * $('#example').dataTable( {
  7139. * "bProcessing": true
  7140. * } );
  7141. * } );
  7142. */
  7143. "bProcessing": false,
  7144. /**
  7145. * Retrieve the DataTables object for the given selector. Note that if the
  7146. * table has already been initialised, this parameter will cause DataTables
  7147. * to simply return the object that has already been set up - it will not take
  7148. * account of any changes you might have made to the initialisation object
  7149. * passed to DataTables (setting this parameter to true is an acknowledgement
  7150. * that you understand this). bDestroy can be used to reinitialise a table if
  7151. * you need.
  7152. * @type boolean
  7153. * @default false
  7154. * @dtopt Options
  7155. *
  7156. * @example
  7157. * $(document).ready(function() {
  7158. * initTable();
  7159. * tableActions();
  7160. * } );
  7161. *
  7162. * function initTable ()
  7163. * {
  7164. * return $('#example').dataTable( {
  7165. * "sScrollY": "200px",
  7166. * "bPaginate": false,
  7167. * "bRetrieve": true
  7168. * } );
  7169. * }
  7170. *
  7171. * function tableActions ()
  7172. * {
  7173. * var oTable = initTable();
  7174. * // perform API operations with oTable
  7175. * }
  7176. */
  7177. "bRetrieve": false,
  7178. /**
  7179. * Indicate if DataTables should be allowed to set the padding / margin
  7180. * etc for the scrolling header elements or not. Typically you will want
  7181. * this.
  7182. * @type boolean
  7183. * @default true
  7184. * @dtopt Options
  7185. *
  7186. * @example
  7187. * $(document).ready(function() {
  7188. * $('#example').dataTable( {
  7189. * "bScrollAutoCss": false,
  7190. * "sScrollY": "200px"
  7191. * } );
  7192. * } );
  7193. */
  7194. "bScrollAutoCss": true,
  7195. /**
  7196. * When vertical (y) scrolling is enabled, DataTables will force the height of
  7197. * the table's viewport to the given height at all times (useful for layout).
  7198. * However, this can look odd when filtering data down to a small data set,
  7199. * and the footer is left "floating" further down. This parameter (when
  7200. * enabled) will cause DataTables to collapse the table's viewport down when
  7201. * the result set will fit within the given Y height.
  7202. * @type boolean
  7203. * @default false
  7204. * @dtopt Options
  7205. *
  7206. * @example
  7207. * $(document).ready(function() {
  7208. * $('#example').dataTable( {
  7209. * "sScrollY": "200",
  7210. * "bScrollCollapse": true
  7211. * } );
  7212. * } );
  7213. */
  7214. "bScrollCollapse": false,
  7215. /**
  7216. * Enable infinite scrolling for DataTables (to be used in combination with
  7217. * sScrollY). Infinite scrolling means that DataTables will continually load
  7218. * data as a user scrolls through a table, which is very useful for large
  7219. * dataset. This cannot be used with pagination, which is automatically
  7220. * disabled. Note - the Scroller extra for DataTables is recommended in
  7221. * in preference to this option.
  7222. * @type boolean
  7223. * @default false
  7224. * @dtopt Features
  7225. *
  7226. * @example
  7227. * $(document).ready(function() {
  7228. * $('#example').dataTable( {
  7229. * "bScrollInfinite": true,
  7230. * "bScrollCollapse": true,
  7231. * "sScrollY": "200px"
  7232. * } );
  7233. * } );
  7234. */
  7235. "bScrollInfinite": false,
  7236. /**
  7237. * Configure DataTables to use server-side processing. Note that the
  7238. * sAjaxSource parameter must also be given in order to give DataTables a
  7239. * source to obtain the required data for each draw.
  7240. * @type boolean
  7241. * @default false
  7242. * @dtopt Features
  7243. * @dtopt Server-side
  7244. *
  7245. * @example
  7246. * $(document).ready( function () {
  7247. * $('#example').dataTable( {
  7248. * "bServerSide": true,
  7249. * "sAjaxSource": "xhr.php"
  7250. * } );
  7251. * } );
  7252. */
  7253. "bServerSide": false,
  7254. /**
  7255. * Enable or disable sorting of columns. Sorting of individual columns can be
  7256. * disabled by the "bSortable" option for each column.
  7257. * @type boolean
  7258. * @default true
  7259. * @dtopt Features
  7260. *
  7261. * @example
  7262. * $(document).ready( function () {
  7263. * $('#example').dataTable( {
  7264. * "bSort": false
  7265. * } );
  7266. * } );
  7267. */
  7268. "bSort": true,
  7269. /**
  7270. * Allows control over whether DataTables should use the top (true) unique
  7271. * cell that is found for a single column, or the bottom (false - default).
  7272. * This is useful when using complex headers.
  7273. * @type boolean
  7274. * @default false
  7275. * @dtopt Options
  7276. *
  7277. * @example
  7278. * $(document).ready(function() {
  7279. * $('#example').dataTable( {
  7280. * "bSortCellsTop": true
  7281. * } );
  7282. * } );
  7283. */
  7284. "bSortCellsTop": false,
  7285. /**
  7286. * Enable or disable the addition of the classes 'sorting_1', 'sorting_2' and
  7287. * 'sorting_3' to the columns which are currently being sorted on. This is
  7288. * presented as a feature switch as it can increase processing time (while
  7289. * classes are removed and added) so for large data sets you might want to
  7290. * turn this off.
  7291. * @type boolean
  7292. * @default true
  7293. * @dtopt Features
  7294. *
  7295. * @example
  7296. * $(document).ready( function () {
  7297. * $('#example').dataTable( {
  7298. * "bSortClasses": false
  7299. * } );
  7300. * } );
  7301. */
  7302. "bSortClasses": true,
  7303. /**
  7304. * Enable or disable state saving. When enabled a cookie will be used to save
  7305. * table display information such as pagination information, display length,
  7306. * filtering and sorting. As such when the end user reloads the page the
  7307. * display display will match what thy had previously set up.
  7308. * @type boolean
  7309. * @default false
  7310. * @dtopt Features
  7311. *
  7312. * @example
  7313. * $(document).ready( function () {
  7314. * $('#example').dataTable( {
  7315. * "bStateSave": true
  7316. * } );
  7317. * } );
  7318. */
  7319. "bStateSave": false,
  7320. /**
  7321. * Customise the cookie and / or the parameters being stored when using
  7322. * DataTables with state saving enabled. This function is called whenever
  7323. * the cookie is modified, and it expects a fully formed cookie string to be
  7324. * returned. Note that the data object passed in is a Javascript object which
  7325. * must be converted to a string (JSON.stringify for example).
  7326. * @type function
  7327. * @param {string} sName Name of the cookie defined by DataTables
  7328. * @param {object} oData Data to be stored in the cookie
  7329. * @param {string} sExpires Cookie expires string
  7330. * @param {string} sPath Path of the cookie to set
  7331. * @returns {string} Cookie formatted string (which should be encoded by
  7332. * using encodeURIComponent())
  7333. * @dtopt Callbacks
  7334. *
  7335. * @example
  7336. * $(document).ready( function () {
  7337. * $('#example').dataTable( {
  7338. * "fnCookieCallback": function (sName, oData, sExpires, sPath) {
  7339. * // Customise oData or sName or whatever else here
  7340. * return sName + "="+JSON.stringify(oData)+"; expires=" + sExpires +"; path=" + sPath;
  7341. * }
  7342. * } );
  7343. * } );
  7344. */
  7345. "fnCookieCallback": null,
  7346. /**
  7347. * This function is called when a TR element is created (and all TD child
  7348. * elements have been inserted), or registered if using a DOM source, allowing
  7349. * manipulation of the TR element (adding classes etc).
  7350. * @type function
  7351. * @param {node} nRow "TR" element for the current row
  7352. * @param {array} aData Raw data array for this row
  7353. * @param {int} iDataIndex The index of this row in aoData
  7354. * @dtopt Callbacks
  7355. *
  7356. * @example
  7357. * $(document).ready(function() {
  7358. * $('#example').dataTable( {
  7359. * "fnCreatedRow": function( nRow, aData, iDataIndex ) {
  7360. * // Bold the grade for all 'A' grade browsers
  7361. * if ( aData[4] == "A" )
  7362. * {
  7363. * $('td:eq(4)', nRow).html( '<b>A</b>' );
  7364. * }
  7365. * }
  7366. * } );
  7367. * } );
  7368. */
  7369. "fnCreatedRow": null,
  7370. /**
  7371. * This function is called on every 'draw' event, and allows you to
  7372. * dynamically modify any aspect you want about the created DOM.
  7373. * @type function
  7374. * @param {object} oSettings DataTables settings object
  7375. * @dtopt Callbacks
  7376. *
  7377. * @example
  7378. * $(document).ready( function() {
  7379. * $('#example').dataTable( {
  7380. * "fnDrawCallback": function( oSettings ) {
  7381. * alert( 'DataTables has redrawn the table' );
  7382. * }
  7383. * } );
  7384. * } );
  7385. */
  7386. "fnDrawCallback": null,
  7387. /**
  7388. * Identical to fnHeaderCallback() but for the table footer this function
  7389. * allows you to modify the table footer on every 'draw' even.
  7390. * @type function
  7391. * @param {node} nFoot "TR" element for the footer
  7392. * @param {array} aData Full table data (as derived from the original HTML)
  7393. * @param {int} iStart Index for the current display starting point in the
  7394. * display array
  7395. * @param {int} iEnd Index for the current display ending point in the
  7396. * display array
  7397. * @param {array int} aiDisplay Index array to translate the visual position
  7398. * to the full data array
  7399. * @dtopt Callbacks
  7400. *
  7401. * @example
  7402. * $(document).ready( function() {
  7403. * $('#example').dataTable( {
  7404. * "fnFooterCallback": function( nFoot, aData, iStart, iEnd, aiDisplay ) {
  7405. * nFoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+iStart;
  7406. * }
  7407. * } );
  7408. * } )
  7409. */
  7410. "fnFooterCallback": null,
  7411. /**
  7412. * When rendering large numbers in the information element for the table
  7413. * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
  7414. * to have a comma separator for the 'thousands' units (e.g. 1 million is
  7415. * rendered as "1,000,000") to help readability for the end user. This
  7416. * function will override the default method DataTables uses.
  7417. * @type function
  7418. * @member
  7419. * @param {int} iIn number to be formatted
  7420. * @returns {string} formatted string for DataTables to show the number
  7421. * @dtopt Callbacks
  7422. *
  7423. * @example
  7424. * $(document).ready(function() {
  7425. * $('#example').dataTable( {
  7426. * "fnFormatNumber": function ( iIn ) {
  7427. * if ( iIn &lt; 1000 ) {
  7428. * return iIn;
  7429. * } else {
  7430. * var
  7431. * s=(iIn+""),
  7432. * a=s.split(""), out="",
  7433. * iLen=s.length;
  7434. *
  7435. * for ( var i=0 ; i&lt;iLen ; i++ ) {
  7436. * if ( i%3 === 0 &amp;&amp; i !== 0 ) {
  7437. * out = "'"+out;
  7438. * }
  7439. * out = a[iLen-i-1]+out;
  7440. * }
  7441. * }
  7442. * return out;
  7443. * };
  7444. * } );
  7445. * } );
  7446. */
  7447. "fnFormatNumber": function ( iIn ) {
  7448. if ( iIn < 1000 )
  7449. {
  7450. // A small optimisation for what is likely to be the majority of use cases
  7451. return iIn;
  7452. }
  7453. var s=(iIn+""), a=s.split(""), out="", iLen=s.length;
  7454. for ( var i=0 ; i<iLen ; i++ )
  7455. {
  7456. if ( i%3 === 0 && i !== 0 )
  7457. {
  7458. out = this.oLanguage.sInfoThousands+out;
  7459. }
  7460. out = a[iLen-i-1]+out;
  7461. }
  7462. return out;
  7463. },
  7464. /**
  7465. * This function is called on every 'draw' event, and allows you to
  7466. * dynamically modify the header row. This can be used to calculate and
  7467. * display useful information about the table.
  7468. * @type function
  7469. * @param {node} nHead "TR" element for the header
  7470. * @param {array} aData Full table data (as derived from the original HTML)
  7471. * @param {int} iStart Index for the current display starting point in the
  7472. * display array
  7473. * @param {int} iEnd Index for the current display ending point in the
  7474. * display array
  7475. * @param {array int} aiDisplay Index array to translate the visual position
  7476. * to the full data array
  7477. * @dtopt Callbacks
  7478. *
  7479. * @example
  7480. * $(document).ready( function() {
  7481. * $('#example').dataTable( {
  7482. * "fnHeaderCallback": function( nHead, aData, iStart, iEnd, aiDisplay ) {
  7483. * nHead.getElementsByTagName('th')[0].innerHTML = "Displaying "+(iEnd-iStart)+" records";
  7484. * }
  7485. * } );
  7486. * } )
  7487. */
  7488. "fnHeaderCallback": null,
  7489. /**
  7490. * The information element can be used to convey information about the current
  7491. * state of the table. Although the internationalisation options presented by
  7492. * DataTables are quite capable of dealing with most customisations, there may
  7493. * be times where you wish to customise the string further. This callback
  7494. * allows you to do exactly that.
  7495. * @type function
  7496. * @param {object} oSettings DataTables settings object
  7497. * @param {int} iStart Starting position in data for the draw
  7498. * @param {int} iEnd End position in data for the draw
  7499. * @param {int} iMax Total number of rows in the table (regardless of
  7500. * filtering)
  7501. * @param {int} iTotal Total number of rows in the data set, after filtering
  7502. * @param {string} sPre The string that DataTables has formatted using it's
  7503. * own rules
  7504. * @returns {string} The string to be displayed in the information element.
  7505. * @dtopt Callbacks
  7506. *
  7507. * @example
  7508. * $('#example').dataTable( {
  7509. * "fnInfoCallback": function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
  7510. * return iStart +" to "+ iEnd;
  7511. * }
  7512. * } );
  7513. */
  7514. "fnInfoCallback": null,
  7515. /**
  7516. * Called when the table has been initialised. Normally DataTables will
  7517. * initialise sequentially and there will be no need for this function,
  7518. * however, this does not hold true when using external language information
  7519. * since that is obtained using an async XHR call.
  7520. * @type function
  7521. * @param {object} oSettings DataTables settings object
  7522. * @param {object} json The JSON object request from the server - only
  7523. * present if client-side Ajax sourced data is used
  7524. * @dtopt Callbacks
  7525. *
  7526. * @example
  7527. * $(document).ready( function() {
  7528. * $('#example').dataTable( {
  7529. * "fnInitComplete": function(oSettings, json) {
  7530. * alert( 'DataTables has finished its initialisation.' );
  7531. * }
  7532. * } );
  7533. * } )
  7534. */
  7535. "fnInitComplete": null,
  7536. /**
  7537. * Called at the very start of each table draw and can be used to cancel the
  7538. * draw by returning false, any other return (including undefined) results in
  7539. * the full draw occurring).
  7540. * @type function
  7541. * @param {object} oSettings DataTables settings object
  7542. * @returns {boolean} False will cancel the draw, anything else (including no
  7543. * return) will allow it to complete.
  7544. * @dtopt Callbacks
  7545. *
  7546. * @example
  7547. * $(document).ready( function() {
  7548. * $('#example').dataTable( {
  7549. * "fnPreDrawCallback": function( oSettings ) {
  7550. * if ( $('#test').val() == 1 ) {
  7551. * return false;
  7552. * }
  7553. * }
  7554. * } );
  7555. * } );
  7556. */
  7557. "fnPreDrawCallback": null,
  7558. /**
  7559. * This function allows you to 'post process' each row after it have been
  7560. * generated for each table draw, but before it is rendered on screen. This
  7561. * function might be used for setting the row class name etc.
  7562. * @type function
  7563. * @param {node} nRow "TR" element for the current row
  7564. * @param {array} aData Raw data array for this row
  7565. * @param {int} iDisplayIndex The display index for the current table draw
  7566. * @param {int} iDisplayIndexFull The index of the data in the full list of
  7567. * rows (after filtering)
  7568. * @dtopt Callbacks
  7569. *
  7570. * @example
  7571. * $(document).ready(function() {
  7572. * $('#example').dataTable( {
  7573. * "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
  7574. * // Bold the grade for all 'A' grade browsers
  7575. * if ( aData[4] == "A" )
  7576. * {
  7577. * $('td:eq(4)', nRow).html( '<b>A</b>' );
  7578. * }
  7579. * }
  7580. * } );
  7581. * } );
  7582. */
  7583. "fnRowCallback": null,
  7584. /**
  7585. * This parameter allows you to override the default function which obtains
  7586. * the data from the server ($.getJSON) so something more suitable for your
  7587. * application. For example you could use POST data, or pull information from
  7588. * a Gears or AIR database.
  7589. * @type function
  7590. * @member
  7591. * @param {string} sSource HTTP source to obtain the data from (sAjaxSource)
  7592. * @param {array} aoData A key/value pair object containing the data to send
  7593. * to the server
  7594. * @param {function} fnCallback to be called on completion of the data get
  7595. * process that will draw the data on the page.
  7596. * @param {object} oSettings DataTables settings object
  7597. * @dtopt Callbacks
  7598. * @dtopt Server-side
  7599. *
  7600. * @example
  7601. * // POST data to server
  7602. * $(document).ready(function() {
  7603. * $('#example').dataTable( {
  7604. * "bProcessing": true,
  7605. * "bServerSide": true,
  7606. * "sAjaxSource": "xhr.php",
  7607. * "fnServerData": function ( sSource, aoData, fnCallback ) {
  7608. * $.ajax( {
  7609. * "dataType": 'json',
  7610. * "type": "POST",
  7611. * "url": sSource,
  7612. * "data": aoData,
  7613. * "success": fnCallback
  7614. * } );
  7615. * }
  7616. * } );
  7617. * } );
  7618. */
  7619. "fnServerData": function ( sUrl, aoData, fnCallback, oSettings ) {
  7620. oSettings.jqXHR = $.ajax( {
  7621. "url": sUrl,
  7622. "data": aoData,
  7623. "success": function (json) {
  7624. $(oSettings.oInstance).trigger('xhr', oSettings);
  7625. fnCallback( json );
  7626. },
  7627. "dataType": "json",
  7628. "cache": false,
  7629. "type": oSettings.sServerMethod,
  7630. "error": function (xhr, error, thrown) {
  7631. if ( error == "parsererror" ) {
  7632. oSettings.oApi._fnLog( oSettings, 0, "DataTables warning: JSON data from "+
  7633. "server could not be parsed. This is caused by a JSON formatting error." );
  7634. }
  7635. }
  7636. } );
  7637. },
  7638. /**
  7639. * It is often useful to send extra data to the server when making an Ajax
  7640. * request - for example custom filtering information, and this callback
  7641. * function makes it trivial to send extra information to the server. The
  7642. * passed in parameter is the data set that has been constructed by
  7643. * DataTables, and you can add to this or modify it as you require.
  7644. * @type function
  7645. * @param {array} aoData Data array (array of objects which are name/value
  7646. * pairs) that has been constructed by DataTables and will be sent to the
  7647. * server. In the case of Ajax sourced data with server-side processing
  7648. * this will be an empty array, for server-side processing there will be a
  7649. * significant number of parameters!
  7650. * @returns {undefined} Ensure that you modify the aoData array passed in,
  7651. * as this is passed by reference.
  7652. * @dtopt Callbacks
  7653. * @dtopt Server-side
  7654. *
  7655. * @example
  7656. * $(document).ready(function() {
  7657. * $('#example').dataTable( {
  7658. * "bProcessing": true,
  7659. * "bServerSide": true,
  7660. * "sAjaxSource": "scripts/server_processing.php",
  7661. * "fnServerParams": function ( aoData ) {
  7662. * aoData.push( { "name": "more_data", "value": "my_value" } );
  7663. * }
  7664. * } );
  7665. * } );
  7666. */
  7667. "fnServerParams": null,
  7668. /**
  7669. * Load the table state. With this function you can define from where, and how, the
  7670. * state of a table is loaded. By default DataTables will load from its state saving
  7671. * cookie, but you might wish to use local storage (HTML5) or a server-side database.
  7672. * @type function
  7673. * @member
  7674. * @param {object} oSettings DataTables settings object
  7675. * @return {object} The DataTables state object to be loaded
  7676. * @dtopt Callbacks
  7677. *
  7678. * @example
  7679. * $(document).ready(function() {
  7680. * $('#example').dataTable( {
  7681. * "bStateSave": true,
  7682. * "fnStateLoad": function (oSettings, oData) {
  7683. * var o;
  7684. *
  7685. * // Send an Ajax request to the server to get the data. Note that
  7686. * // this is a synchronous request.
  7687. * $.ajax( {
  7688. * "url": "/state_load",
  7689. * "async": false,
  7690. * "dataType": "json",
  7691. * "success": function (json) {
  7692. * o = json;
  7693. * }
  7694. * } );
  7695. *
  7696. * return o;
  7697. * }
  7698. * } );
  7699. * } );
  7700. */
  7701. "fnStateLoad": function ( oSettings ) {
  7702. var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance );
  7703. var oData;
  7704. try {
  7705. oData = (typeof $.parseJSON === 'function') ?
  7706. $.parseJSON(sData) : eval( '('+sData+')' );
  7707. } catch (e) {
  7708. oData = null;
  7709. }
  7710. return oData;
  7711. },
  7712. /**
  7713. * Callback which allows modification of the saved state prior to loading that state.
  7714. * This callback is called when the table is loading state from the stored data, but
  7715. * prior to the settings object being modified by the saved state. Note that for
  7716. * plug-in authors, you should use the 'stateLoadParams' event to load parameters for
  7717. * a plug-in.
  7718. * @type function
  7719. * @param {object} oSettings DataTables settings object
  7720. * @param {object} oData The state object that is to be loaded
  7721. * @dtopt Callbacks
  7722. *
  7723. * @example
  7724. * // Remove a saved filter, so filtering is never loaded
  7725. * $(document).ready(function() {
  7726. * $('#example').dataTable( {
  7727. * "bStateSave": true,
  7728. * "fnStateLoadParams": function (oSettings, oData) {
  7729. * oData.oSearch.sSearch = "";
  7730. * } );
  7731. * } );
  7732. *
  7733. * @example
  7734. * // Disallow state loading by returning false
  7735. * $(document).ready(function() {
  7736. * $('#example').dataTable( {
  7737. * "bStateSave": true,
  7738. * "fnStateLoadParams": function (oSettings, oData) {
  7739. * return false;
  7740. * } );
  7741. * } );
  7742. */
  7743. "fnStateLoadParams": null,
  7744. /**
  7745. * Callback that is called when the state has been loaded from the state saving method
  7746. * and the DataTables settings object has been modified as a result of the loaded state.
  7747. * @type function
  7748. * @param {object} oSettings DataTables settings object
  7749. * @param {object} oData The state object that was loaded
  7750. * @dtopt Callbacks
  7751. *
  7752. * @example
  7753. * // Show an alert with the filtering value that was saved
  7754. * $(document).ready(function() {
  7755. * $('#example').dataTable( {
  7756. * "bStateSave": true,
  7757. * "fnStateLoaded": function (oSettings, oData) {
  7758. * alert( 'Saved filter was: '+oData.oSearch.sSearch );
  7759. * } );
  7760. * } );
  7761. */
  7762. "fnStateLoaded": null,
  7763. /**
  7764. * Save the table state. This function allows you to define where and how the state
  7765. * information for the table is stored - by default it will use a cookie, but you
  7766. * might want to use local storage (HTML5) or a server-side database.
  7767. * @type function
  7768. * @member
  7769. * @param {object} oSettings DataTables settings object
  7770. * @param {object} oData The state object to be saved
  7771. * @dtopt Callbacks
  7772. *
  7773. * @example
  7774. * $(document).ready(function() {
  7775. * $('#example').dataTable( {
  7776. * "bStateSave": true,
  7777. * "fnStateSave": function (oSettings, oData) {
  7778. * // Send an Ajax request to the server with the state object
  7779. * $.ajax( {
  7780. * "url": "/state_save",
  7781. * "data": oData,
  7782. * "dataType": "json",
  7783. * "method": "POST"
  7784. * "success": function () {}
  7785. * } );
  7786. * }
  7787. * } );
  7788. * } );
  7789. */
  7790. "fnStateSave": function ( oSettings, oData ) {
  7791. this.oApi._fnCreateCookie(
  7792. oSettings.sCookiePrefix+oSettings.sInstance,
  7793. this.oApi._fnJsonString(oData),
  7794. oSettings.iCookieDuration,
  7795. oSettings.sCookiePrefix,
  7796. oSettings.fnCookieCallback
  7797. );
  7798. },
  7799. /**
  7800. * Callback which allows modification of the state to be saved. Called when the table
  7801. * has changed state a new state save is required. This method allows modification of
  7802. * the state saving object prior to actually doing the save, including addition or
  7803. * other state properties or modification. Note that for plug-in authors, you should
  7804. * use the 'stateSaveParams' event to save parameters for a plug-in.
  7805. * @type function
  7806. * @param {object} oSettings DataTables settings object
  7807. * @param {object} oData The state object to be saved
  7808. * @dtopt Callbacks
  7809. *
  7810. * @example
  7811. * // Remove a saved filter, so filtering is never saved
  7812. * $(document).ready(function() {
  7813. * $('#example').dataTable( {
  7814. * "bStateSave": true,
  7815. * "fnStateSaveParams": function (oSettings, oData) {
  7816. * oData.oSearch.sSearch = "";
  7817. * } );
  7818. * } );
  7819. */
  7820. "fnStateSaveParams": null,
  7821. /**
  7822. * Duration of the cookie which is used for storing session information. This
  7823. * value is given in seconds.
  7824. * @type int
  7825. * @default 7200 <i>(2 hours)</i>
  7826. * @dtopt Options
  7827. *
  7828. * @example
  7829. * $(document).ready( function() {
  7830. * $('#example').dataTable( {
  7831. * "iCookieDuration": 60*60*24 // 1 day
  7832. * } );
  7833. * } )
  7834. */
  7835. "iCookieDuration": 7200,
  7836. /**
  7837. * When enabled DataTables will not make a request to the server for the first
  7838. * page draw - rather it will use the data already on the page (no sorting etc
  7839. * will be applied to it), thus saving on an XHR at load time. iDeferLoading
  7840. * is used to indicate that deferred loading is required, but it is also used
  7841. * to tell DataTables how many records there are in the full table (allowing
  7842. * the information element and pagination to be displayed correctly). In the case
  7843. * where a filtering is applied to the table on initial load, this can be
  7844. * indicated by giving the parameter as an array, where the first element is
  7845. * the number of records available after filtering and the second element is the
  7846. * number of records without filtering (allowing the table information element
  7847. * to be shown correctly).
  7848. * @type int | array
  7849. * @default null
  7850. * @dtopt Options
  7851. *
  7852. * @example
  7853. * // 57 records available in the table, no filtering applied
  7854. * $(document).ready(function() {
  7855. * $('#example').dataTable( {
  7856. * "bServerSide": true,
  7857. * "sAjaxSource": "scripts/server_processing.php",
  7858. * "iDeferLoading": 57
  7859. * } );
  7860. * } );
  7861. *
  7862. * @example
  7863. * // 57 records after filtering, 100 without filtering (an initial filter applied)
  7864. * $(document).ready(function() {
  7865. * $('#example').dataTable( {
  7866. * "bServerSide": true,
  7867. * "sAjaxSource": "scripts/server_processing.php",
  7868. * "iDeferLoading": [ 57, 100 ],
  7869. * "oSearch": {
  7870. * "sSearch": "my_filter"
  7871. * }
  7872. * } );
  7873. * } );
  7874. */
  7875. "iDeferLoading": null,
  7876. /**
  7877. * Number of rows to display on a single page when using pagination. If
  7878. * feature enabled (bLengthChange) then the end user will be able to override
  7879. * this to a custom setting using a pop-up menu.
  7880. * @type int
  7881. * @default 10
  7882. * @dtopt Options
  7883. *
  7884. * @example
  7885. * $(document).ready( function() {
  7886. * $('#example').dataTable( {
  7887. * "iDisplayLength": 50
  7888. * } );
  7889. * } )
  7890. */
  7891. "iDisplayLength": 10,
  7892. /**
  7893. * Define the starting point for data display when using DataTables with
  7894. * pagination. Note that this parameter is the number of records, rather than
  7895. * the page number, so if you have 10 records per page and want to start on
  7896. * the third page, it should be "20".
  7897. * @type int
  7898. * @default 0
  7899. * @dtopt Options
  7900. *
  7901. * @example
  7902. * $(document).ready( function() {
  7903. * $('#example').dataTable( {
  7904. * "iDisplayStart": 20
  7905. * } );
  7906. * } )
  7907. */
  7908. "iDisplayStart": 0,
  7909. /**
  7910. * The scroll gap is the amount of scrolling that is left to go before
  7911. * DataTables will load the next 'page' of data automatically. You typically
  7912. * want a gap which is big enough that the scrolling will be smooth for the
  7913. * user, while not so large that it will load more data than need.
  7914. * @type int
  7915. * @default 100
  7916. * @dtopt Options
  7917. *
  7918. * @example
  7919. * $(document).ready(function() {
  7920. * $('#example').dataTable( {
  7921. * "bScrollInfinite": true,
  7922. * "bScrollCollapse": true,
  7923. * "sScrollY": "200px",
  7924. * "iScrollLoadGap": 50
  7925. * } );
  7926. * } );
  7927. */
  7928. "iScrollLoadGap": 100,
  7929. /**
  7930. * By default DataTables allows keyboard navigation of the table (sorting, paging,
  7931. * and filtering) by adding a tabindex attribute to the required elements. This
  7932. * allows you to tab through the controls and press the enter key to activate them.
  7933. * The tabindex is default 0, meaning that the tab follows the flow of the document.
  7934. * You can overrule this using this parameter if you wish. Use a value of -1 to
  7935. * disable built-in keyboard navigation.
  7936. * @type int
  7937. * @default 0
  7938. * @dtopt Options
  7939. *
  7940. * @example
  7941. * $(document).ready(function() {
  7942. * $('#example').dataTable( {
  7943. * "iTabIndex": 1
  7944. * } );
  7945. * } );
  7946. */
  7947. "iTabIndex": 0,
  7948. /**
  7949. * All strings that DataTables uses in the user interface that it creates
  7950. * are defined in this object, allowing you to modified them individually or
  7951. * completely replace them all as required.
  7952. * @namespace
  7953. */
  7954. "oLanguage": {
  7955. /**
  7956. * Strings that are used for WAI-ARIA labels and controls only (these are not
  7957. * actually visible on the page, but will be read by screenreaders, and thus
  7958. * must be internationalised as well).
  7959. * @namespace
  7960. */
  7961. "oAria": {
  7962. /**
  7963. * ARIA label that is added to the table headers when the column may be
  7964. * sorted ascending by activing the column (click or return when focused).
  7965. * Note that the column header is prefixed to this string.
  7966. * @type string
  7967. * @default : activate to sort column ascending
  7968. * @dtopt Language
  7969. *
  7970. * @example
  7971. * $(document).ready(function() {
  7972. * $('#example').dataTable( {
  7973. * "oLanguage": {
  7974. * "oAria": {
  7975. * "sSortAscending": " - click/return to sort ascending"
  7976. * }
  7977. * }
  7978. * } );
  7979. * } );
  7980. */
  7981. "sSortAscending": ": activate to sort column ascending",
  7982. /**
  7983. * ARIA label that is added to the table headers when the column may be
  7984. * sorted descending by activing the column (click or return when focused).
  7985. * Note that the column header is prefixed to this string.
  7986. * @type string
  7987. * @default : activate to sort column ascending
  7988. * @dtopt Language
  7989. *
  7990. * @example
  7991. * $(document).ready(function() {
  7992. * $('#example').dataTable( {
  7993. * "oLanguage": {
  7994. * "oAria": {
  7995. * "sSortDescending": " - click/return to sort descending"
  7996. * }
  7997. * }
  7998. * } );
  7999. * } );
  8000. */
  8001. "sSortDescending": ": activate to sort column descending"
  8002. },
  8003. /**
  8004. * Pagination string used by DataTables for the two built-in pagination
  8005. * control types ("two_button" and "full_numbers")
  8006. * @namespace
  8007. */
  8008. "oPaginate": {
  8009. /**
  8010. * Text to use when using the 'full_numbers' type of pagination for the
  8011. * button to take the user to the first page.
  8012. * @type string
  8013. * @default First
  8014. * @dtopt Language
  8015. *
  8016. * @example
  8017. * $(document).ready(function() {
  8018. * $('#example').dataTable( {
  8019. * "oLanguage": {
  8020. * "oPaginate": {
  8021. * "sFirst": "First page"
  8022. * }
  8023. * }
  8024. * } );
  8025. * } );
  8026. */
  8027. "sFirst": "First",
  8028. /**
  8029. * Text to use when using the 'full_numbers' type of pagination for the
  8030. * button to take the user to the last page.
  8031. * @type string
  8032. * @default Last
  8033. * @dtopt Language
  8034. *
  8035. * @example
  8036. * $(document).ready(function() {
  8037. * $('#example').dataTable( {
  8038. * "oLanguage": {
  8039. * "oPaginate": {
  8040. * "sLast": "Last page"
  8041. * }
  8042. * }
  8043. * } );
  8044. * } );
  8045. */
  8046. "sLast": "Last",
  8047. /**
  8048. * Text to use when using the 'full_numbers' type of pagination for the
  8049. * button to take the user to the next page.
  8050. * @type string
  8051. * @default Next
  8052. * @dtopt Language
  8053. *
  8054. * @example
  8055. * $(document).ready(function() {
  8056. * $('#example').dataTable( {
  8057. * "oLanguage": {
  8058. * "oPaginate": {
  8059. * "sNext": "Next page"
  8060. * }
  8061. * }
  8062. * } );
  8063. * } );
  8064. */
  8065. "sNext": "Next",
  8066. /**
  8067. * Text to use when using the 'full_numbers' type of pagination for the
  8068. * button to take the user to the previous page.
  8069. * @type string
  8070. * @default Previous
  8071. * @dtopt Language
  8072. *
  8073. * @example
  8074. * $(document).ready(function() {
  8075. * $('#example').dataTable( {
  8076. * "oLanguage": {
  8077. * "oPaginate": {
  8078. * "sPrevious": "Previous page"
  8079. * }
  8080. * }
  8081. * } );
  8082. * } );
  8083. */
  8084. "sPrevious": "Previous"
  8085. },
  8086. /**
  8087. * This string is shown in preference to sZeroRecords when the table is
  8088. * empty of data (regardless of filtering). Note that this is an optional
  8089. * parameter - if it is not given, the value of sZeroRecords will be used
  8090. * instead (either the default or given value).
  8091. * @type string
  8092. * @default No data available in table
  8093. * @dtopt Language
  8094. *
  8095. * @example
  8096. * $(document).ready(function() {
  8097. * $('#example').dataTable( {
  8098. * "oLanguage": {
  8099. * "sEmptyTable": "No data available in table"
  8100. * }
  8101. * } );
  8102. * } );
  8103. */
  8104. "sEmptyTable": "No data available in table",
  8105. /**
  8106. * This string gives information to the end user about the information that
  8107. * is current on display on the page. The _START_, _END_ and _TOTAL_
  8108. * variables are all dynamically replaced as the table display updates, and
  8109. * can be freely moved or removed as the language requirements change.
  8110. * @type string
  8111. * @default Showing _START_ to _END_ of _TOTAL_ entries
  8112. * @dtopt Language
  8113. *
  8114. * @example
  8115. * $(document).ready(function() {
  8116. * $('#example').dataTable( {
  8117. * "oLanguage": {
  8118. * "sInfo": "Got a total of _TOTAL_ entries to show (_START_ to _END_)"
  8119. * }
  8120. * } );
  8121. * } );
  8122. */
  8123. "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
  8124. /**
  8125. * Display information string for when the table is empty. Typically the
  8126. * format of this string should match sInfo.
  8127. * @type string
  8128. * @default Showing 0 to 0 of 0 entries
  8129. * @dtopt Language
  8130. *
  8131. * @example
  8132. * $(document).ready(function() {
  8133. * $('#example').dataTable( {
  8134. * "oLanguage": {
  8135. * "sInfoEmpty": "No entries to show"
  8136. * }
  8137. * } );
  8138. * } );
  8139. */
  8140. "sInfoEmpty": "Showing 0 to 0 of 0 entries",
  8141. /**
  8142. * When a user filters the information in a table, this string is appended
  8143. * to the information (sInfo) to give an idea of how strong the filtering
  8144. * is. The variable _MAX_ is dynamically updated.
  8145. * @type string
  8146. * @default (filtered from _MAX_ total entries)
  8147. * @dtopt Language
  8148. *
  8149. * @example
  8150. * $(document).ready(function() {
  8151. * $('#example').dataTable( {
  8152. * "oLanguage": {
  8153. * "sInfoFiltered": " - filtering from _MAX_ records"
  8154. * }
  8155. * } );
  8156. * } );
  8157. */
  8158. "sInfoFiltered": "(filtered from _MAX_ total entries)",
  8159. /**
  8160. * If can be useful to append extra information to the info string at times,
  8161. * and this variable does exactly that. This information will be appended to
  8162. * the sInfo (sInfoEmpty and sInfoFiltered in whatever combination they are
  8163. * being used) at all times.
  8164. * @type string
  8165. * @default <i>Empty string</i>
  8166. * @dtopt Language
  8167. *
  8168. * @example
  8169. * $(document).ready(function() {
  8170. * $('#example').dataTable( {
  8171. * "oLanguage": {
  8172. * "sInfoPostFix": "All records shown are derived from real information."
  8173. * }
  8174. * } );
  8175. * } );
  8176. */
  8177. "sInfoPostFix": "",
  8178. /**
  8179. * DataTables has a build in number formatter (fnFormatNumber) which is used
  8180. * to format large numbers that are used in the table information. By
  8181. * default a comma is used, but this can be trivially changed to any
  8182. * character you wish with this parameter.
  8183. * @type string
  8184. * @default ,
  8185. * @dtopt Language
  8186. *
  8187. * @example
  8188. * $(document).ready(function() {
  8189. * $('#example').dataTable( {
  8190. * "oLanguage": {
  8191. * "sInfoThousands": "'"
  8192. * }
  8193. * } );
  8194. * } );
  8195. */
  8196. "sInfoThousands": ",",
  8197. /**
  8198. * Detail the action that will be taken when the drop down menu for the
  8199. * pagination length option is changed. The '_MENU_' variable is replaced
  8200. * with a default select list of 10, 25, 50 and 100, and can be replaced
  8201. * with a custom select box if required.
  8202. * @type string
  8203. * @default Show _MENU_ entries
  8204. * @dtopt Language
  8205. *
  8206. * @example
  8207. * // Language change only
  8208. * $(document).ready(function() {
  8209. * $('#example').dataTable( {
  8210. * "oLanguage": {
  8211. * "sLengthMenu": "Display _MENU_ records"
  8212. * }
  8213. * } );
  8214. * } );
  8215. *
  8216. * @example
  8217. * // Language and options change
  8218. * $(document).ready(function() {
  8219. * $('#example').dataTable( {
  8220. * "oLanguage": {
  8221. * "sLengthMenu": 'Display <select>'+
  8222. * '<option value="10">10</option>'+
  8223. * '<option value="20">20</option>'+
  8224. * '<option value="30">30</option>'+
  8225. * '<option value="40">40</option>'+
  8226. * '<option value="50">50</option>'+
  8227. * '<option value="-1">All</option>'+
  8228. * '</select> records'
  8229. * }
  8230. * } );
  8231. * } );
  8232. */
  8233. "sLengthMenu": "Show _MENU_ entries",
  8234. /**
  8235. * When using Ajax sourced data and during the first draw when DataTables is
  8236. * gathering the data, this message is shown in an empty row in the table to
  8237. * indicate to the end user the the data is being loaded. Note that this
  8238. * parameter is not used when loading data by server-side processing, just
  8239. * Ajax sourced data with client-side processing.
  8240. * @type string
  8241. * @default Loading...
  8242. * @dtopt Language
  8243. *
  8244. * @example
  8245. * $(document).ready( function() {
  8246. * $('#example').dataTable( {
  8247. * "oLanguage": {
  8248. * "sLoadingRecords": "Please wait - loading..."
  8249. * }
  8250. * } );
  8251. * } );
  8252. */
  8253. "sLoadingRecords": "Loading...",
  8254. /**
  8255. * Text which is displayed when the table is processing a user action
  8256. * (usually a sort command or similar).
  8257. * @type string
  8258. * @default Processing...
  8259. * @dtopt Language
  8260. *
  8261. * @example
  8262. * $(document).ready(function() {
  8263. * $('#example').dataTable( {
  8264. * "oLanguage": {
  8265. * "sProcessing": "DataTables is currently busy"
  8266. * }
  8267. * } );
  8268. * } );
  8269. */
  8270. "sProcessing": "Processing...",
  8271. /**
  8272. * Details the actions that will be taken when the user types into the
  8273. * filtering input text box. The variable "_INPUT_", if used in the string,
  8274. * is replaced with the HTML text box for the filtering input allowing
  8275. * control over where it appears in the string. If "_INPUT_" is not given
  8276. * then the input box is appended to the string automatically.
  8277. * @type string
  8278. * @default Search:
  8279. * @dtopt Language
  8280. *
  8281. * @example
  8282. * // Input text box will be appended at the end automatically
  8283. * $(document).ready(function() {
  8284. * $('#example').dataTable( {
  8285. * "oLanguage": {
  8286. * "sSearch": "Filter records:"
  8287. * }
  8288. * } );
  8289. * } );
  8290. *
  8291. * @example
  8292. * // Specify where the filter should appear
  8293. * $(document).ready(function() {
  8294. * $('#example').dataTable( {
  8295. * "oLanguage": {
  8296. * "sSearch": "Apply filter _INPUT_ to table"
  8297. * }
  8298. * } );
  8299. * } );
  8300. */
  8301. "sSearch": "Search:",
  8302. /**
  8303. * All of the language information can be stored in a file on the
  8304. * server-side, which DataTables will look up if this parameter is passed.
  8305. * It must store the URL of the language file, which is in a JSON format,
  8306. * and the object has the same properties as the oLanguage object in the
  8307. * initialiser object (i.e. the above parameters). Please refer to one of
  8308. * the example language files to see how this works in action.
  8309. * @type string
  8310. * @default <i>Empty string - i.e. disabled</i>
  8311. * @dtopt Language
  8312. *
  8313. * @example
  8314. * $(document).ready(function() {
  8315. * $('#example').dataTable( {
  8316. * "oLanguage": {
  8317. * "sUrl": "http://www.sprymedia.co.uk/dataTables/lang.txt"
  8318. * }
  8319. * } );
  8320. * } );
  8321. */
  8322. "sUrl": "",
  8323. /**
  8324. * Text shown inside the table records when the is no information to be
  8325. * displayed after filtering. sEmptyTable is shown when there is simply no
  8326. * information in the table at all (regardless of filtering).
  8327. * @type string
  8328. * @default No matching records found
  8329. * @dtopt Language
  8330. *
  8331. * @example
  8332. * $(document).ready(function() {
  8333. * $('#example').dataTable( {
  8334. * "oLanguage": {
  8335. * "sZeroRecords": "No records to display"
  8336. * }
  8337. * } );
  8338. * } );
  8339. */
  8340. "sZeroRecords": "No matching records found"
  8341. },
  8342. /**
  8343. * This parameter allows you to have define the global filtering state at
  8344. * initialisation time. As an object the "sSearch" parameter must be
  8345. * defined, but all other parameters are optional. When "bRegex" is true,
  8346. * the search string will be treated as a regular expression, when false
  8347. * (default) it will be treated as a straight string. When "bSmart"
  8348. * DataTables will use it's smart filtering methods (to word match at
  8349. * any point in the data), when false this will not be done.
  8350. * @namespace
  8351. * @extends DataTable.models.oSearch
  8352. * @dtopt Options
  8353. *
  8354. * @example
  8355. * $(document).ready( function() {
  8356. * $('#example').dataTable( {
  8357. * "oSearch": {"sSearch": "Initial search"}
  8358. * } );
  8359. * } )
  8360. */
  8361. "oSearch": $.extend( {}, DataTable.models.oSearch ),
  8362. /**
  8363. * By default DataTables will look for the property 'aaData' when obtaining
  8364. * data from an Ajax source or for server-side processing - this parameter
  8365. * allows that property to be changed. You can use Javascript dotted object
  8366. * notation to get a data source for multiple levels of nesting.
  8367. * @type string
  8368. * @default aaData
  8369. * @dtopt Options
  8370. * @dtopt Server-side
  8371. *
  8372. * @example
  8373. * // Get data from { "data": [...] }
  8374. * $(document).ready(function() {
  8375. * var oTable = $('#example').dataTable( {
  8376. * "sAjaxSource": "sources/data.txt",
  8377. * "sAjaxDataProp": "data"
  8378. * } );
  8379. * } );
  8380. *
  8381. * @example
  8382. * // Get data from { "data": { "inner": [...] } }
  8383. * $(document).ready(function() {
  8384. * var oTable = $('#example').dataTable( {
  8385. * "sAjaxSource": "sources/data.txt",
  8386. * "sAjaxDataProp": "data.inner"
  8387. * } );
  8388. * } );
  8389. */
  8390. "sAjaxDataProp": "aaData",
  8391. /**
  8392. * You can instruct DataTables to load data from an external source using this
  8393. * parameter (use aData if you want to pass data in you already have). Simply
  8394. * provide a url a JSON object can be obtained from. This object must include
  8395. * the parameter 'aaData' which is the data source for the table.
  8396. * @type string
  8397. * @default null
  8398. * @dtopt Options
  8399. * @dtopt Server-side
  8400. *
  8401. * @example
  8402. * $(document).ready( function() {
  8403. * $('#example').dataTable( {
  8404. * "sAjaxSource": "http://www.sprymedia.co.uk/dataTables/json.php"
  8405. * } );
  8406. * } )
  8407. */
  8408. "sAjaxSource": null,
  8409. /**
  8410. * This parameter can be used to override the default prefix that DataTables
  8411. * assigns to a cookie when state saving is enabled.
  8412. * @type string
  8413. * @default SpryMedia_DataTables_
  8414. * @dtopt Options
  8415. *
  8416. * @example
  8417. * $(document).ready(function() {
  8418. * $('#example').dataTable( {
  8419. * "sCookiePrefix": "my_datatable_",
  8420. * } );
  8421. * } );
  8422. */
  8423. "sCookiePrefix": "SpryMedia_DataTables_",
  8424. /**
  8425. * This initialisation variable allows you to specify exactly where in the
  8426. * DOM you want DataTables to inject the various controls it adds to the page
  8427. * (for example you might want the pagination controls at the top of the
  8428. * table). DIV elements (with or without a custom class) can also be added to
  8429. * aid styling. The follow syntax is used:
  8430. * <ul>
  8431. * <li>The following options are allowed:
  8432. * <ul>
  8433. * <li>'l' - Length changing</li
  8434. * <li>'f' - Filtering input</li>
  8435. * <li>'t' - The table!</li>
  8436. * <li>'i' - Information</li>
  8437. * <li>'p' - Pagination</li>
  8438. * <li>'r' - pRocessing</li>
  8439. * </ul>
  8440. * </li>
  8441. * <li>The following constants are allowed:
  8442. * <ul>
  8443. * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
  8444. * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
  8445. * </ul>
  8446. * </li>
  8447. * <li>The following syntax is expected:
  8448. * <ul>
  8449. * <li>'&lt;' and '&gt;' - div elements</li>
  8450. * <li>'&lt;"class" and '&gt;' - div with a class</li>
  8451. * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
  8452. * </ul>
  8453. * </li>
  8454. * <li>Examples:
  8455. * <ul>
  8456. * <li>'&lt;"wrapper"flipt&gt;'</li>
  8457. * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
  8458. * </ul>
  8459. * </li>
  8460. * </ul>
  8461. * @type string
  8462. * @default lfrtip <i>(when bJQueryUI is false)</i> <b>or</b>
  8463. * <"H"lfr>t<"F"ip> <i>(when bJQueryUI is true)</i>
  8464. * @dtopt Options
  8465. *
  8466. * @example
  8467. * $(document).ready(function() {
  8468. * $('#example').dataTable( {
  8469. * "sDom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&lgt;'
  8470. * } );
  8471. * } );
  8472. */
  8473. "sDom": "lfrtip",
  8474. /**
  8475. * DataTables features two different built-in pagination interaction methods
  8476. * ('two_button' or 'full_numbers') which present different page controls to
  8477. * the end user. Further methods can be added using the API (see below).
  8478. * @type string
  8479. * @default two_button
  8480. * @dtopt Options
  8481. *
  8482. * @example
  8483. * $(document).ready( function() {
  8484. * $('#example').dataTable( {
  8485. * "sPaginationType": "full_numbers"
  8486. * } );
  8487. * } )
  8488. */
  8489. "sPaginationType": "two_button",
  8490. /**
  8491. * Enable horizontal scrolling. When a table is too wide to fit into a certain
  8492. * layout, or you have a large number of columns in the table, you can enable
  8493. * x-scrolling to show the table in a viewport, which can be scrolled. This
  8494. * property can be any CSS unit, or a number (in which case it will be treated
  8495. * as a pixel measurement).
  8496. * @type string
  8497. * @default <i>blank string - i.e. disabled</i>
  8498. * @dtopt Features
  8499. *
  8500. * @example
  8501. * $(document).ready(function() {
  8502. * $('#example').dataTable( {
  8503. * "sScrollX": "100%",
  8504. * "bScrollCollapse": true
  8505. * } );
  8506. * } );
  8507. */
  8508. "sScrollX": "",
  8509. /**
  8510. * This property can be used to force a DataTable to use more width than it
  8511. * might otherwise do when x-scrolling is enabled. For example if you have a
  8512. * table which requires to be well spaced, this parameter is useful for
  8513. * "over-sizing" the table, and thus forcing scrolling. This property can by
  8514. * any CSS unit, or a number (in which case it will be treated as a pixel
  8515. * measurement).
  8516. * @type string
  8517. * @default <i>blank string - i.e. disabled</i>
  8518. * @dtopt Options
  8519. *
  8520. * @example
  8521. * $(document).ready(function() {
  8522. * $('#example').dataTable( {
  8523. * "sScrollX": "100%",
  8524. * "sScrollXInner": "110%"
  8525. * } );
  8526. * } );
  8527. */
  8528. "sScrollXInner": "",
  8529. /**
  8530. * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
  8531. * to the given height, and enable scrolling for any data which overflows the
  8532. * current viewport. This can be used as an alternative to paging to display
  8533. * a lot of data in a small area (although paging and scrolling can both be
  8534. * enabled at the same time). This property can be any CSS unit, or a number
  8535. * (in which case it will be treated as a pixel measurement).
  8536. * @type string
  8537. * @default <i>blank string - i.e. disabled</i>
  8538. * @dtopt Features
  8539. *
  8540. * @example
  8541. * $(document).ready(function() {
  8542. * $('#example').dataTable( {
  8543. * "sScrollY": "200px",
  8544. * "bPaginate": false
  8545. * } );
  8546. * } );
  8547. */
  8548. "sScrollY": "",
  8549. /**
  8550. * Set the HTTP method that is used to make the Ajax call for server-side
  8551. * processing or Ajax sourced data.
  8552. * @type string
  8553. * @default GET
  8554. * @dtopt Options
  8555. * @dtopt Server-side
  8556. *
  8557. * @example
  8558. * $(document).ready(function() {
  8559. * $('#example').dataTable( {
  8560. * "bServerSide": true,
  8561. * "sAjaxSource": "scripts/post.php",
  8562. * "sServerMethod": "POST"
  8563. * } );
  8564. * } );
  8565. */
  8566. "sServerMethod": "GET"
  8567. };
  8568. /**
  8569. * Column options that can be given to DataTables at initialisation time.
  8570. * @namespace
  8571. */
  8572. DataTable.defaults.columns = {
  8573. /**
  8574. * Allows a column's sorting to take multiple columns into account when
  8575. * doing a sort. For example first name / last name columns make sense to
  8576. * do a multi-column sort over the two columns.
  8577. * @type array
  8578. * @default null <i>Takes the value of the column index automatically</i>
  8579. * @dtopt Columns
  8580. *
  8581. * @example
  8582. * // Using aoColumnDefs
  8583. * $(document).ready(function() {
  8584. * $('#example').dataTable( {
  8585. * "aoColumnDefs": [
  8586. * { "aDataSort": [ 0, 1 ], "aTargets": [ 0 ] },
  8587. * { "aDataSort": [ 1, 0 ], "aTargets": [ 1 ] },
  8588. * { "aDataSort": [ 2, 3, 4 ], "aTargets": [ 2 ] }
  8589. * ]
  8590. * } );
  8591. * } );
  8592. *
  8593. * @example
  8594. * // Using aoColumns
  8595. * $(document).ready(function() {
  8596. * $('#example').dataTable( {
  8597. * "aoColumns": [
  8598. * { "aDataSort": [ 0, 1 ] },
  8599. * { "aDataSort": [ 1, 0 ] },
  8600. * { "aDataSort": [ 2, 3, 4 ] },
  8601. * null,
  8602. * null
  8603. * ]
  8604. * } );
  8605. * } );
  8606. */
  8607. "aDataSort": null,
  8608. /**
  8609. * You can control the default sorting direction, and even alter the behaviour
  8610. * of the sort handler (i.e. only allow ascending sorting etc) using this
  8611. * parameter.
  8612. * @type array
  8613. * @default [ 'asc', 'desc' ]
  8614. * @dtopt Columns
  8615. *
  8616. * @example
  8617. * // Using aoColumnDefs
  8618. * $(document).ready(function() {
  8619. * $('#example').dataTable( {
  8620. * "aoColumnDefs": [
  8621. * { "asSorting": [ "asc" ], "aTargets": [ 1 ] },
  8622. * { "asSorting": [ "desc", "asc", "asc" ], "aTargets": [ 2 ] },
  8623. * { "asSorting": [ "desc" ], "aTargets": [ 3 ] }
  8624. * ]
  8625. * } );
  8626. * } );
  8627. *
  8628. * @example
  8629. * // Using aoColumns
  8630. * $(document).ready(function() {
  8631. * $('#example').dataTable( {
  8632. * "aoColumns": [
  8633. * null,
  8634. * { "asSorting": [ "asc" ] },
  8635. * { "asSorting": [ "desc", "asc", "asc" ] },
  8636. * { "asSorting": [ "desc" ] },
  8637. * null
  8638. * ]
  8639. * } );
  8640. * } );
  8641. */
  8642. "asSorting": [ 'asc', 'desc' ],
  8643. /**
  8644. * Enable or disable filtering on the data in this column.
  8645. * @type boolean
  8646. * @default true
  8647. * @dtopt Columns
  8648. *
  8649. * @example
  8650. * // Using aoColumnDefs
  8651. * $(document).ready(function() {
  8652. * $('#example').dataTable( {
  8653. * "aoColumnDefs": [
  8654. * { "bSearchable": false, "aTargets": [ 0 ] }
  8655. * ] } );
  8656. * } );
  8657. *
  8658. * @example
  8659. * // Using aoColumns
  8660. * $(document).ready(function() {
  8661. * $('#example').dataTable( {
  8662. * "aoColumns": [
  8663. * { "bSearchable": false },
  8664. * null,
  8665. * null,
  8666. * null,
  8667. * null
  8668. * ] } );
  8669. * } );
  8670. */
  8671. "bSearchable": true,
  8672. /**
  8673. * Enable or disable sorting on this column.
  8674. * @type boolean
  8675. * @default true
  8676. * @dtopt Columns
  8677. *
  8678. * @example
  8679. * // Using aoColumnDefs
  8680. * $(document).ready(function() {
  8681. * $('#example').dataTable( {
  8682. * "aoColumnDefs": [
  8683. * { "bSortable": false, "aTargets": [ 0 ] }
  8684. * ] } );
  8685. * } );
  8686. *
  8687. * @example
  8688. * // Using aoColumns
  8689. * $(document).ready(function() {
  8690. * $('#example').dataTable( {
  8691. * "aoColumns": [
  8692. * { "bSortable": false },
  8693. * null,
  8694. * null,
  8695. * null,
  8696. * null
  8697. * ] } );
  8698. * } );
  8699. */
  8700. "bSortable": true,
  8701. /**
  8702. * When using fnRender() for a column, you may wish to use the original data
  8703. * (before rendering) for sorting and filtering (the default is to used the
  8704. * rendered data that the user can see). This may be useful for dates etc.
  8705. *
  8706. * *NOTE* It is it is advisable now to use mDataProp as a function and make
  8707. * use of the 'type' that it gives, allowing (potentially) different data to
  8708. * be used for sorting, filtering, display and type detection.
  8709. * @type boolean
  8710. * @default true
  8711. * @dtopt Columns
  8712. *
  8713. * @example
  8714. * // Using aoColumnDefs
  8715. * $(document).ready(function() {
  8716. * $('#example').dataTable( {
  8717. * "aoColumnDefs": [
  8718. * {
  8719. * "fnRender": function ( oObj ) {
  8720. * return oObj.aData[0] +' '+ oObj.aData[3];
  8721. * },
  8722. * "bUseRendered": false,
  8723. * "aTargets": [ 0 ]
  8724. * }
  8725. * ]
  8726. * } );
  8727. * } );
  8728. *
  8729. * @example
  8730. * // Using aoColumns
  8731. * $(document).ready(function() {
  8732. * $('#example').dataTable( {
  8733. * "aoColumns": [
  8734. * {
  8735. * "fnRender": function ( oObj ) {
  8736. * return oObj.aData[0] +' '+ oObj.aData[3];
  8737. * },
  8738. * "bUseRendered": false
  8739. * },
  8740. * null,
  8741. * null,
  8742. * null,
  8743. * null
  8744. * ]
  8745. * } );
  8746. * } );
  8747. */
  8748. "bUseRendered": true,
  8749. /**
  8750. * Enable or disable the display of this column.
  8751. * @type boolean
  8752. * @default true
  8753. * @dtopt Columns
  8754. *
  8755. * @example
  8756. * // Using aoColumnDefs
  8757. * $(document).ready(function() {
  8758. * $('#example').dataTable( {
  8759. * "aoColumnDefs": [
  8760. * { "bVisible": false, "aTargets": [ 0 ] }
  8761. * ] } );
  8762. * } );
  8763. *
  8764. * @example
  8765. * // Using aoColumns
  8766. * $(document).ready(function() {
  8767. * $('#example').dataTable( {
  8768. * "aoColumns": [
  8769. * { "bVisible": false },
  8770. * null,
  8771. * null,
  8772. * null,
  8773. * null
  8774. * ] } );
  8775. * } );
  8776. */
  8777. "bVisible": true,
  8778. /**
  8779. * Developer definable function that is called whenever a cell is created (Ajax source,
  8780. * etc) or processed for input (DOM source). This can be used as a compliment to fnRender
  8781. * allowing you to modify the DOM element (add background colour for example) when the
  8782. * element is available (since it is not when fnRender is called).
  8783. * @type function
  8784. * @param {element} nTd The TD node that has been created
  8785. * @param {*} sData The Data for the cell
  8786. * @param {array|object} oData The data for the whole row
  8787. * @param {int} iRow The row index for the aoData data store
  8788. * @param {int} iCol The column index for aoColumns
  8789. * @dtopt Columns
  8790. *
  8791. * @example
  8792. * $(document).ready(function() {
  8793. * $('#example').dataTable( {
  8794. * "aoColumnDefs": [ {
  8795. * "aTargets": [3],
  8796. * "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
  8797. * if ( sData == "1.7" ) {
  8798. * $(nTd).css('color', 'blue')
  8799. * }
  8800. * }
  8801. * } ]
  8802. * });
  8803. * } );
  8804. */
  8805. "fnCreatedCell": null,
  8806. /**
  8807. * Custom display function that will be called for the display of each cell in
  8808. * this column.
  8809. * @type function
  8810. * @param {object} o Object with the following parameters:
  8811. * @param {int} o.iDataRow The row in aoData
  8812. * @param {int} o.iDataColumn The column in question
  8813. * @param {array} o.aData The data for the row in question
  8814. * @param {object} o.oSettings The settings object for this DataTables instance
  8815. * @param {object} o.mDataProp The data property used for this column
  8816. * @param {*} val The current cell value
  8817. * @returns {string} The string you which to use in the display
  8818. * @dtopt Columns
  8819. *
  8820. * @example
  8821. * // Using aoColumnDefs
  8822. * $(document).ready(function() {
  8823. * $('#example').dataTable( {
  8824. * "aoColumnDefs": [
  8825. * {
  8826. * "fnRender": function ( o, val ) {
  8827. * return o.aData[0] +' '+ o.aData[3];
  8828. * },
  8829. * "aTargets": [ 0 ]
  8830. * }
  8831. * ]
  8832. * } );
  8833. * } );
  8834. *
  8835. * @example
  8836. * // Using aoColumns
  8837. * $(document).ready(function() {
  8838. * $('#example').dataTable( {
  8839. * "aoColumns": [
  8840. * { "fnRender": function ( o, val ) {
  8841. * return o.aData[0] +' '+ o.aData[3];
  8842. * } },
  8843. * null,
  8844. * null,
  8845. * null,
  8846. * null
  8847. * ]
  8848. * } );
  8849. * } );
  8850. */
  8851. "fnRender": null,
  8852. /**
  8853. * The column index (starting from 0!) that you wish a sort to be performed
  8854. * upon when this column is selected for sorting. This can be used for sorting
  8855. * on hidden columns for example.
  8856. * @type int
  8857. * @default -1 <i>Use automatically calculated column index</i>
  8858. * @dtopt Columns
  8859. *
  8860. * @example
  8861. * // Using aoColumnDefs
  8862. * $(document).ready(function() {
  8863. * $('#example').dataTable( {
  8864. * "aoColumnDefs": [
  8865. * { "iDataSort": 1, "aTargets": [ 0 ] }
  8866. * ]
  8867. * } );
  8868. * } );
  8869. *
  8870. * @example
  8871. * // Using aoColumns
  8872. * $(document).ready(function() {
  8873. * $('#example').dataTable( {
  8874. * "aoColumns": [
  8875. * { "iDataSort": 1 },
  8876. * null,
  8877. * null,
  8878. * null,
  8879. * null
  8880. * ]
  8881. * } );
  8882. * } );
  8883. */
  8884. "iDataSort": -1,
  8885. /**
  8886. * This property can be used to read data from any JSON data source property,
  8887. * including deeply nested objects / properties. mDataProp can be given in a
  8888. * number of different ways which effect its behaviour:
  8889. * <ul>
  8890. * <li>integer - treated as an array index for the data source. This is the
  8891. * default that DataTables uses (incrementally increased for each column).</li>
  8892. * <li>string - read an object property from the data source. Note that you can
  8893. * use Javascript dotted notation to read deep properties/arrays from the
  8894. * data source.</li>
  8895. * <li>null - the sDefaultContent option will be used for the cell (null
  8896. * by default, so you will need to specify the default content you want -
  8897. * typically an empty string). This can be useful on generated columns such
  8898. * as edit / delete action columns.</li>
  8899. * <li>function - the function given will be executed whenever DataTables
  8900. * needs to set or get the data for a cell in the column. The function
  8901. * takes three parameters:
  8902. * <ul>
  8903. * <li>{array|object} The data source for the row</li>
  8904. * <li>{string} The type call data requested - this will be 'set' when
  8905. * setting data or 'filter', 'display', 'type', 'sort' or undefined when
  8906. * gathering data. Note that when <i>undefined</i> is given for the type
  8907. * DataTables expects to get the raw data for the object back</li>
  8908. * <li>{*} Data to set when the second parameter is 'set'.</li>
  8909. * </ul>
  8910. * The return value from the function is not required when 'set' is the type
  8911. * of call, but otherwise the return is what will be used for the data
  8912. * requested.</li>
  8913. * </ul>
  8914. * @type string|int|function|null
  8915. * @default null <i>Use automatically calculated column index</i>
  8916. * @dtopt Columns
  8917. *
  8918. * @example
  8919. * // Read table data from objects
  8920. * $(document).ready(function() {
  8921. * var oTable = $('#example').dataTable( {
  8922. * "sAjaxSource": "sources/deep.txt",
  8923. * "aoColumns": [
  8924. * { "mDataProp": "engine" },
  8925. * { "mDataProp": "browser" },
  8926. * { "mDataProp": "platform.inner" },
  8927. * { "mDataProp": "platform.details.0" },
  8928. * { "mDataProp": "platform.details.1" }
  8929. * ]
  8930. * } );
  8931. * } );
  8932. *
  8933. * @example
  8934. * // Using mDataProp as a function to provide different information for
  8935. * // sorting, filtering and display. In this case, currency (price)
  8936. * $(document).ready(function() {
  8937. * var oTable = $('#example').dataTable( {
  8938. * "aoColumnDefs": [
  8939. * {
  8940. * "aTargets": [ 0 ],
  8941. * "mDataProp": function ( source, type, val ) {
  8942. * if (type === 'set') {
  8943. * source.price = val;
  8944. * // Store the computed dislay and filter values for efficiency
  8945. * source.price_display = val=="" ? "" : "$"+numberFormat(val);
  8946. * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
  8947. * return;
  8948. * }
  8949. * else if (type === 'display') {
  8950. * return source.price_display;
  8951. * }
  8952. * else if (type === 'filter') {
  8953. * return source.price_filter;
  8954. * }
  8955. * // 'sort', 'type' and undefined all just use the integer
  8956. * return source.price;
  8957. * }
  8958. * ]
  8959. * } );
  8960. * } );
  8961. */
  8962. "mDataProp": null,
  8963. /**
  8964. * Change the cell type created for the column - either TD cells or TH cells. This
  8965. * can be useful as TH cells have semantic meaning in the table body, allowing them
  8966. * to act as a header for a row (you may wish to add scope='row' to the TH elements).
  8967. * @type string
  8968. * @default td
  8969. * @dtopt Columns
  8970. *
  8971. * @example
  8972. * // Make the first column use TH cells
  8973. * $(document).ready(function() {
  8974. * var oTable = $('#example').dataTable( {
  8975. * "aoColumnDefs": [
  8976. * {
  8977. * "aTargets": [ 0 ],
  8978. * "sCellType": "th"
  8979. * ]
  8980. * } );
  8981. * } );
  8982. */
  8983. "sCellType": "td",
  8984. /**
  8985. * Class to give to each cell in this column.
  8986. * @type string
  8987. * @default <i>Empty string</i>
  8988. * @dtopt Columns
  8989. *
  8990. * @example
  8991. * // Using aoColumnDefs
  8992. * $(document).ready(function() {
  8993. * $('#example').dataTable( {
  8994. * "aoColumnDefs": [
  8995. * { "sClass": "my_class", "aTargets": [ 0 ] }
  8996. * ]
  8997. * } );
  8998. * } );
  8999. *
  9000. * @example
  9001. * // Using aoColumns
  9002. * $(document).ready(function() {
  9003. * $('#example').dataTable( {
  9004. * "aoColumns": [
  9005. * { "sClass": "my_class" },
  9006. * null,
  9007. * null,
  9008. * null,
  9009. * null
  9010. * ]
  9011. * } );
  9012. * } );
  9013. */
  9014. "sClass": "",
  9015. /**
  9016. * When DataTables calculates the column widths to assign to each column,
  9017. * it finds the longest string in each column and then constructs a
  9018. * temporary table and reads the widths from that. The problem with this
  9019. * is that "mmm" is much wider then "iiii", but the latter is a longer
  9020. * string - thus the calculation can go wrong (doing it properly and putting
  9021. * it into an DOM object and measuring that is horribly(!) slow). Thus as
  9022. * a "work around" we provide this option. It will append its value to the
  9023. * text that is found to be the longest string for the column - i.e. padding.
  9024. * Generally you shouldn't need this, and it is not documented on the
  9025. * general DataTables.net documentation
  9026. * @type string
  9027. * @default <i>Empty string<i>
  9028. * @dtopt Columns
  9029. *
  9030. * @example
  9031. * // Using aoColumns
  9032. * $(document).ready(function() {
  9033. * $('#example').dataTable( {
  9034. * "aoColumns": [
  9035. * null,
  9036. * null,
  9037. * null,
  9038. * {
  9039. * "sContentPadding": "mmm"
  9040. * }
  9041. * ]
  9042. * } );
  9043. * } );
  9044. */
  9045. "sContentPadding": "",
  9046. /**
  9047. * Allows a default value to be given for a column's data, and will be used
  9048. * whenever a null data source is encountered (this can be because mDataProp
  9049. * is set to null, or because the data source itself is null).
  9050. * @type string
  9051. * @default null
  9052. * @dtopt Columns
  9053. *
  9054. * @example
  9055. * // Using aoColumnDefs
  9056. * $(document).ready(function() {
  9057. * $('#example').dataTable( {
  9058. * "aoColumnDefs": [
  9059. * {
  9060. * "mDataProp": null,
  9061. * "sDefaultContent": "Edit",
  9062. * "aTargets": [ -1 ]
  9063. * }
  9064. * ]
  9065. * } );
  9066. * } );
  9067. *
  9068. * @example
  9069. * // Using aoColumns
  9070. * $(document).ready(function() {
  9071. * $('#example').dataTable( {
  9072. * "aoColumns": [
  9073. * null,
  9074. * null,
  9075. * null,
  9076. * {
  9077. * "mDataProp": null,
  9078. * "sDefaultContent": "Edit"
  9079. * }
  9080. * ]
  9081. * } );
  9082. * } );
  9083. */
  9084. "sDefaultContent": null,
  9085. /**
  9086. * This parameter is only used in DataTables' server-side processing. It can
  9087. * be exceptionally useful to know what columns are being displayed on the
  9088. * client side, and to map these to database fields. When defined, the names
  9089. * also allow DataTables to reorder information from the server if it comes
  9090. * back in an unexpected order (i.e. if you switch your columns around on the
  9091. * client-side, your server-side code does not also need updating).
  9092. * @type string
  9093. * @default <i>Empty string</i>
  9094. * @dtopt Columns
  9095. *
  9096. * @example
  9097. * // Using aoColumnDefs
  9098. * $(document).ready(function() {
  9099. * $('#example').dataTable( {
  9100. * "aoColumnDefs": [
  9101. * { "sName": "engine", "aTargets": [ 0 ] },
  9102. * { "sName": "browser", "aTargets": [ 1 ] },
  9103. * { "sName": "platform", "aTargets": [ 2 ] },
  9104. * { "sName": "version", "aTargets": [ 3 ] },
  9105. * { "sName": "grade", "aTargets": [ 4 ] }
  9106. * ]
  9107. * } );
  9108. * } );
  9109. *
  9110. * @example
  9111. * // Using aoColumns
  9112. * $(document).ready(function() {
  9113. * $('#example').dataTable( {
  9114. * "aoColumns": [
  9115. * { "sName": "engine" },
  9116. * { "sName": "browser" },
  9117. * { "sName": "platform" },
  9118. * { "sName": "version" },
  9119. * { "sName": "grade" }
  9120. * ]
  9121. * } );
  9122. * } );
  9123. */
  9124. "sName": "",
  9125. /**
  9126. * Defines a data source type for the sorting which can be used to read
  9127. * realtime information from the table (updating the internally cached
  9128. * version) prior to sorting. This allows sorting to occur on user editable
  9129. * elements such as form inputs.
  9130. * @type string
  9131. * @default std
  9132. * @dtopt Columns
  9133. *
  9134. * @example
  9135. * // Using aoColumnDefs
  9136. * $(document).ready(function() {
  9137. * $('#example').dataTable( {
  9138. * "aoColumnDefs": [
  9139. * { "sSortDataType": "dom-text", "aTargets": [ 2, 3 ] },
  9140. * { "sType": "numeric", "aTargets": [ 3 ] },
  9141. * { "sSortDataType": "dom-select", "aTargets": [ 4 ] },
  9142. * { "sSortDataType": "dom-checkbox", "aTargets": [ 5 ] }
  9143. * ]
  9144. * } );
  9145. * } );
  9146. *
  9147. * @example
  9148. * // Using aoColumns
  9149. * $(document).ready(function() {
  9150. * $('#example').dataTable( {
  9151. * "aoColumns": [
  9152. * null,
  9153. * null,
  9154. * { "sSortDataType": "dom-text" },
  9155. * { "sSortDataType": "dom-text", "sType": "numeric" },
  9156. * { "sSortDataType": "dom-select" },
  9157. * { "sSortDataType": "dom-checkbox" }
  9158. * ]
  9159. * } );
  9160. * } );
  9161. */
  9162. "sSortDataType": "std",
  9163. /**
  9164. * The title of this column.
  9165. * @type string
  9166. * @default null <i>Derived from the 'TH' value for this column in the
  9167. * original HTML table.</i>
  9168. * @dtopt Columns
  9169. *
  9170. * @example
  9171. * // Using aoColumnDefs
  9172. * $(document).ready(function() {
  9173. * $('#example').dataTable( {
  9174. * "aoColumnDefs": [
  9175. * { "sTitle": "My column title", "aTargets": [ 0 ] }
  9176. * ]
  9177. * } );
  9178. * } );
  9179. *
  9180. * @example
  9181. * // Using aoColumns
  9182. * $(document).ready(function() {
  9183. * $('#example').dataTable( {
  9184. * "aoColumns": [
  9185. * { "sTitle": "My column title" },
  9186. * null,
  9187. * null,
  9188. * null,
  9189. * null
  9190. * ]
  9191. * } );
  9192. * } );
  9193. */
  9194. "sTitle": null,
  9195. /**
  9196. * The type allows you to specify how the data for this column will be sorted.
  9197. * Four types (string, numeric, date and html (which will strip HTML tags
  9198. * before sorting)) are currently available. Note that only date formats
  9199. * understood by Javascript's Date() object will be accepted as type date. For
  9200. * example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 'numeric',
  9201. * 'date' or 'html' (by default). Further types can be adding through
  9202. * plug-ins.
  9203. * @type string
  9204. * @default null <i>Auto-detected from raw data</i>
  9205. * @dtopt Columns
  9206. *
  9207. * @example
  9208. * // Using aoColumnDefs
  9209. * $(document).ready(function() {
  9210. * $('#example').dataTable( {
  9211. * "aoColumnDefs": [
  9212. * { "sType": "html", "aTargets": [ 0 ] }
  9213. * ]
  9214. * } );
  9215. * } );
  9216. *
  9217. * @example
  9218. * // Using aoColumns
  9219. * $(document).ready(function() {
  9220. * $('#example').dataTable( {
  9221. * "aoColumns": [
  9222. * { "sType": "html" },
  9223. * null,
  9224. * null,
  9225. * null,
  9226. * null
  9227. * ]
  9228. * } );
  9229. * } );
  9230. */
  9231. "sType": null,
  9232. /**
  9233. * Defining the width of the column, this parameter may take any CSS value
  9234. * (3em, 20px etc). DataTables applys 'smart' widths to columns which have not
  9235. * been given a specific width through this interface ensuring that the table
  9236. * remains readable.
  9237. * @type string
  9238. * @default null <i>Automatic</i>
  9239. * @dtopt Columns
  9240. *
  9241. * @example
  9242. * // Using aoColumnDefs
  9243. * $(document).ready(function() {
  9244. * $('#example').dataTable( {
  9245. * "aoColumnDefs": [
  9246. * { "sWidth": "20%", "aTargets": [ 0 ] }
  9247. * ]
  9248. * } );
  9249. * } );
  9250. *
  9251. * @example
  9252. * // Using aoColumns
  9253. * $(document).ready(function() {
  9254. * $('#example').dataTable( {
  9255. * "aoColumns": [
  9256. * { "sWidth": "20%" },
  9257. * null,
  9258. * null,
  9259. * null,
  9260. * null
  9261. * ]
  9262. * } );
  9263. * } );
  9264. */
  9265. "sWidth": null
  9266. };
  9267. /**
  9268. * DataTables settings object - this holds all the information needed for a
  9269. * given table, including configuration, data and current application of the
  9270. * table options. DataTables does not have a single instance for each DataTable
  9271. * with the settings attached to that instance, but rather instances of the
  9272. * DataTable "class" are created on-the-fly as needed (typically by a
  9273. * $().dataTable() call) and the settings object is then applied to that
  9274. * instance.
  9275. *
  9276. * Note that this object is related to {@link DataTable.defaults} but this
  9277. * one is the internal data store for DataTables's cache of columns. It should
  9278. * NOT be manipulated outside of DataTables. Any configuration should be done
  9279. * through the initialisation options.
  9280. * @namespace
  9281. * @todo Really should attach the settings object to individual instances so we
  9282. * don't need to create new instances on each $().dataTable() call (if the
  9283. * table already exists). It would also save passing oSettings around and
  9284. * into every single function. However, this is a very significant
  9285. * architecture change for DataTables and will almost certainly break
  9286. * backwards compatibility with older installations. This is something that
  9287. * will be done in 2.0.
  9288. */
  9289. DataTable.models.oSettings = {
  9290. /**
  9291. * Primary features of DataTables and their enablement state.
  9292. * @namespace
  9293. */
  9294. "oFeatures": {
  9295. /**
  9296. * Flag to say if DataTables should automatically try to calculate the
  9297. * optimum table and columns widths (true) or not (false).
  9298. * Note that this parameter will be set by the initialisation routine. To
  9299. * set a default use {@link DataTable.defaults}.
  9300. * @type boolean
  9301. */
  9302. "bAutoWidth": null,
  9303. /**
  9304. * Delay the creation of TR and TD elements until they are actually
  9305. * needed by a driven page draw. This can give a significant speed
  9306. * increase for Ajax source and Javascript source data, but makes no
  9307. * difference at all fro DOM and server-side processing tables.
  9308. * Note that this parameter will be set by the initialisation routine. To
  9309. * set a default use {@link DataTable.defaults}.
  9310. * @type boolean
  9311. */
  9312. "bDeferRender": null,
  9313. /**
  9314. * Enable filtering on the table or not. Note that if this is disabled
  9315. * then there is no filtering at all on the table, including fnFilter.
  9316. * To just remove the filtering input use sDom and remove the 'f' option.
  9317. * Note that this parameter will be set by the initialisation routine. To
  9318. * set a default use {@link DataTable.defaults}.
  9319. * @type boolean
  9320. */
  9321. "bFilter": null,
  9322. /**
  9323. * Table information element (the 'Showing x of y records' div) enable
  9324. * flag.
  9325. * Note that this parameter will be set by the initialisation routine. To
  9326. * set a default use {@link DataTable.defaults}.
  9327. * @type boolean
  9328. */
  9329. "bInfo": null,
  9330. /**
  9331. * Present a user control allowing the end user to change the page size
  9332. * when pagination is enabled.
  9333. * Note that this parameter will be set by the initialisation routine. To
  9334. * set a default use {@link DataTable.defaults}.
  9335. * @type boolean
  9336. */
  9337. "bLengthChange": null,
  9338. /**
  9339. * Pagination enabled or not. Note that if this is disabled then length
  9340. * changing must also be disabled.
  9341. * Note that this parameter will be set by the initialisation routine. To
  9342. * set a default use {@link DataTable.defaults}.
  9343. * @type boolean
  9344. */
  9345. "bPaginate": null,
  9346. /**
  9347. * Processing indicator enable flag whenever DataTables is enacting a
  9348. * user request - typically an Ajax request for server-side processing.
  9349. * Note that this parameter will be set by the initialisation routine. To
  9350. * set a default use {@link DataTable.defaults}.
  9351. * @type boolean
  9352. */
  9353. "bProcessing": null,
  9354. /**
  9355. * Server-side processing enabled flag - when enabled DataTables will
  9356. * get all data from the server for every draw - there is no filtering,
  9357. * sorting or paging done on the client-side.
  9358. * Note that this parameter will be set by the initialisation routine. To
  9359. * set a default use {@link DataTable.defaults}.
  9360. * @type boolean
  9361. */
  9362. "bServerSide": null,
  9363. /**
  9364. * Sorting enablement flag.
  9365. * Note that this parameter will be set by the initialisation routine. To
  9366. * set a default use {@link DataTable.defaults}.
  9367. * @type boolean
  9368. */
  9369. "bSort": null,
  9370. /**
  9371. * Apply a class to the columns which are being sorted to provide a
  9372. * visual highlight or not. This can slow things down when enabled since
  9373. * there is a lot of DOM interaction.
  9374. * Note that this parameter will be set by the initialisation routine. To
  9375. * set a default use {@link DataTable.defaults}.
  9376. * @type boolean
  9377. */
  9378. "bSortClasses": null,
  9379. /**
  9380. * State saving enablement flag.
  9381. * Note that this parameter will be set by the initialisation routine. To
  9382. * set a default use {@link DataTable.defaults}.
  9383. * @type boolean
  9384. */
  9385. "bStateSave": null
  9386. },
  9387. /**
  9388. * Scrolling settings for a table.
  9389. * @namespace
  9390. */
  9391. "oScroll": {
  9392. /**
  9393. * Indicate if DataTables should be allowed to set the padding / margin
  9394. * etc for the scrolling header elements or not. Typically you will want
  9395. * this.
  9396. * Note that this parameter will be set by the initialisation routine. To
  9397. * set a default use {@link DataTable.defaults}.
  9398. * @type boolean
  9399. */
  9400. "bAutoCss": null,
  9401. /**
  9402. * When the table is shorter in height than sScrollY, collapse the
  9403. * table container down to the height of the table (when true).
  9404. * Note that this parameter will be set by the initialisation routine. To
  9405. * set a default use {@link DataTable.defaults}.
  9406. * @type boolean
  9407. */
  9408. "bCollapse": null,
  9409. /**
  9410. * Infinite scrolling enablement flag. Now deprecated in favour of
  9411. * using the Scroller plug-in.
  9412. * Note that this parameter will be set by the initialisation routine. To
  9413. * set a default use {@link DataTable.defaults}.
  9414. * @type boolean
  9415. */
  9416. "bInfinite": null,
  9417. /**
  9418. * Width of the scrollbar for the web-browser's platform. Calculated
  9419. * during table initialisation.
  9420. * @type int
  9421. * @default 0
  9422. */
  9423. "iBarWidth": 0,
  9424. /**
  9425. * Space (in pixels) between the bottom of the scrolling container and
  9426. * the bottom of the scrolling viewport before the next page is loaded
  9427. * when using infinite scrolling.
  9428. * Note that this parameter will be set by the initialisation routine. To
  9429. * set a default use {@link DataTable.defaults}.
  9430. * @type int
  9431. */
  9432. "iLoadGap": null,
  9433. /**
  9434. * Viewport width for horizontal scrolling. Horizontal scrolling is
  9435. * disabled if an empty string.
  9436. * Note that this parameter will be set by the initialisation routine. To
  9437. * set a default use {@link DataTable.defaults}.
  9438. * @type string
  9439. */
  9440. "sX": null,
  9441. /**
  9442. * Width to expand the table to when using x-scrolling. Typically you
  9443. * should not need to use this.
  9444. * Note that this parameter will be set by the initialisation routine. To
  9445. * set a default use {@link DataTable.defaults}.
  9446. * @type string
  9447. * @deprecated
  9448. */
  9449. "sXInner": null,
  9450. /**
  9451. * Viewport height for vertical scrolling. Vertical scrolling is disabled
  9452. * if an empty string.
  9453. * Note that this parameter will be set by the initialisation routine. To
  9454. * set a default use {@link DataTable.defaults}.
  9455. * @type string
  9456. */
  9457. "sY": null
  9458. },
  9459. /**
  9460. * Language information for the table.
  9461. * @namespace
  9462. * @extends DataTable.defaults.oLanguage
  9463. */
  9464. "oLanguage": {
  9465. /**
  9466. * Information callback function. See
  9467. * {@link DataTable.defaults.fnInfoCallback}
  9468. * @type function
  9469. * @default
  9470. */
  9471. "fnInfoCallback": null
  9472. },
  9473. /**
  9474. * Array referencing the nodes which are used for the features. The
  9475. * parameters of this object match what is allowed by sDom - i.e.
  9476. * <ul>
  9477. * <li>'l' - Length changing</li>
  9478. * <li>'f' - Filtering input</li>
  9479. * <li>'t' - The table!</li>
  9480. * <li>'i' - Information</li>
  9481. * <li>'p' - Pagination</li>
  9482. * <li>'r' - pRocessing</li>
  9483. * </ul>
  9484. * @type array
  9485. * @default []
  9486. */
  9487. "aanFeatures": [],
  9488. /**
  9489. * Store data information - see {@link DataTable.models.oRow} for detailed
  9490. * information.
  9491. * @type array
  9492. * @default []
  9493. */
  9494. "aoData": [],
  9495. /**
  9496. * Array of indexes which are in the current display (after filtering etc)
  9497. * @type array
  9498. * @default []
  9499. */
  9500. "aiDisplay": [],
  9501. /**
  9502. * Array of indexes for display - no filtering
  9503. * @type array
  9504. * @default []
  9505. */
  9506. "aiDisplayMaster": [],
  9507. /**
  9508. * Store information about each column that is in use
  9509. * @type array
  9510. * @default []
  9511. */
  9512. "aoColumns": [],
  9513. /**
  9514. * Store information about the table's header
  9515. * @type array
  9516. * @default []
  9517. */
  9518. "aoHeader": [],
  9519. /**
  9520. * Store information about the table's footer
  9521. * @type array
  9522. * @default []
  9523. */
  9524. "aoFooter": [],
  9525. /**
  9526. * Search data array for regular expression searching
  9527. * @type array
  9528. * @default []
  9529. */
  9530. "asDataSearch": [],
  9531. /**
  9532. * Store the applied global search information in case we want to force a
  9533. * research or compare the old search to a new one.
  9534. * Note that this parameter will be set by the initialisation routine. To
  9535. * set a default use {@link DataTable.defaults}.
  9536. * @namespace
  9537. * @extends DataTable.models.oSearch
  9538. */
  9539. "oPreviousSearch": {},
  9540. /**
  9541. * Store the applied search for each column - see
  9542. * {@link DataTable.models.oSearch} for the format that is used for the
  9543. * filtering information for each column.
  9544. * @type array
  9545. * @default []
  9546. */
  9547. "aoPreSearchCols": [],
  9548. /**
  9549. * Sorting that is applied to the table. Note that the inner arrays are
  9550. * used in the following manner:
  9551. * <ul>
  9552. * <li>Index 0 - column number</li>
  9553. * <li>Index 1 - current sorting direction</li>
  9554. * <li>Index 2 - index of asSorting for this column</li>
  9555. * </ul>
  9556. * Note that this parameter will be set by the initialisation routine. To
  9557. * set a default use {@link DataTable.defaults}.
  9558. * @type array
  9559. * @todo These inner arrays should really be objects
  9560. */
  9561. "aaSorting": null,
  9562. /**
  9563. * Sorting that is always applied to the table (i.e. prefixed in front of
  9564. * aaSorting).
  9565. * Note that this parameter will be set by the initialisation routine. To
  9566. * set a default use {@link DataTable.defaults}.
  9567. * @type array|null
  9568. * @default null
  9569. */
  9570. "aaSortingFixed": null,
  9571. /**
  9572. * Classes to use for the striping of a table.
  9573. * Note that this parameter will be set by the initialisation routine. To
  9574. * set a default use {@link DataTable.defaults}.
  9575. * @type array
  9576. * @default []
  9577. */
  9578. "asStripeClasses": null,
  9579. /**
  9580. * If restoring a table - we should restore its striping classes as well
  9581. * @type array
  9582. * @default []
  9583. */
  9584. "asDestroyStripes": [],
  9585. /**
  9586. * If restoring a table - we should restore its width
  9587. * @type int
  9588. * @default 0
  9589. */
  9590. "sDestroyWidth": 0,
  9591. /**
  9592. * Callback functions array for every time a row is inserted (i.e. on a draw).
  9593. * @type array
  9594. * @default []
  9595. */
  9596. "aoRowCallback": [],
  9597. /**
  9598. * Callback functions for the header on each draw.
  9599. * @type array
  9600. * @default []
  9601. */
  9602. "aoHeaderCallback": [],
  9603. /**
  9604. * Callback function for the footer on each draw.
  9605. * @type array
  9606. * @default []
  9607. */
  9608. "aoFooterCallback": [],
  9609. /**
  9610. * Array of callback functions for draw callback functions
  9611. * @type array
  9612. * @default []
  9613. */
  9614. "aoDrawCallback": [],
  9615. /**
  9616. * Array of callback functions for row created function
  9617. * @type array
  9618. * @default []
  9619. */
  9620. "aoRowCreatedCallback": [],
  9621. /**
  9622. * Callback functions for just before the table is redrawn. A return of
  9623. * false will be used to cancel the draw.
  9624. * @type array
  9625. * @default []
  9626. */
  9627. "aoPreDrawCallback": [],
  9628. /**
  9629. * Callback functions for when the table has been initialised.
  9630. * @type array
  9631. * @default []
  9632. */
  9633. "aoInitComplete": [],
  9634. /**
  9635. * Callbacks for modifying the settings to be stored for state saving, prior to
  9636. * saving state.
  9637. * @type array
  9638. * @default []
  9639. */
  9640. "aoStateSaveParams": [],
  9641. /**
  9642. * Callbacks for modifying the settings that have been stored for state saving
  9643. * prior to using the stored values to restore the state.
  9644. * @type array
  9645. * @default []
  9646. */
  9647. "aoStateLoadParams": [],
  9648. /**
  9649. * Callbacks for operating on the settings object once the saved state has been
  9650. * loaded
  9651. * @type array
  9652. * @default []
  9653. */
  9654. "aoStateLoaded": [],
  9655. /**
  9656. * Cache the table ID for quick access
  9657. * @type string
  9658. * @default <i>Empty string</i>
  9659. */
  9660. "sTableId": "",
  9661. /**
  9662. * The TABLE node for the main table
  9663. * @type node
  9664. * @default null
  9665. */
  9666. "nTable": null,
  9667. /**
  9668. * Permanent ref to the thead element
  9669. * @type node
  9670. * @default null
  9671. */
  9672. "nTHead": null,
  9673. /**
  9674. * Permanent ref to the tfoot element - if it exists
  9675. * @type node
  9676. * @default null
  9677. */
  9678. "nTFoot": null,
  9679. /**
  9680. * Permanent ref to the tbody element
  9681. * @type node
  9682. * @default null
  9683. */
  9684. "nTBody": null,
  9685. /**
  9686. * Cache the wrapper node (contains all DataTables controlled elements)
  9687. * @type node
  9688. * @default null
  9689. */
  9690. "nTableWrapper": null,
  9691. /**
  9692. * Indicate if when using server-side processing the loading of data
  9693. * should be deferred until the second draw.
  9694. * Note that this parameter will be set by the initialisation routine. To
  9695. * set a default use {@link DataTable.defaults}.
  9696. * @type boolean
  9697. * @default false
  9698. */
  9699. "bDeferLoading": false,
  9700. /**
  9701. * Indicate if all required information has been read in
  9702. * @type boolean
  9703. * @default false
  9704. */
  9705. "bInitialised": false,
  9706. /**
  9707. * Information about open rows. Each object in the array has the parameters
  9708. * 'nTr' and 'nParent'
  9709. * @type array
  9710. * @default []
  9711. */
  9712. "aoOpenRows": [],
  9713. /**
  9714. * Dictate the positioning of DataTables' control elements - see
  9715. * {@link DataTable.model.oInit.sDom}.
  9716. * Note that this parameter will be set by the initialisation routine. To
  9717. * set a default use {@link DataTable.defaults}.
  9718. * @type string
  9719. * @default null
  9720. */
  9721. "sDom": null,
  9722. /**
  9723. * Which type of pagination should be used.
  9724. * Note that this parameter will be set by the initialisation routine. To
  9725. * set a default use {@link DataTable.defaults}.
  9726. * @type string
  9727. * @default two_button
  9728. */
  9729. "sPaginationType": "two_button",
  9730. /**
  9731. * The cookie duration (for bStateSave) in seconds.
  9732. * Note that this parameter will be set by the initialisation routine. To
  9733. * set a default use {@link DataTable.defaults}.
  9734. * @type int
  9735. * @default 0
  9736. */
  9737. "iCookieDuration": 0,
  9738. /**
  9739. * The cookie name prefix.
  9740. * Note that this parameter will be set by the initialisation routine. To
  9741. * set a default use {@link DataTable.defaults}.
  9742. * @type string
  9743. * @default <i>Empty string</i>
  9744. */
  9745. "sCookiePrefix": "",
  9746. /**
  9747. * Callback function for cookie creation.
  9748. * Note that this parameter will be set by the initialisation routine. To
  9749. * set a default use {@link DataTable.defaults}.
  9750. * @type function
  9751. * @default null
  9752. */
  9753. "fnCookieCallback": null,
  9754. /**
  9755. * Array of callback functions for state saving. Each array element is an
  9756. * object with the following parameters:
  9757. * <ul>
  9758. * <li>function:fn - function to call. Takes two parameters, oSettings
  9759. * and the JSON string to save that has been thus far created. Returns
  9760. * a JSON string to be inserted into a json object
  9761. * (i.e. '"param": [ 0, 1, 2]')</li>
  9762. * <li>string:sName - name of callback</li>
  9763. * </ul>
  9764. * @type array
  9765. * @default []
  9766. */
  9767. "aoStateSave": [],
  9768. /**
  9769. * Array of callback functions for state loading. Each array element is an
  9770. * object with the following parameters:
  9771. * <ul>
  9772. * <li>function:fn - function to call. Takes two parameters, oSettings
  9773. * and the object stored. May return false to cancel state loading</li>
  9774. * <li>string:sName - name of callback</li>
  9775. * </ul>
  9776. * @type array
  9777. * @default []
  9778. */
  9779. "aoStateLoad": [],
  9780. /**
  9781. * State that was loaded from the cookie. Useful for back reference
  9782. * @type object
  9783. * @default null
  9784. */
  9785. "oLoadedState": null,
  9786. /**
  9787. * Source url for AJAX data for the table.
  9788. * Note that this parameter will be set by the initialisation routine. To
  9789. * set a default use {@link DataTable.defaults}.
  9790. * @type string
  9791. * @default null
  9792. */
  9793. "sAjaxSource": null,
  9794. /**
  9795. * Property from a given object from which to read the table data from. This
  9796. * can be an empty string (when not server-side processing), in which case
  9797. * it is assumed an an array is given directly.
  9798. * Note that this parameter will be set by the initialisation routine. To
  9799. * set a default use {@link DataTable.defaults}.
  9800. * @type string
  9801. */
  9802. "sAjaxDataProp": null,
  9803. /**
  9804. * Note if draw should be blocked while getting data
  9805. * @type boolean
  9806. * @default true
  9807. */
  9808. "bAjaxDataGet": true,
  9809. /**
  9810. * The last jQuery XHR object that was used for server-side data gathering.
  9811. * This can be used for working with the XHR information in one of the
  9812. * callbacks
  9813. * @type object
  9814. * @default null
  9815. */
  9816. "jqXHR": null,
  9817. /**
  9818. * Function to get the server-side data.
  9819. * Note that this parameter will be set by the initialisation routine. To
  9820. * set a default use {@link DataTable.defaults}.
  9821. * @type function
  9822. */
  9823. "fnServerData": null,
  9824. /**
  9825. * Functions which are called prior to sending an Ajax request so extra
  9826. * parameters can easily be sent to the server
  9827. * @type array
  9828. * @default []
  9829. */
  9830. "aoServerParams": [],
  9831. /**
  9832. * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
  9833. * required).
  9834. * Note that this parameter will be set by the initialisation routine. To
  9835. * set a default use {@link DataTable.defaults}.
  9836. * @type string
  9837. */
  9838. "sServerMethod": null,
  9839. /**
  9840. * Format numbers for display.
  9841. * Note that this parameter will be set by the initialisation routine. To
  9842. * set a default use {@link DataTable.defaults}.
  9843. * @type function
  9844. */
  9845. "fnFormatNumber": null,
  9846. /**
  9847. * List of options that can be used for the user selectable length menu.
  9848. * Note that this parameter will be set by the initialisation routine. To
  9849. * set a default use {@link DataTable.defaults}.
  9850. * @type array
  9851. * @default []
  9852. */
  9853. "aLengthMenu": null,
  9854. /**
  9855. * Counter for the draws that the table does. Also used as a tracker for
  9856. * server-side processing
  9857. * @type int
  9858. * @default 0
  9859. */
  9860. "iDraw": 0,
  9861. /**
  9862. * Indicate if a redraw is being done - useful for Ajax
  9863. * @type boolean
  9864. * @default false
  9865. */
  9866. "bDrawing": false,
  9867. /**
  9868. * Draw index (iDraw) of the last error when parsing the returned data
  9869. * @type int
  9870. * @default -1
  9871. */
  9872. "iDrawError": -1,
  9873. /**
  9874. * Paging display length
  9875. * @type int
  9876. * @default 10
  9877. */
  9878. "_iDisplayLength": 10,
  9879. /**
  9880. * Paging start point - aiDisplay index
  9881. * @type int
  9882. * @default 0
  9883. */
  9884. "_iDisplayStart": 0,
  9885. /**
  9886. * Paging end point - aiDisplay index. Use fnDisplayEnd rather than
  9887. * this property to get the end point
  9888. * @type int
  9889. * @default 10
  9890. * @private
  9891. */
  9892. "_iDisplayEnd": 10,
  9893. /**
  9894. * Server-side processing - number of records in the result set
  9895. * (i.e. before filtering), Use fnRecordsTotal rather than
  9896. * this property to get the value of the number of records, regardless of
  9897. * the server-side processing setting.
  9898. * @type int
  9899. * @default 0
  9900. * @private
  9901. */
  9902. "_iRecordsTotal": 0,
  9903. /**
  9904. * Server-side processing - number of records in the current display set
  9905. * (i.e. after filtering). Use fnRecordsDisplay rather than
  9906. * this property to get the value of the number of records, regardless of
  9907. * the server-side processing setting.
  9908. * @type boolean
  9909. * @default 0
  9910. * @private
  9911. */
  9912. "_iRecordsDisplay": 0,
  9913. /**
  9914. * Flag to indicate if jQuery UI marking and classes should be used.
  9915. * Note that this parameter will be set by the initialisation routine. To
  9916. * set a default use {@link DataTable.defaults}.
  9917. * @type boolean
  9918. */
  9919. "bJUI": null,
  9920. /**
  9921. * The classes to use for the table
  9922. * @type object
  9923. * @default {}
  9924. */
  9925. "oClasses": {},
  9926. /**
  9927. * Flag attached to the settings object so you can check in the draw
  9928. * callback if filtering has been done in the draw. Deprecated in favour of
  9929. * events.
  9930. * @type boolean
  9931. * @default false
  9932. * @deprecated
  9933. */
  9934. "bFiltered": false,
  9935. /**
  9936. * Flag attached to the settings object so you can check in the draw
  9937. * callback if sorting has been done in the draw. Deprecated in favour of
  9938. * events.
  9939. * @type boolean
  9940. * @default false
  9941. * @deprecated
  9942. */
  9943. "bSorted": false,
  9944. /**
  9945. * Indicate that if multiple rows are in the header and there is more than
  9946. * one unique cell per column, if the top one (true) or bottom one (false)
  9947. * should be used for sorting / title by DataTables.
  9948. * Note that this parameter will be set by the initialisation routine. To
  9949. * set a default use {@link DataTable.defaults}.
  9950. * @type boolean
  9951. */
  9952. "bSortCellsTop": null,
  9953. /**
  9954. * Initialisation object that is used for the table
  9955. * @type object
  9956. * @default null
  9957. */
  9958. "oInit": null,
  9959. /**
  9960. * Destroy callback functions - for plug-ins to attach themselves to the
  9961. * destroy so they can clean up markup and events.
  9962. * @type array
  9963. * @default []
  9964. */
  9965. "aoDestroyCallback": [],
  9966. /**
  9967. * Get the number of records in the current record set, before filtering
  9968. * @type function
  9969. */
  9970. "fnRecordsTotal": function ()
  9971. {
  9972. if ( this.oFeatures.bServerSide ) {
  9973. return parseInt(this._iRecordsTotal, 10);
  9974. } else {
  9975. return this.aiDisplayMaster.length;
  9976. }
  9977. },
  9978. /**
  9979. * Get the number of records in the current record set, after filtering
  9980. * @type function
  9981. */
  9982. "fnRecordsDisplay": function ()
  9983. {
  9984. if ( this.oFeatures.bServerSide ) {
  9985. return parseInt(this._iRecordsDisplay, 10);
  9986. } else {
  9987. return this.aiDisplay.length;
  9988. }
  9989. },
  9990. /**
  9991. * Set the display end point - aiDisplay index
  9992. * @type function
  9993. * @todo Should do away with _iDisplayEnd and calculate it on-the-fly here
  9994. */
  9995. "fnDisplayEnd": function ()
  9996. {
  9997. if ( this.oFeatures.bServerSide ) {
  9998. if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) {
  9999. return this._iDisplayStart+this.aiDisplay.length;
  10000. } else {
  10001. return Math.min( this._iDisplayStart+this._iDisplayLength,
  10002. this._iRecordsDisplay );
  10003. }
  10004. } else {
  10005. return this._iDisplayEnd;
  10006. }
  10007. },
  10008. /**
  10009. * The DataTables object for this table
  10010. * @type object
  10011. * @default null
  10012. */
  10013. "oInstance": null,
  10014. /**
  10015. * Unique identifier for each instance of the DataTables object. If there
  10016. * is an ID on the table node, then it takes that value, otherwise an
  10017. * incrementing internal counter is used.
  10018. * @type string
  10019. * @default null
  10020. */
  10021. "sInstance": null,
  10022. /**
  10023. * tabindex attribute value that is added to DataTables control elements, allowing
  10024. * keyboard navigation of the table and its controls.
  10025. */
  10026. "iTabIndex": 0,
  10027. /**
  10028. * DIV container for the footer scrolling table if scrolling
  10029. */
  10030. "nScrollHead": null,
  10031. /**
  10032. * DIV container for the footer scrolling table if scrolling
  10033. */
  10034. "nScrollFoot": null
  10035. };
  10036. /**
  10037. * Extension object for DataTables that is used to provide all extension options.
  10038. *
  10039. * Note that the <i>DataTable.ext</i> object is available through
  10040. * <i>jQuery.fn.dataTable.ext</i> where it may be accessed and manipulated. It is
  10041. * also aliased to <i>jQuery.fn.dataTableExt</i> for historic reasons.
  10042. * @namespace
  10043. * @extends DataTable.models.ext
  10044. */
  10045. DataTable.ext = $.extend( true, {}, DataTable.models.ext );
  10046. $.extend( DataTable.ext.oStdClasses, {
  10047. "sTable": "dataTable",
  10048. /* Two buttons buttons */
  10049. "sPagePrevEnabled": "paginate_enabled_previous",
  10050. "sPagePrevDisabled": "paginate_disabled_previous",
  10051. "sPageNextEnabled": "paginate_enabled_next",
  10052. "sPageNextDisabled": "paginate_disabled_next",
  10053. "sPageJUINext": "",
  10054. "sPageJUIPrev": "",
  10055. /* Full numbers paging buttons */
  10056. "sPageButton": "paginate_button",
  10057. "sPageButtonActive": "paginate_active",
  10058. "sPageButtonStaticDisabled": "paginate_button paginate_button_disabled",
  10059. "sPageFirst": "first",
  10060. "sPagePrevious": "previous",
  10061. "sPageNext": "next",
  10062. "sPageLast": "last",
  10063. /* Striping classes */
  10064. "sStripeOdd": "odd",
  10065. "sStripeEven": "even",
  10066. /* Empty row */
  10067. "sRowEmpty": "dataTables_empty",
  10068. /* Features */
  10069. "sWrapper": "dataTables_wrapper",
  10070. "sFilter": "dataTables_filter",
  10071. "sInfo": "dataTables_info",
  10072. "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
  10073. "sLength": "dataTables_length",
  10074. "sProcessing": "dataTables_processing",
  10075. /* Sorting */
  10076. "sSortAsc": "sorting_asc",
  10077. "sSortDesc": "sorting_desc",
  10078. "sSortable": "sorting", /* Sortable in both directions */
  10079. "sSortableAsc": "sorting_asc_disabled",
  10080. "sSortableDesc": "sorting_desc_disabled",
  10081. "sSortableNone": "sorting_disabled",
  10082. "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
  10083. "sSortJUIAsc": "",
  10084. "sSortJUIDesc": "",
  10085. "sSortJUI": "",
  10086. "sSortJUIAscAllowed": "",
  10087. "sSortJUIDescAllowed": "",
  10088. "sSortJUIWrapper": "",
  10089. "sSortIcon": "",
  10090. /* Scrolling */
  10091. "sScrollWrapper": "dataTables_scroll",
  10092. "sScrollHead": "dataTables_scrollHead",
  10093. "sScrollHeadInner": "dataTables_scrollHeadInner",
  10094. "sScrollBody": "dataTables_scrollBody",
  10095. "sScrollFoot": "dataTables_scrollFoot",
  10096. "sScrollFootInner": "dataTables_scrollFootInner",
  10097. /* Misc */
  10098. "sFooterTH": ""
  10099. } );
  10100. $.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, {
  10101. /* Two buttons buttons */
  10102. "sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left",
  10103. "sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",
  10104. "sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right",
  10105. "sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",
  10106. "sPageJUINext": "ui-icon ui-icon-circle-arrow-e",
  10107. "sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w",
  10108. /* Full numbers paging buttons */
  10109. "sPageButton": "fg-button ui-button ui-state-default",
  10110. "sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled",
  10111. "sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled",
  10112. "sPageFirst": "first ui-corner-tl ui-corner-bl",
  10113. "sPageLast": "last ui-corner-tr ui-corner-br",
  10114. /* Features */
  10115. "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
  10116. "ui-buttonset-multi paging_", /* Note that the type is postfixed */
  10117. /* Sorting */
  10118. "sSortAsc": "ui-state-default",
  10119. "sSortDesc": "ui-state-default",
  10120. "sSortable": "ui-state-default",
  10121. "sSortableAsc": "ui-state-default",
  10122. "sSortableDesc": "ui-state-default",
  10123. "sSortableNone": "ui-state-default",
  10124. "sSortJUIAsc": "css_right ui-icon ui-icon-triangle-1-n",
  10125. "sSortJUIDesc": "css_right ui-icon ui-icon-triangle-1-s",
  10126. "sSortJUI": "css_right ui-icon ui-icon-carat-2-n-s",
  10127. "sSortJUIAscAllowed": "css_right ui-icon ui-icon-carat-1-n",
  10128. "sSortJUIDescAllowed": "css_right ui-icon ui-icon-carat-1-s",
  10129. "sSortJUIWrapper": "DataTables_sort_wrapper",
  10130. "sSortIcon": "DataTables_sort_icon",
  10131. /* Scrolling */
  10132. "sScrollHead": "dataTables_scrollHead ui-state-default",
  10133. "sScrollFoot": "dataTables_scrollFoot ui-state-default",
  10134. /* Misc */
  10135. "sFooterTH": "ui-state-default"
  10136. } );
  10137. /*
  10138. * Variable: oPagination
  10139. * Purpose:
  10140. * Scope: jQuery.fn.dataTableExt
  10141. */
  10142. $.extend( DataTable.ext.oPagination, {
  10143. /*
  10144. * Variable: two_button
  10145. * Purpose: Standard two button (forward/back) pagination
  10146. * Scope: jQuery.fn.dataTableExt.oPagination
  10147. */
  10148. "two_button": {
  10149. /*
  10150. * Function: oPagination.two_button.fnInit
  10151. * Purpose: Initialise dom elements required for pagination with forward/back buttons only
  10152. * Returns: -
  10153. * Inputs: object:oSettings - dataTables settings object
  10154. * node:nPaging - the DIV which contains this pagination control
  10155. * function:fnCallbackDraw - draw function which must be called on update
  10156. */
  10157. "fnInit": function ( oSettings, nPaging, fnCallbackDraw )
  10158. {
  10159. var oLang = oSettings.oLanguage.oPaginate;
  10160. var oClasses = oSettings.oClasses;
  10161. var fnClickHandler = function ( e ) {
  10162. if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
  10163. {
  10164. fnCallbackDraw( oSettings );
  10165. }
  10166. };
  10167. var sAppend = (!oSettings.bJUI) ?
  10168. '<a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sPrevious+'</a>'+
  10169. '<a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sNext+'</a>'
  10170. :
  10171. '<a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="'+oSettings.oClasses.sPageJUIPrev+'"></span></a>'+
  10172. '<a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="'+oSettings.oClasses.sPageJUINext+'"></span></a>';
  10173. $(nPaging).append( sAppend );
  10174. var els = $('a', nPaging);
  10175. var nPrevious = els[0],
  10176. nNext = els[1];
  10177. oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler );
  10178. oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
  10179. /* ID the first elements only */
  10180. if ( !oSettings.aanFeatures.p )
  10181. {
  10182. nPaging.id = oSettings.sTableId+'_paginate';
  10183. nPrevious.id = oSettings.sTableId+'_previous';
  10184. nNext.id = oSettings.sTableId+'_next';
  10185. nPrevious.setAttribute('aria-controls', oSettings.sTableId);
  10186. nNext.setAttribute('aria-controls', oSettings.sTableId);
  10187. }
  10188. },
  10189. /*
  10190. * Function: oPagination.two_button.fnUpdate
  10191. * Purpose: Update the two button pagination at the end of the draw
  10192. * Returns: -
  10193. * Inputs: object:oSettings - dataTables settings object
  10194. * function:fnCallbackDraw - draw function to call on page change
  10195. */
  10196. "fnUpdate": function ( oSettings, fnCallbackDraw )
  10197. {
  10198. if ( !oSettings.aanFeatures.p )
  10199. {
  10200. return;
  10201. }
  10202. var oClasses = oSettings.oClasses;
  10203. var an = oSettings.aanFeatures.p;
  10204. /* Loop over each instance of the pager */
  10205. for ( var i=0, iLen=an.length ; i<iLen ; i++ )
  10206. {
  10207. if ( an[i].childNodes.length !== 0 )
  10208. {
  10209. an[i].childNodes[0].className = ( oSettings._iDisplayStart === 0 ) ?
  10210. oClasses.sPagePrevDisabled : oClasses.sPagePrevEnabled;
  10211. an[i].childNodes[1].className = ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() ) ?
  10212. oClasses.sPageNextDisabled : oClasses.sPageNextEnabled;
  10213. }
  10214. }
  10215. }
  10216. },
  10217. /*
  10218. * Variable: iFullNumbersShowPages
  10219. * Purpose: Change the number of pages which can be seen
  10220. * Scope: jQuery.fn.dataTableExt.oPagination
  10221. */
  10222. "iFullNumbersShowPages": 5,
  10223. /*
  10224. * Variable: full_numbers
  10225. * Purpose: Full numbers pagination
  10226. * Scope: jQuery.fn.dataTableExt.oPagination
  10227. */
  10228. "full_numbers": {
  10229. /*
  10230. * Function: oPagination.full_numbers.fnInit
  10231. * Purpose: Initialise dom elements required for pagination with a list of the pages
  10232. * Returns: -
  10233. * Inputs: object:oSettings - dataTables settings object
  10234. * node:nPaging - the DIV which contains this pagination control
  10235. * function:fnCallbackDraw - draw function which must be called on update
  10236. */
  10237. "fnInit": function ( oSettings, nPaging, fnCallbackDraw )
  10238. {
  10239. var oLang = oSettings.oLanguage.oPaginate;
  10240. var oClasses = oSettings.oClasses;
  10241. var fnClickHandler = function ( e ) {
  10242. if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
  10243. {
  10244. fnCallbackDraw( oSettings );
  10245. }
  10246. };
  10247. $(nPaging).append(
  10248. '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'">'+oLang.sFirst+'</a>'+
  10249. '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'">'+oLang.sPrevious+'</a>'+
  10250. '<span></span>'+
  10251. '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+'</a>'+
  10252. '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+'</a>'
  10253. );
  10254. var els = $('a', nPaging);
  10255. var nFirst = els[0],
  10256. nPrev = els[1],
  10257. nNext = els[2],
  10258. nLast = els[3];
  10259. oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler );
  10260. oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler );
  10261. oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
  10262. oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler );
  10263. /* ID the first elements only */
  10264. if ( !oSettings.aanFeatures.p )
  10265. {
  10266. nPaging.id = oSettings.sTableId+'_paginate';
  10267. nFirst.id =oSettings.sTableId+'_first';
  10268. nPrev.id =oSettings.sTableId+'_previous';
  10269. nNext.id =oSettings.sTableId+'_next';
  10270. nLast.id =oSettings.sTableId+'_last';
  10271. }
  10272. },
  10273. /*
  10274. * Function: oPagination.full_numbers.fnUpdate
  10275. * Purpose: Update the list of page buttons shows
  10276. * Returns: -
  10277. * Inputs: object:oSettings - dataTables settings object
  10278. * function:fnCallbackDraw - draw function to call on page change
  10279. */
  10280. "fnUpdate": function ( oSettings, fnCallbackDraw )
  10281. {
  10282. if ( !oSettings.aanFeatures.p )
  10283. {
  10284. return;
  10285. }
  10286. var iPageCount = DataTable.ext.oPagination.iFullNumbersShowPages;
  10287. var iPageCountHalf = Math.floor(iPageCount / 2);
  10288. var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
  10289. var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
  10290. var sList = "";
  10291. var iStartButton, iEndButton, i, iLen;
  10292. var oClasses = oSettings.oClasses;
  10293. var anButtons, anStatic, nPaginateList;
  10294. var an = oSettings.aanFeatures.p;
  10295. var fnBind = function (j) {
  10296. oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) {
  10297. /* Use the information in the element to jump to the required page */
  10298. oSettings.oApi._fnPageChange( oSettings, e.data.page );
  10299. fnCallbackDraw( oSettings );
  10300. e.preventDefault();
  10301. } );
  10302. };
  10303. /* Pages calculation */
  10304. if ( oSettings._iDisplayLength === -1 )
  10305. {
  10306. iStartButton = 1;
  10307. iEndButton = 1;
  10308. iCurrentPage = 1;
  10309. }
  10310. else if (iPages < iPageCount)
  10311. {
  10312. iStartButton = 1;
  10313. iEndButton = iPages;
  10314. }
  10315. else if (iCurrentPage <= iPageCountHalf)
  10316. {
  10317. iStartButton = 1;
  10318. iEndButton = iPageCount;
  10319. }
  10320. else if (iCurrentPage >= (iPages - iPageCountHalf))
  10321. {
  10322. iStartButton = iPages - iPageCount + 1;
  10323. iEndButton = iPages;
  10324. }
  10325. else
  10326. {
  10327. iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
  10328. iEndButton = iStartButton + iPageCount - 1;
  10329. }
  10330. /* Build the dynamic list */
  10331. for ( i=iStartButton ; i<=iEndButton ; i++ )
  10332. {
  10333. sList += (iCurrentPage !== i) ?
  10334. '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+'">'+oSettings.fnFormatNumber(i)+'</a>' :
  10335. '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButtonActive+'">'+oSettings.fnFormatNumber(i)+'</a>';
  10336. }
  10337. /* Loop over each instance of the pager */
  10338. for ( i=0, iLen=an.length ; i<iLen ; i++ )
  10339. {
  10340. if ( an[i].childNodes.length === 0 )
  10341. {
  10342. continue;
  10343. }
  10344. /* Build up the dynamic list forst - html and listeners */
  10345. $('span:eq(0)', an[i])
  10346. .html( sList )
  10347. .children('a').each( fnBind );
  10348. /* Update the premanent botton's classes */
  10349. anButtons = an[i].getElementsByTagName('a');
  10350. anStatic = [
  10351. anButtons[0], anButtons[1],
  10352. anButtons[anButtons.length-2], anButtons[anButtons.length-1]
  10353. ];
  10354. $(anStatic).removeClass( oClasses.sPageButton+" "+oClasses.sPageButtonActive+" "+oClasses.sPageButtonStaticDisabled );
  10355. $([anStatic[0], anStatic[1]]).addClass(
  10356. (iCurrentPage==1) ?
  10357. oClasses.sPageButtonStaticDisabled :
  10358. oClasses.sPageButton
  10359. );
  10360. $([anStatic[2], anStatic[3]]).addClass(
  10361. (iPages===0 || iCurrentPage===iPages || oSettings._iDisplayLength===-1) ?
  10362. oClasses.sPageButtonStaticDisabled :
  10363. oClasses.sPageButton
  10364. );
  10365. }
  10366. }
  10367. }
  10368. } );
  10369. $.extend( DataTable.ext.oSort, {
  10370. /*
  10371. * text sorting
  10372. */
  10373. "string-pre": function ( a )
  10374. {
  10375. if ( typeof a != 'string' ) {
  10376. a = (a !== null && a.toString) ? a.toString() : '';
  10377. }
  10378. return a.toLowerCase();
  10379. },
  10380. "string-asc": function ( x, y )
  10381. {
  10382. return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  10383. },
  10384. "string-desc": function ( x, y )
  10385. {
  10386. return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  10387. },
  10388. /*
  10389. * html sorting (ignore html tags)
  10390. */
  10391. "html-pre": function ( a )
  10392. {
  10393. return a.replace( /<.*?>/g, "" ).toLowerCase();
  10394. },
  10395. "html-asc": function ( x, y )
  10396. {
  10397. return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  10398. },
  10399. "html-desc": function ( x, y )
  10400. {
  10401. return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  10402. },
  10403. /*
  10404. * date sorting
  10405. */
  10406. "date-pre": function ( a )
  10407. {
  10408. var x = Date.parse( a );
  10409. if ( isNaN(x) || x==="" )
  10410. {
  10411. x = Date.parse( "01/01/1970 00:00:00" );
  10412. }
  10413. return x;
  10414. },
  10415. "date-asc": function ( x, y )
  10416. {
  10417. return x - y;
  10418. },
  10419. "date-desc": function ( x, y )
  10420. {
  10421. return y - x;
  10422. },
  10423. /*
  10424. * numerical sorting
  10425. */
  10426. "numeric-pre": function ( a )
  10427. {
  10428. return (a=="-" || a==="") ? 0 : a*1;
  10429. },
  10430. "numeric-asc": function ( x, y )
  10431. {
  10432. return x - y;
  10433. },
  10434. "numeric-desc": function ( x, y )
  10435. {
  10436. return y - x;
  10437. }
  10438. } );
  10439. $.extend( DataTable.ext.aTypes, [
  10440. /*
  10441. * Function: -
  10442. * Purpose: Check to see if a string is numeric
  10443. * Returns: string:'numeric' or null
  10444. * Inputs: mixed:sText - string to check
  10445. */
  10446. function ( sData )
  10447. {
  10448. /* Allow zero length strings as a number */
  10449. if ( typeof sData === 'number' )
  10450. {
  10451. return 'numeric';
  10452. }
  10453. else if ( typeof sData !== 'string' )
  10454. {
  10455. return null;
  10456. }
  10457. var sValidFirstChars = "0123456789-";
  10458. var sValidChars = "0123456789.";
  10459. var Char;
  10460. var bDecimal = false;
  10461. /* Check for a valid first char (no period and allow negatives) */
  10462. Char = sData.charAt(0);
  10463. if (sValidFirstChars.indexOf(Char) == -1)
  10464. {
  10465. return null;
  10466. }
  10467. /* Check all the other characters are valid */
  10468. for ( var i=1 ; i<sData.length ; i++ )
  10469. {
  10470. Char = sData.charAt(i);
  10471. if (sValidChars.indexOf(Char) == -1)
  10472. {
  10473. return null;
  10474. }
  10475. /* Only allowed one decimal place... */
  10476. if ( Char == "." )
  10477. {
  10478. if ( bDecimal )
  10479. {
  10480. return null;
  10481. }
  10482. bDecimal = true;
  10483. }
  10484. }
  10485. return 'numeric';
  10486. },
  10487. /*
  10488. * Function: -
  10489. * Purpose: Check to see if a string is actually a formatted date
  10490. * Returns: string:'date' or null
  10491. * Inputs: string:sText - string to check
  10492. */
  10493. function ( sData )
  10494. {
  10495. var iParse = Date.parse(sData);
  10496. if ( (iParse !== null && !isNaN(iParse)) || (typeof sData === 'string' && sData.length === 0) )
  10497. {
  10498. return 'date';
  10499. }
  10500. return null;
  10501. },
  10502. /*
  10503. * Function: -
  10504. * Purpose: Check to see if a string should be treated as an HTML string
  10505. * Returns: string:'html' or null
  10506. * Inputs: string:sText - string to check
  10507. */
  10508. function ( sData )
  10509. {
  10510. if ( typeof sData === 'string' && sData.indexOf('<') != -1 && sData.indexOf('>') != -1 )
  10511. {
  10512. return 'html';
  10513. }
  10514. return null;
  10515. }
  10516. ] );
  10517. // jQuery aliases
  10518. $.fn.DataTable = DataTable;
  10519. $.fn.dataTable = DataTable;
  10520. $.fn.dataTableSettings = DataTable.settings;
  10521. $.fn.dataTableExt = DataTable.ext;
  10522. // Information about events fired by DataTables - for documentation.
  10523. /**
  10524. * Draw event, fired whenever the table is redrawn on the page, at the same point as
  10525. * fnDrawCallback. This may be useful for binding events or performing calculations when
  10526. * the table is altered at all.
  10527. * @name DataTable#draw
  10528. * @event
  10529. * @param {event} e jQuery event object
  10530. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  10531. */
  10532. /**
  10533. * Filter event, fired when the filtering applied to the table (using the build in global
  10534. * global filter, or column filters) is altered.
  10535. * @name DataTable#filter
  10536. * @event
  10537. * @param {event} e jQuery event object
  10538. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  10539. */
  10540. /**
  10541. * Page change event, fired when the paging of the table is altered.
  10542. * @name DataTable#page
  10543. * @event
  10544. * @param {event} e jQuery event object
  10545. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  10546. */
  10547. /**
  10548. * Sort event, fired when the sorting applied to the table is altered.
  10549. * @name DataTable#sort
  10550. * @event
  10551. * @param {event} e jQuery event object
  10552. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  10553. */
  10554. /**
  10555. * DataTables initialisation complete event, fired when the table is fully drawn,
  10556. * including Ajax data loaded, if Ajax data is required.
  10557. * @name DataTable#init
  10558. * @event
  10559. * @param {event} e jQuery event object
  10560. * @param {object} oSettings DataTables settings object
  10561. * @param {object} json The JSON object request from the server - only
  10562. * present if client-side Ajax sourced data is used</li></ol>
  10563. */
  10564. /**
  10565. * State save event, fired when the table has changed state a new state save is required.
  10566. * This method allows modification of the state saving object prior to actually doing the
  10567. * save, including addition or other state properties (for plug-ins) or modification
  10568. * of a DataTables core property.
  10569. * @name DataTable#stateSaveParams
  10570. * @event
  10571. * @param {event} e jQuery event object
  10572. * @param {object} oSettings DataTables settings object
  10573. * @param {object} json The state information to be saved
  10574. */
  10575. /**
  10576. * State load event, fired when the table is loading state from the stored data, but
  10577. * prior to the settings object being modified by the saved state - allowing modification
  10578. * of the saved state is required or loading of state for a plug-in.
  10579. * @name DataTable#stateLoadParams
  10580. * @event
  10581. * @param {event} e jQuery event object
  10582. * @param {object} oSettings DataTables settings object
  10583. * @param {object} json The saved state information
  10584. */
  10585. /**
  10586. * State loaded event, fired when state has been loaded from stored data and the settings
  10587. * object has been modified by the loaded data.
  10588. * @name DataTable#stateLoaded
  10589. * @event
  10590. * @param {event} e jQuery event object
  10591. * @param {object} oSettings DataTables settings object
  10592. * @param {object} json The saved state information
  10593. */
  10594. /**
  10595. * Processing event, fired when DataTables is doing some kind of processing (be it,
  10596. * sort, filter or anything else). Can be used to indicate to the end user that
  10597. * there is something happening, or that something has finished.
  10598. * @name DataTable#processing
  10599. * @event
  10600. * @param {event} e jQuery event object
  10601. * @param {object} oSettings DataTables settings object
  10602. * @param {boolean} bShow Flag for if DataTables is doing processing or not
  10603. */
  10604. /**
  10605. * Ajax (XHR) event, fired whenever an Ajax request is completed from a request to
  10606. * made to the server for new data (note that this trigger is called in fnServerData,
  10607. * if you override fnServerData and which to use this event, you need to trigger it in
  10608. * you success function).
  10609. * @name DataTable#xhr
  10610. * @event
  10611. * @param {event} e jQuery event object
  10612. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  10613. */
  10614. /**
  10615. * Destroy event, fired when the DataTable is destroyed by calling fnDestroy or passing
  10616. * the bDestroy:true parameter in the initialisation object. This can be used to remove
  10617. * bound events, added DOM nodes, etc.
  10618. * @name DataTable#destroy
  10619. * @event
  10620. * @param {event} e jQuery event object
  10621. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  10622. */
  10623. }(jQuery, window, document, undefined));